moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
move_group_interface.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2014, SRI International
5 * Copyright (c) 2013, Ioan A. Sucan
6 * Copyright (c) 2012, Willow Garage, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of Willow Garage nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 *********************************************************************/
36
37/* Author: Ioan Sucan, Sachin Chitta */
38
39#include <stdexcept>
40#include <sstream>
41#include <memory>
42
43#include <rclcpp/rclcpp.hpp>
44#include <rclcpp/version.h>
45
46#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
57#include <moveit_msgs/action/execute_trajectory.hpp>
58#include <moveit_msgs/srv/query_planner_interfaces.hpp>
59#include <moveit_msgs/srv/get_cartesian_path.hpp>
60#include <moveit_msgs/srv/grasp_planning.hpp>
61#include <moveit_msgs/srv/get_planner_params.hpp>
62#include <moveit_msgs/srv/set_planner_params.hpp>
65
66#include <std_msgs/msg/string.hpp>
67#include <geometry_msgs/msg/transform_stamped.hpp>
68// TODO: Remove conditional include when released to all active distros.
69#if __has_include(<tf2/utils.hpp>)
70#include <tf2/utils.hpp>
71#else
72#include <tf2/utils.h>
73#endif
74#include <tf2_eigen/tf2_eigen.hpp>
75// For Rolling, Kilted, and newer
76#if RCLCPP_VERSION_GTE(29, 6, 0)
77#include <tf2_ros/transform_listener.hpp>
78// For Jazzy and older
79#else
80#include <tf2_ros/transform_listener.h>
81#endif
82
83namespace moveit
84{
85namespace planning_interface
86{
88 "robot_description"; // name of the robot description (a param name, so it can be changed externally)
89
90const std::string GRASP_PLANNING_SERVICE_NAME = "plan_grasps"; // name of the service that can be used to plan grasps
91
92namespace
93{
94enum ActiveTargetType
95{
96 JOINT,
97 POSE,
98 POSITION,
99 ORIENTATION
100};
101
102// Function to support both Rolling and Humble on the main branch
103// Rolling has deprecated the version of the create_client method that takes
104// rmw_qos_profile_services_default for the QoS argument
105#if RCLCPP_VERSION_GTE(17, 0, 0) // Rolling
106auto qosDefault()
107{
108 return rclcpp::SystemDefaultsQoS();
109}
110#else // Humble
111auto qosDefault()
112{
113 return rmw_qos_profile_services_default;
114}
115#endif
116
117} // namespace
118
120{
121 friend MoveGroupInterface;
122
123public:
124 MoveGroupInterfaceImpl(const rclcpp::Node::SharedPtr& node, const Options& opt,
125 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, const rclcpp::Duration& wait_for_servers)
126 : opt_(opt), node_(node), logger_(moveit::getLogger("moveit.ros.move_group_interface")), tf_buffer_(tf_buffer)
127 {
128 // We have no control on how the passed node is getting executed. To make sure MGI is functional, we're creating
129 // our own callback group which is managed in a separate callback thread
130 callback_group_ = node_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive,
131 false /* don't spin with node executor */);
132 callback_executor_.add_callback_group(callback_group_, node->get_node_base_interface());
133 callback_thread_ = std::thread([this]() { callback_executor_.spin(); });
134
135 robot_model_ = opt.robot_model ? opt.robot_model : getSharedRobotModel(node_, opt.robot_description);
136 if (!getRobotModel())
137 {
138 std::string error = "Unable to construct robot model. Please make sure all needed information is on the "
139 "parameter server.";
140 RCLCPP_FATAL_STREAM(logger_, error);
141 throw std::runtime_error(error);
142 }
143
144 if (!getRobotModel()->hasJointModelGroup(opt.group_name))
145 {
146 std::string error = "Group '" + opt.group_name + "' was not found.";
147 RCLCPP_FATAL_STREAM(logger_, error);
148 throw std::runtime_error(error);
149 }
150
152 joint_model_group_ = getRobotModel()->getJointModelGroup(opt.group_name);
153
154 joint_state_target_ = std::make_shared<moveit::core::RobotState>(getRobotModel());
155 joint_state_target_->setToDefaultValues();
156 active_target_ = JOINT;
157 can_look_ = false;
158 look_around_attempts_ = 0;
159 can_replan_ = false;
160 replan_delay_ = 2.0;
161 replan_attempts_ = 1;
162 goal_joint_tolerance_ = 1e-4;
163 goal_position_tolerance_ = 1e-4; // 0.1 mm
164 goal_orientation_tolerance_ = 1e-3; // ~0.1 deg
165 allowed_planning_time_ = 5.0;
166 num_planning_attempts_ = 1;
167 node_->get_parameter_or<double>("robot_description_planning.default_velocity_scaling_factor",
168 max_velocity_scaling_factor_, 0.1);
169 node_->get_parameter_or<double>("robot_description_planning.default_acceleration_scaling_factor",
170 max_acceleration_scaling_factor_, 0.1);
171 initializing_constraints_ = false;
172
173 if (joint_model_group_->isChain())
174 end_effector_link_ = joint_model_group_->getLinkModelNames().back();
175 pose_reference_frame_ = getRobotModel()->getModelFrame();
176 // Append the slash between two topic components
177 trajectory_event_publisher_ = node_->create_publisher<std_msgs::msg::String>(
180 1);
181 attached_object_publisher_ = node_->create_publisher<moveit_msgs::msg::AttachedCollisionObject>(
184 1);
185
186 current_state_monitor_ = getSharedStateMonitor(node_, robot_model_, tf_buffer_);
187
188 move_action_client_ = rclcpp_action::create_client<moveit_msgs::action::MoveGroup>(
189 node_, rclcpp::names::append(opt_.move_group_namespace, move_group::MOVE_ACTION), callback_group_);
190 move_action_client_->wait_for_action_server(wait_for_servers.to_chrono<std::chrono::duration<double>>());
191 execute_action_client_ = rclcpp_action::create_client<moveit_msgs::action::ExecuteTrajectory>(
192 node_, rclcpp::names::append(opt_.move_group_namespace, move_group::EXECUTE_ACTION_NAME), callback_group_);
193 execute_action_client_->wait_for_action_server(wait_for_servers.to_chrono<std::chrono::duration<double>>());
194
195 query_service_ = node_->create_client<moveit_msgs::srv::QueryPlannerInterfaces>(
196 rclcpp::names::append(opt_.move_group_namespace, move_group::QUERY_PLANNERS_SERVICE_NAME), qosDefault(),
197 callback_group_);
198 get_params_service_ = node_->create_client<moveit_msgs::srv::GetPlannerParams>(
199 rclcpp::names::append(opt_.move_group_namespace, move_group::GET_PLANNER_PARAMS_SERVICE_NAME), qosDefault(),
200 callback_group_);
201 set_params_service_ = node_->create_client<moveit_msgs::srv::SetPlannerParams>(
202 rclcpp::names::append(opt_.move_group_namespace, move_group::SET_PLANNER_PARAMS_SERVICE_NAME), qosDefault(),
203 callback_group_);
204 cartesian_path_service_ = node_->create_client<moveit_msgs::srv::GetCartesianPath>(
205 rclcpp::names::append(opt_.move_group_namespace, move_group::CARTESIAN_PATH_SERVICE_NAME), qosDefault(),
206 callback_group_);
207
208 RCLCPP_INFO_STREAM(logger_, "Ready to take commands for planning group " << opt.group_name << '.');
209 }
210
212 {
213 if (constraints_init_thread_)
214 constraints_init_thread_->join();
215
216 callback_executor_.cancel();
217
218 if (callback_thread_.joinable())
219 callback_thread_.join();
220 }
221
222 const std::shared_ptr<tf2_ros::Buffer>& getTF() const
223 {
224 return tf_buffer_;
225 }
226
227 const Options& getOptions() const
228 {
229 return opt_;
230 }
231
232 const moveit::core::RobotModelConstPtr& getRobotModel() const
233 {
234 return robot_model_;
235 }
236
238 {
239 return joint_model_group_;
240 }
241
242 rclcpp_action::Client<moveit_msgs::action::MoveGroup>& getMoveGroupClient() const
243 {
244 return *move_action_client_;
245 }
246
247 bool getInterfaceDescription(moveit_msgs::msg::PlannerInterfaceDescription& desc)
248 {
249 auto req = std::make_shared<moveit_msgs::srv::QueryPlannerInterfaces::Request>();
250 auto future_response = query_service_->async_send_request(req);
251
252 if (future_response.valid())
253 {
254 const auto& response = future_response.get();
255 if (!response->planner_interfaces.empty())
256 {
257 desc = response->planner_interfaces.front();
258 return true;
259 }
260 }
261 return false;
262 }
263
264 bool getInterfaceDescriptions(std::vector<moveit_msgs::msg::PlannerInterfaceDescription>& desc)
265 {
266 auto req = std::make_shared<moveit_msgs::srv::QueryPlannerInterfaces::Request>();
267 auto future_response = query_service_->async_send_request(req);
268 if (future_response.valid())
269 {
270 const auto& response = future_response.get();
271 if (!response->planner_interfaces.empty())
272 {
273 desc = response->planner_interfaces;
274 return true;
275 }
276 }
277 return false;
278 }
279
280 std::map<std::string, std::string> getPlannerParams(const std::string& planner_id, const std::string& group = "")
281 {
282 auto req = std::make_shared<moveit_msgs::srv::GetPlannerParams::Request>();
283 moveit_msgs::srv::GetPlannerParams::Response::SharedPtr response;
284 req->planner_config = planner_id;
285 req->group = group;
286 std::map<std::string, std::string> result;
287
288 auto future_response = get_params_service_->async_send_request(req);
289 if (future_response.valid())
290 {
291 response = future_response.get();
292 for (unsigned int i = 0, end = response->params.keys.size(); i < end; ++i)
293 result[response->params.keys[i]] = response->params.values[i];
294 }
295 return result;
296 }
297
298 void setPlannerParams(const std::string& planner_id, const std::string& group,
299 const std::map<std::string, std::string>& params, bool replace = false)
300 {
301 auto req = std::make_shared<moveit_msgs::srv::SetPlannerParams::Request>();
302 req->planner_config = planner_id;
303 req->group = group;
304 req->replace = replace;
305 for (const std::pair<const std::string, std::string>& param : params)
306 {
307 req->params.keys.push_back(param.first);
308 req->params.values.push_back(param.second);
309 }
310 set_params_service_->async_send_request(req);
311 }
312
314 {
315 std::string default_planning_pipeline;
316 node_->get_parameter("move_group.default_planning_pipeline", default_planning_pipeline);
317 return default_planning_pipeline;
318 }
319
320 void setPlanningPipelineId(const std::string& pipeline_id)
321 {
322 if (pipeline_id != planning_pipeline_id_)
323 {
324 planning_pipeline_id_ = pipeline_id;
325
326 // Reset planner_id if planning pipeline changed
327 planner_id_ = "";
328 }
329 }
330
331 const std::string& getPlanningPipelineId() const
332 {
333 return planning_pipeline_id_;
334 }
335
336 std::string getDefaultPlannerId(const std::string& group) const
337 {
338 // Check what planning pipeline config should be used
339 std::string pipeline_id = getDefaultPlanningPipelineId();
340 if (!planning_pipeline_id_.empty())
341 pipeline_id = planning_pipeline_id_;
342
343 std::stringstream param_name;
344 param_name << "move_group";
345 if (!pipeline_id.empty())
346 param_name << "/planning_pipelines/" << pipeline_id;
347 if (!group.empty())
348 param_name << '.' << group;
349 param_name << ".default_planner_config";
350
351 std::string default_planner_config;
352 node_->get_parameter(param_name.str(), default_planner_config);
353 return default_planner_config;
354 }
355
356 void setPlannerId(const std::string& planner_id)
357 {
358 planner_id_ = planner_id;
359 }
360
361 const std::string& getPlannerId() const
362 {
363 return planner_id_;
364 }
365
366 void setNumPlanningAttempts(unsigned int num_planning_attempts)
367 {
368 num_planning_attempts_ = num_planning_attempts;
369 }
370
372 {
373 setMaxScalingFactor(max_velocity_scaling_factor_, value, "velocity_scaling_factor", 0.1);
374 }
375
377 {
378 return max_velocity_scaling_factor_;
379 }
380
382 {
383 setMaxScalingFactor(max_acceleration_scaling_factor_, value, "acceleration_scaling_factor", 0.1);
384 }
385
387 {
388 return max_acceleration_scaling_factor_;
389 }
390
391 void setMaxScalingFactor(double& variable, const double target_value, const char* factor_name, double fallback_value)
392 {
393 if (target_value > 1.0)
394 {
395 RCLCPP_WARN(logger_, "Limiting max_%s (%.2f) to 1.0.", factor_name, target_value);
396 variable = 1.0;
397 }
398 else if (target_value <= 0.0)
399 {
400 node_->get_parameter_or<double>(std::string("robot_description_planning.default_") + factor_name, variable,
401 fallback_value);
402 if (target_value < 0.0)
403 {
404 RCLCPP_WARN(logger_, "max_%s < 0.0! Setting to default: %.2f.", factor_name, variable);
405 }
406 }
407 else
408 {
409 variable = target_value;
410 }
411 }
412
414 {
415 return *joint_state_target_;
416 }
417
419 {
420 return *joint_state_target_;
421 }
422
423 void setStartState(const moveit_msgs::msg::RobotState& start_state)
424 {
425 considered_start_state_ = start_state;
426 }
427
429 {
430 considered_start_state_ = moveit_msgs::msg::RobotState();
431 moveit::core::robotStateToRobotStateMsg(start_state, considered_start_state_, true);
432 }
433
435 {
436 // set message to empty diff
437 considered_start_state_ = moveit_msgs::msg::RobotState();
438 considered_start_state_.is_diff = true;
439 }
440
441 moveit::core::RobotStatePtr getStartState()
442 {
443 moveit::core::RobotStatePtr s;
445 moveit::core::robotStateMsgToRobotState(considered_start_state_, *s, true);
446 return s;
447 }
448
449 bool setJointValueTarget(const geometry_msgs::msg::Pose& eef_pose, const std::string& end_effector_link,
450 const std::string& frame, bool approx)
451 {
452 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
453 // this only works if we have an end-effector
454 if (!eef.empty())
455 {
456 // first we set the goal to be the same as the start state
457 moveit::core::RobotStatePtr c = getStartState();
458 if (c)
459 {
460 setTargetType(JOINT);
461 c->enforceBounds();
462 getTargetRobotState() = *c;
463 if (!getTargetRobotState().satisfiesBounds(getGoalJointTolerance()))
464 return false;
465 }
466 else
467 return false;
468
469 // we may need to do approximate IK
472
473 // if no frame transforms are needed, call IK directly
474 if (frame.empty() || moveit::core::Transforms::sameFrame(frame, getRobotModel()->getModelFrame()))
475 {
476 return getTargetRobotState().setFromIK(getJointModelGroup(), eef_pose, eef, 0.0,
478 }
479 else
480 {
481 // transform the pose into the model frame, then do IK
482 bool frame_found;
483 const Eigen::Isometry3d& t = getTargetRobotState().getFrameTransform(frame, &frame_found);
484 if (frame_found)
485 {
486 Eigen::Isometry3d p;
487 tf2::fromMsg(eef_pose, p);
488 return getTargetRobotState().setFromIK(getJointModelGroup(), t * p, eef, 0.0,
490 }
491 else
492 {
493 RCLCPP_ERROR(logger_, "Unable to transform from frame '%s' to frame '%s'", frame.c_str(),
494 getRobotModel()->getModelFrame().c_str());
495 return false;
496 }
497 }
498 }
499 else
500 return false;
501 }
502
503 void setEndEffectorLink(const std::string& end_effector)
504 {
505 end_effector_link_ = end_effector;
506 }
507
508 void clearPoseTarget(const std::string& end_effector_link)
509 {
510 pose_targets_.erase(end_effector_link);
511 }
512
514 {
515 pose_targets_.clear();
516 }
517
518 const std::string& getEndEffectorLink() const
519 {
520 return end_effector_link_;
521 }
522
523 const std::string& getEndEffector() const
524 {
525 if (!end_effector_link_.empty())
526 {
527 const std::vector<std::string>& possible_eefs =
528 getRobotModel()->getJointModelGroup(opt_.group_name)->getAttachedEndEffectorNames();
529 for (const std::string& possible_eef : possible_eefs)
530 {
531 if (getRobotModel()->getEndEffector(possible_eef)->hasLinkModel(end_effector_link_))
532 return possible_eef;
533 }
534 }
535 static std::string empty;
536 return empty;
537 }
538
539 bool setPoseTargets(const std::vector<geometry_msgs::msg::PoseStamped>& poses, const std::string& end_effector_link)
540 {
541 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
542 if (eef.empty())
543 {
544 RCLCPP_ERROR(logger_, "No end-effector to set the pose for");
545 return false;
546 }
547 else
548 {
549 pose_targets_[eef] = poses;
550 // make sure we don't store an actual stamp, since that will become stale can potentially cause tf errors
551 std::vector<geometry_msgs::msg::PoseStamped>& stored_poses = pose_targets_[eef];
552 for (geometry_msgs::msg::PoseStamped& stored_pose : stored_poses)
553 stored_pose.header.stamp = rclcpp::Time(0);
554 }
555 return true;
556 }
557
558 bool hasPoseTarget(const std::string& end_effector_link) const
559 {
560 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
561 return pose_targets_.find(eef) != pose_targets_.end();
562 }
563
564 const geometry_msgs::msg::PoseStamped& getPoseTarget(const std::string& end_effector_link) const
565 {
566 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
567
568 // if multiple pose targets are set, return the first one
569 std::map<std::string, std::vector<geometry_msgs::msg::PoseStamped>>::const_iterator jt = pose_targets_.find(eef);
570 if (jt != pose_targets_.end())
571 {
572 if (!jt->second.empty())
573 return jt->second.at(0);
574 }
575
576 // or return an error
577 static const geometry_msgs::msg::PoseStamped UNKNOWN;
578 RCLCPP_ERROR(logger_, "Pose for end-effector '%s' not known.", eef.c_str());
579 return UNKNOWN;
580 }
581
582 const std::vector<geometry_msgs::msg::PoseStamped>& getPoseTargets(const std::string& end_effector_link) const
583 {
584 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
585
586 std::map<std::string, std::vector<geometry_msgs::msg::PoseStamped>>::const_iterator jt = pose_targets_.find(eef);
587 if (jt != pose_targets_.end())
588 {
589 if (!jt->second.empty())
590 return jt->second;
591 }
592
593 // or return an error
594 static const std::vector<geometry_msgs::msg::PoseStamped> EMPTY;
595 RCLCPP_ERROR(logger_, "Poses for end-effector '%s' are not known.", eef.c_str());
596 return EMPTY;
597 }
598
599 void setPoseReferenceFrame(const std::string& pose_reference_frame)
600 {
601 pose_reference_frame_ = pose_reference_frame;
602 }
603
604 const std::string& getPoseReferenceFrame() const
605 {
606 return pose_reference_frame_;
607 }
608
609 void setTargetType(ActiveTargetType type)
610 {
611 active_target_ = type;
612 }
613
614 ActiveTargetType getTargetType() const
615 {
616 return active_target_;
617 }
618
619 bool startStateMonitor(double wait)
620 {
621 if (!current_state_monitor_)
622 {
623 RCLCPP_ERROR(logger_, "Unable to monitor current robot state");
624 return false;
625 }
626
627 // if needed, start the monitor and wait up to 1 second for a full robot state
628 if (!current_state_monitor_->isActive())
629 current_state_monitor_->startStateMonitor();
630
631 current_state_monitor_->waitForCompleteState(opt_.group_name, wait);
632 return true;
633 }
634
635 bool getCurrentState(moveit::core::RobotStatePtr& current_state, double wait_seconds = 1.0)
636 {
637 if (!current_state_monitor_)
638 {
639 RCLCPP_ERROR(logger_, "Unable to get current robot state");
640 return false;
641 }
642
643 // if needed, start the monitor and wait up to 1 second for a full robot state
644 if (!current_state_monitor_->isActive())
645 current_state_monitor_->startStateMonitor();
646
647 if (!current_state_monitor_->waitForCurrentState(node_->now(), wait_seconds))
648 {
649 RCLCPP_ERROR(logger_, "Failed to fetch current robot state");
650 return false;
651 }
652
653 current_state = current_state_monitor_->getCurrentState();
654 return true;
655 }
656
658 {
659 if (!move_action_client_ || !move_action_client_->action_server_is_ready())
660 {
661 RCLCPP_INFO_STREAM(logger_, "MoveGroup action client/server not ready");
662 return moveit::core::MoveItErrorCode::FAILURE;
663 }
664 RCLCPP_INFO_STREAM(logger_, "MoveGroup action client/server ready");
665
666 moveit_msgs::action::MoveGroup::Goal goal;
667 constructGoal(goal);
668 goal.planning_options.plan_only = true;
669 goal.planning_options.look_around = false;
670 goal.planning_options.replan = false;
671 goal.planning_options.planning_scene_diff.is_diff = true;
672 goal.planning_options.planning_scene_diff.robot_state.is_diff = true;
673
674 bool done = false;
675 rclcpp_action::ResultCode code = rclcpp_action::ResultCode::UNKNOWN;
676 std::shared_ptr<moveit_msgs::action::MoveGroup::Result> res;
677 auto send_goal_opts = rclcpp_action::Client<moveit_msgs::action::MoveGroup>::SendGoalOptions();
678
679 send_goal_opts.goal_response_callback =
680 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::SharedPtr& goal_handle) {
681 if (!goal_handle)
682 {
683 done = true;
684 RCLCPP_INFO(logger_, "Planning request rejected");
685 }
686 else
687 RCLCPP_INFO(logger_, "Planning request accepted");
688 };
689 send_goal_opts.result_callback =
690 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::WrappedResult& result) {
691 res = result.result;
692 code = result.code;
693 done = true;
694
695 switch (result.code)
696 {
697 case rclcpp_action::ResultCode::SUCCEEDED:
698 RCLCPP_INFO(logger_, "Planning request complete!");
699 break;
700 case rclcpp_action::ResultCode::ABORTED:
701 RCLCPP_INFO(logger_, "Planning request aborted");
702 return;
703 case rclcpp_action::ResultCode::CANCELED:
704 RCLCPP_INFO(logger_, "Planning request canceled");
705 return;
706 default:
707 RCLCPP_INFO(logger_, "Planning request unknown result code");
708 return;
709 }
710 };
711
712 auto goal_handle_future = move_action_client_->async_send_goal(goal, send_goal_opts);
713
714 // wait until send_goal_opts.result_callback is called
715 while (!done)
716 {
717 std::this_thread::sleep_for(std::chrono::milliseconds(1));
718 }
719
720 if (code != rclcpp_action::ResultCode::SUCCEEDED)
721 {
722 RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::plan() failed or timeout reached");
723 return res->error_code;
724 }
725
726 plan.trajectory = res->planned_trajectory;
727 plan.start_state = res->trajectory_start;
728 plan.planning_time = res->planning_time;
729 RCLCPP_INFO(logger_, "time taken to generate plan: %g seconds", plan.planning_time);
730
731 return res->error_code;
732 }
733
735 {
736 if (!move_action_client_ || !move_action_client_->action_server_is_ready())
737 {
738 RCLCPP_INFO_STREAM(logger_, "MoveGroup action client/server not ready");
739 return moveit::core::MoveItErrorCode::FAILURE;
740 }
741
742 moveit_msgs::action::MoveGroup::Goal goal;
743 constructGoal(goal);
744 goal.planning_options.plan_only = false;
745 goal.planning_options.look_around = can_look_;
746 goal.planning_options.replan = can_replan_;
747 goal.planning_options.replan_delay = replan_delay_;
748 goal.planning_options.planning_scene_diff.is_diff = true;
749 goal.planning_options.planning_scene_diff.robot_state.is_diff = true;
750
751 bool done = false;
752 rclcpp_action::ResultCode code = rclcpp_action::ResultCode::UNKNOWN;
753 std::shared_ptr<moveit_msgs::action::MoveGroup_Result> res;
754 auto send_goal_opts = rclcpp_action::Client<moveit_msgs::action::MoveGroup>::SendGoalOptions();
755
756 send_goal_opts.goal_response_callback =
757 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::SharedPtr& goal_handle) {
758 if (!goal_handle)
759 {
760 done = true;
761 RCLCPP_INFO(logger_, "Plan and Execute request rejected");
762 }
763 else
764 RCLCPP_INFO(logger_, "Plan and Execute request accepted");
765 };
766 send_goal_opts.result_callback =
767 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::WrappedResult& result) {
768 res = result.result;
769 code = result.code;
770 done = true;
771
772 switch (result.code)
773 {
774 case rclcpp_action::ResultCode::SUCCEEDED:
775 RCLCPP_INFO(logger_, "Plan and Execute request complete!");
776 break;
777 case rclcpp_action::ResultCode::ABORTED:
778 RCLCPP_INFO(logger_, "Plan and Execute request aborted");
779 return;
780 case rclcpp_action::ResultCode::CANCELED:
781 RCLCPP_INFO(logger_, "Plan and Execute request canceled");
782 return;
783 default:
784 RCLCPP_INFO(logger_, "Plan and Execute request unknown result code");
785 return;
786 }
787 };
788 auto goal_handle_future = move_action_client_->async_send_goal(goal, send_goal_opts);
789 if (!wait)
790 return moveit::core::MoveItErrorCode::SUCCESS;
791
792 // wait until send_goal_opts.result_callback is called
793 while (!done)
794 {
795 std::this_thread::sleep_for(std::chrono::milliseconds(1));
796 }
797
798 if (code != rclcpp_action::ResultCode::SUCCEEDED)
799 {
800 RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::move() failed or timeout reached");
801 }
802 return res->error_code;
803 }
804
805 moveit::core::MoveItErrorCode execute(const moveit_msgs::msg::RobotTrajectory& trajectory, bool wait,
806 const std::vector<std::string>& controllers = std::vector<std::string>())
807 {
808 if (!execute_action_client_ || !execute_action_client_->action_server_is_ready())
809 {
810 RCLCPP_INFO_STREAM(logger_, "execute_action_client_ client/server not ready");
811 return moveit::core::MoveItErrorCode::FAILURE;
812 }
813
814 bool done = false;
815 rclcpp_action::ResultCode code = rclcpp_action::ResultCode::UNKNOWN;
816 std::shared_ptr<moveit_msgs::action::ExecuteTrajectory_Result> res;
817 auto send_goal_opts = rclcpp_action::Client<moveit_msgs::action::ExecuteTrajectory>::SendGoalOptions();
818
819 send_goal_opts.goal_response_callback =
820 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::ExecuteTrajectory>::SharedPtr& goal_handle) {
821 if (!goal_handle)
822 {
823 done = true;
824 RCLCPP_INFO(logger_, "Execute request rejected");
825 }
826 else
827 RCLCPP_INFO(logger_, "Execute request accepted");
828 };
829 send_goal_opts.result_callback =
830 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::ExecuteTrajectory>::WrappedResult& result) {
831 res = result.result;
832 code = result.code;
833 done = true;
834
835 switch (result.code)
836 {
837 case rclcpp_action::ResultCode::SUCCEEDED:
838 RCLCPP_INFO(logger_, "Execute request success!");
839 break;
840 case rclcpp_action::ResultCode::ABORTED:
841 RCLCPP_INFO(logger_, "Execute request aborted");
842 return;
843 case rclcpp_action::ResultCode::CANCELED:
844 RCLCPP_INFO(logger_, "Execute request canceled");
845 return;
846 default:
847 RCLCPP_INFO(logger_, "Execute request unknown result code");
848 return;
849 }
850 };
851
852 moveit_msgs::action::ExecuteTrajectory::Goal goal;
853 goal.trajectory = trajectory;
854 goal.controller_names = controllers;
855
856 auto goal_handle_future = execute_action_client_->async_send_goal(goal, send_goal_opts);
857 if (!wait)
858 return moveit::core::MoveItErrorCode::SUCCESS;
859
860 // wait until send_goal_opts.result_callback is called
861 while (!done)
862 {
863 std::this_thread::sleep_for(std::chrono::milliseconds(1));
864 }
865
866 if (code != rclcpp_action::ResultCode::SUCCEEDED)
867 {
868 RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::execute() failed or timeout reached");
869 }
870 return res->error_code;
871 }
872
873 double computeCartesianPath(const std::vector<geometry_msgs::msg::Pose>& waypoints, double step,
874 moveit_msgs::msg::RobotTrajectory& msg,
875 const moveit_msgs::msg::Constraints& path_constraints, bool avoid_collisions,
876 moveit_msgs::msg::MoveItErrorCodes& error_code)
877 {
878 auto req = std::make_shared<moveit_msgs::srv::GetCartesianPath::Request>();
879 moveit_msgs::srv::GetCartesianPath::Response::SharedPtr response;
880
881 req->start_state = considered_start_state_;
882 req->group_name = opt_.group_name;
883 req->header.frame_id = getPoseReferenceFrame();
884 req->header.stamp = getClock()->now();
885 req->waypoints = waypoints;
886 req->max_step = step;
887 req->path_constraints = path_constraints;
888 req->avoid_collisions = avoid_collisions;
889 req->link_name = getEndEffectorLink();
890 req->max_velocity_scaling_factor = max_velocity_scaling_factor_;
891 req->max_acceleration_scaling_factor = max_acceleration_scaling_factor_;
892
893 auto future_response = cartesian_path_service_->async_send_request(req);
894 if (future_response.valid())
895 {
896 response = future_response.get();
897 error_code = response->error_code;
898 if (response->error_code.val == moveit_msgs::msg::MoveItErrorCodes::SUCCESS)
899 {
900 msg = response->solution;
901 return response->fraction;
902 }
903 else
904 return -1.0;
905 }
906 else
907 {
908 error_code.val = error_code.FAILURE;
909 return -1.0;
910 }
911 }
912
913 void stop()
914 {
915 if (trajectory_event_publisher_)
916 {
917 std_msgs::msg::String event;
918 event.data = "stop";
919 trajectory_event_publisher_->publish(event);
920 }
921 }
922
923 bool attachObject(const std::string& object, const std::string& link, const std::vector<std::string>& touch_links)
924 {
925 std::string l = link.empty() ? getEndEffectorLink() : link;
926 if (l.empty())
927 {
928 const std::vector<std::string>& links = joint_model_group_->getLinkModelNames();
929 if (!links.empty())
930 l = links[0];
931 }
932 if (l.empty())
933 {
934 RCLCPP_ERROR(logger_, "No known link to attach object '%s' to", object.c_str());
935 return false;
936 }
937 moveit_msgs::msg::AttachedCollisionObject aco;
938 aco.object.id = object;
939 aco.link_name.swap(l);
940 if (touch_links.empty())
941 {
942 aco.touch_links.push_back(aco.link_name);
943 }
944 else
945 {
946 aco.touch_links = touch_links;
947 }
948 aco.object.operation = moveit_msgs::msg::CollisionObject::ADD;
949 attached_object_publisher_->publish(aco);
950 return true;
951 }
952
953 bool detachObject(const std::string& name)
954 {
955 moveit_msgs::msg::AttachedCollisionObject aco;
956 // if name is a link
957 if (!name.empty() && joint_model_group_->hasLinkModel(name))
958 {
959 aco.link_name = name;
960 }
961 else
962 {
963 aco.object.id = name;
964 }
965 aco.object.operation = moveit_msgs::msg::CollisionObject::REMOVE;
966 if (aco.link_name.empty() && aco.object.id.empty())
967 {
968 // we only want to detach objects for this group
969 const std::vector<std::string>& lnames = joint_model_group_->getLinkModelNames();
970 for (const std::string& lname : lnames)
971 {
972 aco.link_name = lname;
973 attached_object_publisher_->publish(aco);
974 }
975 }
976 else
977 {
978 attached_object_publisher_->publish(aco);
979 }
980 return true;
981 }
982
984 {
985 return goal_position_tolerance_;
986 }
987
989 {
990 return goal_orientation_tolerance_;
991 }
992
994 {
995 return goal_joint_tolerance_;
996 }
997
998 void setGoalJointTolerance(double tolerance)
999 {
1000 goal_joint_tolerance_ = tolerance;
1001 }
1002
1003 void setGoalPositionTolerance(double tolerance)
1004 {
1005 goal_position_tolerance_ = tolerance;
1006 }
1007
1008 void setGoalOrientationTolerance(double tolerance)
1009 {
1010 goal_orientation_tolerance_ = tolerance;
1011 }
1012
1013 void setPlanningTime(double seconds)
1014 {
1015 if (seconds > 0.0)
1016 allowed_planning_time_ = seconds;
1017 }
1018
1019 double getPlanningTime() const
1020 {
1021 return allowed_planning_time_;
1022 }
1023
1024 void constructRobotState(moveit_msgs::msg::RobotState& state) const
1025 {
1026 state = considered_start_state_;
1027 }
1028
1029 void constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest& request) const
1030 {
1031 request.group_name = opt_.group_name;
1032 request.num_planning_attempts = num_planning_attempts_;
1033 request.max_velocity_scaling_factor = max_velocity_scaling_factor_;
1034 request.max_acceleration_scaling_factor = max_acceleration_scaling_factor_;
1035 request.allowed_planning_time = allowed_planning_time_;
1036 request.pipeline_id = planning_pipeline_id_;
1037 request.planner_id = planner_id_;
1038 request.workspace_parameters = workspace_parameters_;
1039 request.start_state = considered_start_state_;
1040
1041 if (active_target_ == JOINT)
1042 {
1043 request.goal_constraints.resize(1);
1044 request.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(
1045 getTargetRobotState(), joint_model_group_, goal_joint_tolerance_);
1046 }
1047 else if (active_target_ == POSE || active_target_ == POSITION || active_target_ == ORIENTATION)
1048 {
1049 // find out how many goals are specified
1050 std::size_t goal_count = 0;
1051 for (const auto& pose_target : pose_targets_)
1052 goal_count = std::max(goal_count, pose_target.second.size());
1053
1054 // start filling the goals;
1055 // each end effector has a number of possible poses (K) as valid goals
1056 // but there could be multiple end effectors specified, so we want each end effector
1057 // to reach the goal that corresponds to the goals of the other end effectors
1058 request.goal_constraints.resize(goal_count);
1059
1060 for (const auto& pose_target : pose_targets_)
1061 {
1062 for (std::size_t i = 0; i < pose_target.second.size(); ++i)
1063 {
1064 moveit_msgs::msg::Constraints c = kinematic_constraints::constructGoalConstraints(
1065 pose_target.first, pose_target.second[i], goal_position_tolerance_, goal_orientation_tolerance_);
1066 if (active_target_ == ORIENTATION)
1067 c.position_constraints.clear();
1068 if (active_target_ == POSITION)
1069 c.orientation_constraints.clear();
1070 request.goal_constraints[i] = kinematic_constraints::mergeConstraints(request.goal_constraints[i], c);
1071 }
1072 }
1073 }
1074 else
1075 RCLCPP_ERROR(logger_, "Unable to construct MotionPlanRequest representation");
1076
1077 if (path_constraints_)
1078 request.path_constraints = *path_constraints_;
1079 if (trajectory_constraints_)
1080 request.trajectory_constraints = *trajectory_constraints_;
1081 }
1082
1083 void constructGoal(moveit_msgs::action::MoveGroup::Goal& goal) const
1084 {
1085 constructMotionPlanRequest(goal.request);
1086 }
1087
1088 void setPathConstraints(const moveit_msgs::msg::Constraints& constraint)
1089 {
1090 path_constraints_ = std::make_unique<moveit_msgs::msg::Constraints>(constraint);
1091 }
1092
1093 bool setPathConstraints(const std::string& constraint)
1094 {
1095 if (constraints_storage_)
1096 {
1098 if (constraints_storage_->getConstraints(msg_m, constraint, robot_model_->getName(), opt_.group_name))
1099 {
1100 path_constraints_ =
1101 std::make_unique<moveit_msgs::msg::Constraints>(static_cast<moveit_msgs::msg::Constraints>(*msg_m));
1102 return true;
1103 }
1104 else
1105 return false;
1106 }
1107 else
1108 return false;
1109 }
1110
1112 {
1113 path_constraints_.reset();
1114 }
1115
1116 void setTrajectoryConstraints(const moveit_msgs::msg::TrajectoryConstraints& constraint)
1117 {
1118 trajectory_constraints_ = std::make_unique<moveit_msgs::msg::TrajectoryConstraints>(constraint);
1119 }
1120
1122 {
1123 trajectory_constraints_.reset();
1124 }
1125
1126 std::vector<std::string> getKnownConstraints() const
1127 {
1128 while (initializing_constraints_)
1129 {
1130 std::chrono::duration<double> d(0.01);
1131 rclcpp::sleep_for(std::chrono::duration_cast<std::chrono::nanoseconds>(d), rclcpp::Context::SharedPtr(nullptr));
1132 }
1133
1134 std::vector<std::string> c;
1135 if (constraints_storage_)
1136 constraints_storage_->getKnownConstraints(c, robot_model_->getName(), opt_.group_name);
1137
1138 return c;
1139 }
1140
1141 moveit_msgs::msg::Constraints getPathConstraints() const
1142 {
1143 if (path_constraints_)
1144 {
1145 return *path_constraints_;
1146 }
1147 else
1148 {
1149 return moveit_msgs::msg::Constraints();
1150 }
1151 }
1152
1153 moveit_msgs::msg::TrajectoryConstraints getTrajectoryConstraints() const
1154 {
1155 if (trajectory_constraints_)
1156 {
1157 return *trajectory_constraints_;
1158 }
1159 else
1160 {
1161 return moveit_msgs::msg::TrajectoryConstraints();
1162 }
1163 }
1164
1165 void initializeConstraintsStorage(const std::string& host, unsigned int port)
1166 {
1167 initializing_constraints_ = true;
1168 if (constraints_init_thread_)
1169 constraints_init_thread_->join();
1170 constraints_init_thread_ =
1171 std::make_unique<std::thread>([this, host, port] { initializeConstraintsStorageThread(host, port); });
1172 }
1173
1174 void setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
1175 {
1176 workspace_parameters_.header.frame_id = getRobotModel()->getModelFrame();
1177 workspace_parameters_.header.stamp = getClock()->now();
1178 workspace_parameters_.min_corner.x = minx;
1179 workspace_parameters_.min_corner.y = miny;
1180 workspace_parameters_.min_corner.z = minz;
1181 workspace_parameters_.max_corner.x = maxx;
1182 workspace_parameters_.max_corner.y = maxy;
1183 workspace_parameters_.max_corner.z = maxz;
1184 }
1185
1186 rclcpp::Clock::SharedPtr getClock()
1187 {
1188 return node_->get_clock();
1189 }
1190
1191private:
1192 void initializeConstraintsStorageThread(const std::string& host, unsigned int port)
1193 {
1194 // Set up db
1195 try
1196 {
1197 warehouse_ros::DatabaseConnection::Ptr conn = moveit_warehouse::loadDatabase(node_);
1198 conn->setParams(host, port);
1199 if (conn->connect())
1200 {
1201 constraints_storage_ = std::make_unique<moveit_warehouse::ConstraintsStorage>(conn);
1202 }
1203 }
1204 catch (std::exception& ex)
1205 {
1206 RCLCPP_ERROR(logger_, "%s", ex.what());
1207 }
1208 initializing_constraints_ = false;
1209 }
1210
1211 Options opt_;
1212 rclcpp::Node::SharedPtr node_;
1213 rclcpp::Logger logger_;
1214 rclcpp::CallbackGroup::SharedPtr callback_group_;
1215 rclcpp::executors::SingleThreadedExecutor callback_executor_;
1216 std::thread callback_thread_;
1217 std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
1218 moveit::core::RobotModelConstPtr robot_model_;
1219 planning_scene_monitor::CurrentStateMonitorPtr current_state_monitor_;
1220
1221 std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::MoveGroup>> move_action_client_;
1222 // std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::Pickup>> pick_action_client_;
1223 // std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::Place>> place_action_client_;
1224 std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::ExecuteTrajectory>> execute_action_client_;
1225
1226 // general planning params
1227 moveit_msgs::msg::RobotState considered_start_state_;
1228 moveit_msgs::msg::WorkspaceParameters workspace_parameters_;
1229 double allowed_planning_time_;
1230 std::string planning_pipeline_id_;
1231 std::string planner_id_;
1232 unsigned int num_planning_attempts_;
1233 double max_velocity_scaling_factor_;
1234 double max_acceleration_scaling_factor_;
1235 double goal_joint_tolerance_;
1236 double goal_position_tolerance_;
1237 double goal_orientation_tolerance_;
1238 bool can_look_;
1239 int32_t look_around_attempts_;
1240 bool can_replan_;
1241 int32_t replan_attempts_;
1242 double replan_delay_;
1243
1244 // joint state goal
1245 moveit::core::RobotStatePtr joint_state_target_;
1246 const moveit::core::JointModelGroup* joint_model_group_;
1247
1248 // pose goal;
1249 // for each link we have a set of possible goal locations;
1250 std::map<std::string, std::vector<geometry_msgs::msg::PoseStamped>> pose_targets_;
1251
1252 // common properties for goals
1253 ActiveTargetType active_target_;
1254 std::unique_ptr<moveit_msgs::msg::Constraints> path_constraints_;
1255 std::unique_ptr<moveit_msgs::msg::TrajectoryConstraints> trajectory_constraints_;
1256 std::string end_effector_link_;
1257 std::string pose_reference_frame_;
1258
1259 // ROS communication
1260 rclcpp::Publisher<std_msgs::msg::String>::SharedPtr trajectory_event_publisher_;
1261 rclcpp::Publisher<moveit_msgs::msg::AttachedCollisionObject>::SharedPtr attached_object_publisher_;
1262 rclcpp::Client<moveit_msgs::srv::QueryPlannerInterfaces>::SharedPtr query_service_;
1263 rclcpp::Client<moveit_msgs::srv::GetPlannerParams>::SharedPtr get_params_service_;
1264 rclcpp::Client<moveit_msgs::srv::SetPlannerParams>::SharedPtr set_params_service_;
1265 rclcpp::Client<moveit_msgs::srv::GetCartesianPath>::SharedPtr cartesian_path_service_;
1266 // rclcpp::Client<moveit_msgs::srv::GraspPlanning>::SharedPtr plan_grasps_service_;
1267 std::unique_ptr<moveit_warehouse::ConstraintsStorage> constraints_storage_;
1268 std::unique_ptr<std::thread> constraints_init_thread_;
1269 bool initializing_constraints_;
1270};
1271
1272MoveGroupInterface::MoveGroupInterface(const rclcpp::Node::SharedPtr& node, const std::string& group_name,
1273 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
1274 const rclcpp::Duration& wait_for_servers)
1275 : logger_(moveit::getLogger("moveit.ros.move_group_interface"))
1276{
1277 if (!rclcpp::ok())
1278 throw std::runtime_error("ROS does not seem to be running");
1279 impl_ =
1280 new MoveGroupInterfaceImpl(node, Options(group_name), tf_buffer ? tf_buffer : getSharedTF(), wait_for_servers);
1281}
1282
1283MoveGroupInterface::MoveGroupInterface(const rclcpp::Node::SharedPtr& node, const Options& opt,
1284 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
1285 const rclcpp::Duration& wait_for_servers)
1286 : logger_(moveit::getLogger("moveit.ros.move_group_interface"))
1287{
1288 impl_ = new MoveGroupInterfaceImpl(node, opt, tf_buffer ? tf_buffer : getSharedTF(), wait_for_servers);
1289}
1290
1292{
1293 delete impl_;
1294}
1295
1297 : remembered_joint_values_(std::move(other.remembered_joint_values_))
1298 , impl_(other.impl_)
1299 , logger_(std::move(other.logger_))
1300{
1301 other.impl_ = nullptr;
1302}
1303
1305{
1306 if (this != &other)
1307 {
1308 delete impl_;
1309 impl_ = other.impl_;
1310 logger_ = other.logger_;
1311 remembered_joint_values_ = std::move(other.remembered_joint_values_);
1312 other.impl_ = nullptr;
1313 }
1314
1315 return *this;
1316}
1317
1318const std::string& MoveGroupInterface::getName() const
1319{
1320 return impl_->getOptions().group_name;
1321}
1322
1323const std::vector<std::string>& MoveGroupInterface::getNamedTargets() const
1324{
1325 // The pointer returned by getJointModelGroup is guaranteed by the class
1326 // constructor to always be non-null
1327 return impl_->getJointModelGroup()->getDefaultStateNames();
1328}
1329
1330const std::shared_ptr<tf2_ros::Buffer>& MoveGroupInterface::getTF() const
1331{
1332 return impl_->getTF();
1333}
1334
1335moveit::core::RobotModelConstPtr MoveGroupInterface::getRobotModel() const
1336{
1337 return impl_->getRobotModel();
1338}
1339
1340bool MoveGroupInterface::getInterfaceDescription(moveit_msgs::msg::PlannerInterfaceDescription& desc) const
1341{
1342 return impl_->getInterfaceDescription(desc);
1343}
1344
1345bool MoveGroupInterface::getInterfaceDescriptions(std::vector<moveit_msgs::msg::PlannerInterfaceDescription>& desc) const
1346{
1347 return impl_->getInterfaceDescriptions(desc);
1348}
1349
1350std::map<std::string, std::string> MoveGroupInterface::getPlannerParams(const std::string& planner_id,
1351 const std::string& group) const
1352{
1353 return impl_->getPlannerParams(planner_id, group);
1354}
1355
1356void MoveGroupInterface::setPlannerParams(const std::string& planner_id, const std::string& group,
1357 const std::map<std::string, std::string>& params, bool replace)
1358{
1359 impl_->setPlannerParams(planner_id, group, params, replace);
1360}
1361
1363{
1364 return impl_->getDefaultPlanningPipelineId();
1365}
1366
1367void MoveGroupInterface::setPlanningPipelineId(const std::string& pipeline_id)
1368{
1369 impl_->setPlanningPipelineId(pipeline_id);
1370}
1371
1373{
1374 return impl_->getPlanningPipelineId();
1375}
1376
1377std::string MoveGroupInterface::getDefaultPlannerId(const std::string& group) const
1378{
1379 return impl_->getDefaultPlannerId(group);
1380}
1381
1382void MoveGroupInterface::setPlannerId(const std::string& planner_id)
1383{
1384 impl_->setPlannerId(planner_id);
1385}
1386
1387const std::string& MoveGroupInterface::getPlannerId() const
1388{
1389 return impl_->getPlannerId();
1390}
1391
1392void MoveGroupInterface::setNumPlanningAttempts(unsigned int num_planning_attempts)
1393{
1394 impl_->setNumPlanningAttempts(num_planning_attempts);
1395}
1396
1397void MoveGroupInterface::setMaxVelocityScalingFactor(double max_velocity_scaling_factor)
1398{
1399 impl_->setMaxVelocityScalingFactor(max_velocity_scaling_factor);
1400}
1401
1406
1407void MoveGroupInterface::setMaxAccelerationScalingFactor(double max_acceleration_scaling_factor)
1408{
1409 impl_->setMaxAccelerationScalingFactor(max_acceleration_scaling_factor);
1410}
1411
1416
1421
1422rclcpp_action::Client<moveit_msgs::action::MoveGroup>& MoveGroupInterface::getMoveGroupClient() const
1423{
1424 return impl_->getMoveGroupClient();
1425}
1426
1428{
1429 return impl_->move(true);
1430}
1431
1433 const std::vector<std::string>& controllers)
1434{
1435 return impl_->execute(plan.trajectory, false, controllers);
1436}
1437
1438moveit::core::MoveItErrorCode MoveGroupInterface::asyncExecute(const moveit_msgs::msg::RobotTrajectory& trajectory,
1439 const std::vector<std::string>& controllers)
1440{
1441 return impl_->execute(trajectory, false, controllers);
1442}
1443
1444moveit::core::MoveItErrorCode MoveGroupInterface::execute(const Plan& plan, const std::vector<std::string>& controllers)
1445{
1446 return impl_->execute(plan.trajectory, true, controllers);
1447}
1448
1449moveit::core::MoveItErrorCode MoveGroupInterface::execute(const moveit_msgs::msg::RobotTrajectory& trajectory,
1450 const std::vector<std::string>& controllers)
1451{
1452 return impl_->execute(trajectory, true, controllers);
1453}
1454
1459
1460double MoveGroupInterface::computeCartesianPath(const std::vector<geometry_msgs::msg::Pose>& waypoints, double eef_step,
1461 moveit_msgs::msg::RobotTrajectory& trajectory, bool avoid_collisions,
1462 moveit_msgs::msg::MoveItErrorCodes* error_code)
1463{
1464 moveit_msgs::msg::Constraints path_constraints_tmp;
1465 return computeCartesianPath(waypoints, eef_step, trajectory, moveit_msgs::msg::Constraints(), avoid_collisions,
1466 error_code);
1467}
1468
1469double MoveGroupInterface::computeCartesianPath(const std::vector<geometry_msgs::msg::Pose>& waypoints, double eef_step,
1470 moveit_msgs::msg::RobotTrajectory& trajectory,
1471 const moveit_msgs::msg::Constraints& path_constraints,
1472 bool avoid_collisions, moveit_msgs::msg::MoveItErrorCodes* error_code)
1473{
1474 if (error_code)
1475 {
1476 return impl_->computeCartesianPath(waypoints, eef_step, trajectory, path_constraints, avoid_collisions, *error_code);
1477 }
1478 else
1479 {
1480 moveit_msgs::msg::MoveItErrorCodes err_tmp;
1481 err_tmp.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
1482 moveit_msgs::msg::MoveItErrorCodes& err = error_code ? *error_code : err_tmp;
1483 return impl_->computeCartesianPath(waypoints, eef_step, trajectory, path_constraints, avoid_collisions, err);
1484 }
1485}
1486
1488{
1489 impl_->stop();
1490}
1491
1492void MoveGroupInterface::setStartState(const moveit_msgs::msg::RobotState& start_state)
1493{
1494 impl_->setStartState(start_state);
1495}
1496
1498{
1499 impl_->setStartState(start_state);
1500}
1501
1506
1512
1513const std::vector<std::string>& MoveGroupInterface::getJointNames() const
1514{
1515 return impl_->getJointModelGroup()->getVariableNames();
1516}
1517
1518const std::vector<std::string>& MoveGroupInterface::getLinkNames() const
1519{
1520 return impl_->getJointModelGroup()->getLinkModelNames();
1521}
1522
1523std::map<std::string, double> MoveGroupInterface::getNamedTargetValues(const std::string& name) const
1524{
1525 std::map<std::string, std::vector<double>>::const_iterator it = remembered_joint_values_.find(name);
1526 std::map<std::string, double> positions;
1527
1528 if (it != remembered_joint_values_.cend())
1529 {
1530 std::vector<std::string> names = impl_->getJointModelGroup()->getVariableNames();
1531 for (size_t x = 0; x < names.size(); ++x)
1532 {
1533 positions[names[x]] = it->second[x];
1534 }
1535 }
1536 else
1537 {
1538 if (!impl_->getJointModelGroup()->getVariableDefaultPositions(name, positions))
1539 {
1540 RCLCPP_ERROR(logger_, "The requested named target '%s' does not exist, returning empty positions.", name.c_str());
1541 }
1542 }
1543 return positions;
1544}
1545
1546bool MoveGroupInterface::setNamedTarget(const std::string& name)
1547{
1548 std::map<std::string, std::vector<double>>::const_iterator it = remembered_joint_values_.find(name);
1549 if (it != remembered_joint_values_.end())
1550 {
1551 return setJointValueTarget(it->second);
1552 }
1553 else
1554 {
1555 if (impl_->getTargetRobotState().setToDefaultValues(impl_->getJointModelGroup(), name))
1556 {
1557 impl_->setTargetType(JOINT);
1558 return true;
1559 }
1560 RCLCPP_ERROR(logger_, "The requested named target '%s' does not exist", name.c_str());
1561 return false;
1562 }
1563}
1564
1565void MoveGroupInterface::getJointValueTarget(std::vector<double>& group_variable_values) const
1566{
1567 impl_->getTargetRobotState().copyJointGroupPositions(impl_->getJointModelGroup(), group_variable_values);
1568}
1569
1570bool MoveGroupInterface::setJointValueTarget(const std::vector<double>& joint_values)
1571{
1572 const auto n_group_joints = impl_->getJointModelGroup()->getVariableCount();
1573 if (joint_values.size() != n_group_joints)
1574 {
1575 RCLCPP_DEBUG_STREAM(logger_, "Provided joint value list has length " << joint_values.size() << " but group "
1576 << impl_->getJointModelGroup()->getName()
1577 << " has " << n_group_joints << " joints");
1578 return false;
1579 }
1580 impl_->setTargetType(JOINT);
1581 impl_->getTargetRobotState().setJointGroupPositions(impl_->getJointModelGroup(), joint_values);
1583}
1584
1585bool MoveGroupInterface::setJointValueTarget(const std::map<std::string, double>& variable_values)
1586{
1587 const auto& allowed = impl_->getJointModelGroup()->getVariableNames();
1588 for (const auto& pair : variable_values)
1589 {
1590 if (std::find(allowed.begin(), allowed.end(), pair.first) == allowed.end())
1591 {
1592 RCLCPP_ERROR_STREAM(logger_, "joint variable " << pair.first << " is not part of group "
1593 << impl_->getJointModelGroup()->getName());
1594 return false;
1595 }
1596 }
1597
1598 impl_->setTargetType(JOINT);
1599 impl_->getTargetRobotState().setVariablePositions(variable_values);
1601}
1602
1603bool MoveGroupInterface::setJointValueTarget(const std::vector<std::string>& variable_names,
1604 const std::vector<double>& variable_values)
1605{
1606 if (variable_names.size() != variable_values.size())
1607 {
1608 RCLCPP_ERROR_STREAM(logger_, "sizes of name and position arrays do not match");
1609 return false;
1610 }
1611 const auto& allowed = impl_->getJointModelGroup()->getVariableNames();
1612 for (const auto& variable_name : variable_names)
1613 {
1614 if (std::find(allowed.begin(), allowed.end(), variable_name) == allowed.end())
1615 {
1616 RCLCPP_ERROR_STREAM(logger_, "joint variable " << variable_name << " is not part of group "
1617 << impl_->getJointModelGroup()->getName());
1618 return false;
1619 }
1620 }
1621
1622 impl_->setTargetType(JOINT);
1623 impl_->getTargetRobotState().setVariablePositions(variable_names, variable_values);
1625}
1626
1628{
1629 impl_->setTargetType(JOINT);
1630 impl_->getTargetRobotState() = rstate;
1632}
1633
1634bool MoveGroupInterface::setJointValueTarget(const std::string& joint_name, double value)
1635{
1636 std::vector<double> values(1, value);
1637 return setJointValueTarget(joint_name, values);
1638}
1639
1640bool MoveGroupInterface::setJointValueTarget(const std::string& joint_name, const std::vector<double>& values)
1641{
1642 impl_->setTargetType(JOINT);
1643 const moveit::core::JointModel* jm = impl_->getJointModelGroup()->getJointModel(joint_name);
1644 if (jm && jm->getVariableCount() == values.size())
1645 {
1646 impl_->getTargetRobotState().setJointPositions(jm, values);
1647 return impl_->getTargetRobotState().satisfiesBounds(jm, impl_->getGoalJointTolerance());
1648 }
1649
1650 RCLCPP_ERROR_STREAM(logger_,
1651 "joint " << joint_name << " is not part of group " << impl_->getJointModelGroup()->getName());
1652 return false;
1653}
1654
1655bool MoveGroupInterface::setJointValueTarget(const sensor_msgs::msg::JointState& state)
1656{
1657 return setJointValueTarget(state.name, state.position);
1658}
1659
1660bool MoveGroupInterface::setJointValueTarget(const geometry_msgs::msg::Pose& eef_pose,
1661 const std::string& end_effector_link)
1662{
1663 return impl_->setJointValueTarget(eef_pose, end_effector_link, "", false);
1664}
1665
1666bool MoveGroupInterface::setJointValueTarget(const geometry_msgs::msg::PoseStamped& eef_pose,
1667 const std::string& end_effector_link)
1668{
1669 return impl_->setJointValueTarget(eef_pose.pose, end_effector_link, eef_pose.header.frame_id, false);
1670}
1671
1672bool MoveGroupInterface::setJointValueTarget(const Eigen::Isometry3d& eef_pose, const std::string& end_effector_link)
1673{
1674 geometry_msgs::msg::Pose msg = tf2::toMsg(eef_pose);
1675 return setJointValueTarget(msg, end_effector_link);
1676}
1677
1678bool MoveGroupInterface::setApproximateJointValueTarget(const geometry_msgs::msg::Pose& eef_pose,
1679 const std::string& end_effector_link)
1680{
1681 return impl_->setJointValueTarget(eef_pose, end_effector_link, "", true);
1682}
1683
1684bool MoveGroupInterface::setApproximateJointValueTarget(const geometry_msgs::msg::PoseStamped& eef_pose,
1685 const std::string& end_effector_link)
1686{
1687 return impl_->setJointValueTarget(eef_pose.pose, end_effector_link, eef_pose.header.frame_id, true);
1688}
1689
1690bool MoveGroupInterface::setApproximateJointValueTarget(const Eigen::Isometry3d& eef_pose,
1691 const std::string& end_effector_link)
1692{
1693 geometry_msgs::msg::Pose msg = tf2::toMsg(eef_pose);
1694 return setApproximateJointValueTarget(msg, end_effector_link);
1695}
1696
1701
1703{
1704 return impl_->getEndEffectorLink();
1705}
1706
1707const std::string& MoveGroupInterface::getEndEffector() const
1708{
1709 return impl_->getEndEffector();
1710}
1711
1712bool MoveGroupInterface::setEndEffectorLink(const std::string& link_name)
1713{
1714 if (impl_->getEndEffectorLink().empty() || link_name.empty())
1715 return false;
1716 impl_->setEndEffectorLink(link_name);
1717 impl_->setTargetType(POSE);
1718 return true;
1719}
1720
1721bool MoveGroupInterface::setEndEffector(const std::string& eef_name)
1722{
1723 const moveit::core::JointModelGroup* jmg = impl_->getRobotModel()->getEndEffector(eef_name);
1724 if (jmg)
1725 return setEndEffectorLink(jmg->getEndEffectorParentGroup().second);
1726 return false;
1727}
1728
1729void MoveGroupInterface::clearPoseTarget(const std::string& end_effector_link)
1730{
1731 impl_->clearPoseTarget(end_effector_link);
1732}
1733
1738
1739bool MoveGroupInterface::setPoseTarget(const Eigen::Isometry3d& pose, const std::string& end_effector_link)
1740{
1741 std::vector<geometry_msgs::msg::PoseStamped> pose_msg(1);
1742 pose_msg[0].pose = tf2::toMsg(pose);
1743 pose_msg[0].header.frame_id = getPoseReferenceFrame();
1744 pose_msg[0].header.stamp = impl_->getClock()->now();
1745 return setPoseTargets(pose_msg, end_effector_link);
1746}
1747
1748bool MoveGroupInterface::setPoseTarget(const geometry_msgs::msg::Pose& target, const std::string& end_effector_link)
1749{
1750 std::vector<geometry_msgs::msg::PoseStamped> pose_msg(1);
1751 pose_msg[0].pose = target;
1752 pose_msg[0].header.frame_id = getPoseReferenceFrame();
1753 pose_msg[0].header.stamp = impl_->getClock()->now();
1754 return setPoseTargets(pose_msg, end_effector_link);
1755}
1756
1757bool MoveGroupInterface::setPoseTarget(const geometry_msgs::msg::PoseStamped& target,
1758 const std::string& end_effector_link)
1759{
1760 std::vector<geometry_msgs::msg::PoseStamped> targets(1, target);
1761 return setPoseTargets(targets, end_effector_link);
1762}
1763
1764bool MoveGroupInterface::setPoseTargets(const EigenSTL::vector_Isometry3d& target, const std::string& end_effector_link)
1765{
1766 std::vector<geometry_msgs::msg::PoseStamped> pose_out(target.size());
1767 rclcpp::Time tm = impl_->getClock()->now();
1768 const std::string& frame_id = getPoseReferenceFrame();
1769 for (std::size_t i = 0; i < target.size(); ++i)
1770 {
1771 pose_out[i].pose = tf2::toMsg(target[i]);
1772 pose_out[i].header.stamp = tm;
1773 pose_out[i].header.frame_id = frame_id;
1774 }
1775 return setPoseTargets(pose_out, end_effector_link);
1776}
1777
1778bool MoveGroupInterface::setPoseTargets(const std::vector<geometry_msgs::msg::Pose>& target,
1779 const std::string& end_effector_link)
1780{
1781 std::vector<geometry_msgs::msg::PoseStamped> target_stamped(target.size());
1782 rclcpp::Time tm = impl_->getClock()->now();
1783 const std::string& frame_id = getPoseReferenceFrame();
1784 for (std::size_t i = 0; i < target.size(); ++i)
1785 {
1786 target_stamped[i].pose = target[i];
1787 target_stamped[i].header.stamp = tm;
1788 target_stamped[i].header.frame_id = frame_id;
1789 }
1790 return setPoseTargets(target_stamped, end_effector_link);
1791}
1792
1793bool MoveGroupInterface::setPoseTargets(const std::vector<geometry_msgs::msg::PoseStamped>& target,
1794 const std::string& end_effector_link)
1795{
1796 if (target.empty())
1797 {
1798 RCLCPP_ERROR(logger_, "No pose specified as goal target");
1799 return false;
1800 }
1801 else
1802 {
1803 impl_->setTargetType(POSE);
1804 return impl_->setPoseTargets(target, end_effector_link);
1805 }
1806}
1807
1808const geometry_msgs::msg::PoseStamped& MoveGroupInterface::getPoseTarget(const std::string& end_effector_link) const
1809{
1810 return impl_->getPoseTarget(end_effector_link);
1811}
1812
1813const std::vector<geometry_msgs::msg::PoseStamped>&
1814MoveGroupInterface::getPoseTargets(const std::string& end_effector_link) const
1815{
1816 return impl_->getPoseTargets(end_effector_link);
1817}
1818
1819namespace
1820{
1821inline void transformPose(const tf2_ros::Buffer& tf_buffer, const std::string& desired_frame,
1822 geometry_msgs::msg::PoseStamped& target)
1823{
1824 if (desired_frame != target.header.frame_id)
1825 {
1826 geometry_msgs::msg::PoseStamped target_in(target);
1827 tf_buffer.transform(target_in, target, desired_frame);
1828 // we leave the stamp to ros::Time(0) on purpose
1829 target.header.stamp = rclcpp::Time(0);
1830 }
1831}
1832} // namespace
1833
1834bool MoveGroupInterface::setPositionTarget(double x, double y, double z, const std::string& end_effector_link)
1835{
1836 geometry_msgs::msg::PoseStamped target;
1837 if (impl_->hasPoseTarget(end_effector_link))
1838 {
1839 target = getPoseTarget(end_effector_link);
1840 transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
1841 }
1842 else
1843 {
1844 target.pose.orientation.x = 0.0;
1845 target.pose.orientation.y = 0.0;
1846 target.pose.orientation.z = 0.0;
1847 target.pose.orientation.w = 1.0;
1848 target.header.frame_id = impl_->getPoseReferenceFrame();
1849 }
1850
1851 target.pose.position.x = x;
1852 target.pose.position.y = y;
1853 target.pose.position.z = z;
1854 bool result = setPoseTarget(target, end_effector_link);
1855 impl_->setTargetType(POSITION);
1856 return result;
1857}
1858
1859bool MoveGroupInterface::setRPYTarget(double r, double p, double y, const std::string& end_effector_link)
1860{
1861 geometry_msgs::msg::PoseStamped target;
1862 if (impl_->hasPoseTarget(end_effector_link))
1863 {
1864 target = getPoseTarget(end_effector_link);
1865 transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
1866 }
1867 else
1868 {
1869 target.pose.position.x = 0.0;
1870 target.pose.position.y = 0.0;
1871 target.pose.position.z = 0.0;
1872 target.header.frame_id = impl_->getPoseReferenceFrame();
1873 }
1874 tf2::Quaternion q;
1875 q.setRPY(r, p, y);
1876 target.pose.orientation = tf2::toMsg(q);
1877 bool result = setPoseTarget(target, end_effector_link);
1878 impl_->setTargetType(ORIENTATION);
1879 return result;
1880}
1881
1882bool MoveGroupInterface::setOrientationTarget(double x, double y, double z, double w,
1883 const std::string& end_effector_link)
1884{
1885 geometry_msgs::msg::PoseStamped target;
1886 if (impl_->hasPoseTarget(end_effector_link))
1887 {
1888 target = getPoseTarget(end_effector_link);
1889 transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
1890 }
1891 else
1892 {
1893 target.pose.position.x = 0.0;
1894 target.pose.position.y = 0.0;
1895 target.pose.position.z = 0.0;
1896 target.header.frame_id = impl_->getPoseReferenceFrame();
1897 }
1898
1899 target.pose.orientation.x = x;
1900 target.pose.orientation.y = y;
1901 target.pose.orientation.z = z;
1902 target.pose.orientation.w = w;
1903 bool result = setPoseTarget(target, end_effector_link);
1904 impl_->setTargetType(ORIENTATION);
1905 return result;
1906}
1907
1908void MoveGroupInterface::setPoseReferenceFrame(const std::string& pose_reference_frame)
1909{
1910 impl_->setPoseReferenceFrame(pose_reference_frame);
1911}
1912
1914{
1915 return impl_->getPoseReferenceFrame();
1916}
1917
1919{
1920 return impl_->getGoalJointTolerance();
1921}
1922
1924{
1925 return impl_->getGoalPositionTolerance();
1926}
1927
1932
1934{
1935 setGoalJointTolerance(tolerance);
1936 setGoalPositionTolerance(tolerance);
1937 setGoalOrientationTolerance(tolerance);
1938}
1939
1941{
1942 impl_->setGoalJointTolerance(tolerance);
1943}
1944
1946{
1947 impl_->setGoalPositionTolerance(tolerance);
1948}
1949
1951{
1952 impl_->setGoalOrientationTolerance(tolerance);
1953}
1954
1955void MoveGroupInterface::rememberJointValues(const std::string& name)
1956{
1958}
1959
1961{
1962 return impl_->startStateMonitor(wait);
1963}
1964
1966{
1967 moveit::core::RobotStatePtr current_state;
1968 std::vector<double> values;
1969 if (impl_->getCurrentState(current_state))
1970 current_state->copyJointGroupPositions(getName(), values);
1971 return values;
1972}
1973
1975{
1976 std::vector<double> r;
1978 return r;
1979}
1980
1981geometry_msgs::msg::PoseStamped MoveGroupInterface::getRandomPose(const std::string& end_effector_link) const
1982{
1983 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
1984 Eigen::Isometry3d pose;
1985 pose.setIdentity();
1986 if (eef.empty())
1987 {
1988 RCLCPP_ERROR(logger_, "No end-effector specified");
1989 }
1990 else
1991 {
1992 moveit::core::RobotStatePtr current_state;
1993 if (impl_->getCurrentState(current_state))
1994 {
1995 current_state->setToRandomPositions(impl_->getJointModelGroup());
1996 const moveit::core::LinkModel* lm = current_state->getLinkModel(eef);
1997 if (lm)
1998 pose = current_state->getGlobalLinkTransform(lm);
1999 }
2000 }
2001 geometry_msgs::msg::PoseStamped pose_msg;
2002 pose_msg.header.stamp = impl_->getClock()->now();
2003 pose_msg.header.frame_id = impl_->getRobotModel()->getModelFrame();
2004 pose_msg.pose = tf2::toMsg(pose);
2005 return pose_msg;
2006}
2007
2008geometry_msgs::msg::PoseStamped MoveGroupInterface::getCurrentPose(const std::string& end_effector_link) const
2009{
2010 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
2011 Eigen::Isometry3d pose;
2012 pose.setIdentity();
2013 if (eef.empty())
2014 {
2015 RCLCPP_ERROR(logger_, "No end-effector specified");
2016 }
2017 else
2018 {
2019 moveit::core::RobotStatePtr current_state;
2020 if (impl_->getCurrentState(current_state))
2021 {
2022 const moveit::core::LinkModel* lm = current_state->getLinkModel(eef);
2023 if (lm)
2024 pose = current_state->getGlobalLinkTransform(lm);
2025 }
2026 }
2027 geometry_msgs::msg::PoseStamped pose_msg;
2028 pose_msg.header.stamp = impl_->getClock()->now();
2029 pose_msg.header.frame_id = impl_->getRobotModel()->getModelFrame();
2030 pose_msg.pose = tf2::toMsg(pose);
2031 return pose_msg;
2032}
2033
2034std::vector<double> MoveGroupInterface::getCurrentRPY(const std::string& end_effector_link) const
2035{
2036 std::vector<double> result;
2037 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
2038 if (eef.empty())
2039 {
2040 RCLCPP_ERROR(logger_, "No end-effector specified");
2041 }
2042 else
2043 {
2044 moveit::core::RobotStatePtr current_state;
2045 if (impl_->getCurrentState(current_state))
2046 {
2047 const moveit::core::LinkModel* lm = current_state->getLinkModel(eef);
2048 if (lm)
2049 {
2050 result.resize(3);
2051 geometry_msgs::msg::TransformStamped tfs = tf2::eigenToTransform(current_state->getGlobalLinkTransform(lm));
2052 double pitch, roll, yaw;
2053 tf2::getEulerYPR<geometry_msgs::msg::Quaternion>(tfs.transform.rotation, yaw, pitch, roll);
2054 result[0] = roll;
2055 result[1] = pitch;
2056 result[2] = yaw;
2057 }
2058 }
2059 }
2060 return result;
2061}
2062
2063const std::vector<std::string>& MoveGroupInterface::getActiveJoints() const
2064{
2066}
2067
2068const std::vector<std::string>& MoveGroupInterface::getJoints() const
2069{
2070 return impl_->getJointModelGroup()->getJointModelNames();
2071}
2072
2074{
2075 return impl_->getJointModelGroup()->getVariableCount();
2076}
2077
2078moveit::core::RobotStatePtr MoveGroupInterface::getCurrentState(double wait) const
2079{
2080 moveit::core::RobotStatePtr current_state;
2081 impl_->getCurrentState(current_state, wait);
2082 return current_state;
2083}
2084
2085void MoveGroupInterface::rememberJointValues(const std::string& name, const std::vector<double>& values)
2086{
2087 remembered_joint_values_[name] = values;
2088}
2089
2090void MoveGroupInterface::forgetJointValues(const std::string& name)
2091{
2092 remembered_joint_values_.erase(name);
2093}
2094
2096{
2097 impl_->can_look_ = flag;
2098 RCLCPP_DEBUG(logger_, "Looking around: %s", flag ? "yes" : "no");
2099}
2100
2102{
2103 if (attempts < 0)
2104 {
2105 RCLCPP_ERROR(logger_, "Tried to set negative number of look-around attempts");
2106 }
2107 else
2108 {
2109 RCLCPP_DEBUG_STREAM(logger_, "Look around attempts: " << attempts);
2110 impl_->look_around_attempts_ = attempts;
2111 }
2112}
2113
2115{
2116 impl_->can_replan_ = flag;
2117 RCLCPP_DEBUG(logger_, "Replanning: %s", flag ? "yes" : "no");
2118}
2119
2121{
2122 if (attempts < 0)
2123 {
2124 RCLCPP_ERROR(logger_, "Tried to set negative number of replan attempts");
2125 }
2126 else
2127 {
2128 RCLCPP_DEBUG_STREAM(logger_, "Replan Attempts: " << attempts);
2129 impl_->replan_attempts_ = attempts;
2130 }
2131}
2132
2134{
2135 if (delay < 0.0)
2136 {
2137 RCLCPP_ERROR(logger_, "Tried to set negative replan delay");
2138 }
2139 else
2140 {
2141 RCLCPP_DEBUG_STREAM(logger_, "Replan Delay: " << delay);
2142 impl_->replan_delay_ = delay;
2143 }
2144}
2145
2146std::vector<std::string> MoveGroupInterface::getKnownConstraints() const
2147{
2148 return impl_->getKnownConstraints();
2149}
2150
2151moveit_msgs::msg::Constraints MoveGroupInterface::getPathConstraints() const
2152{
2153 return impl_->getPathConstraints();
2154}
2155
2156bool MoveGroupInterface::setPathConstraints(const std::string& constraint)
2157{
2158 return impl_->setPathConstraints(constraint);
2159}
2160
2161void MoveGroupInterface::setPathConstraints(const moveit_msgs::msg::Constraints& constraint)
2162{
2163 impl_->setPathConstraints(constraint);
2164}
2165
2170
2171moveit_msgs::msg::TrajectoryConstraints MoveGroupInterface::getTrajectoryConstraints() const
2172{
2173 return impl_->getTrajectoryConstraints();
2174}
2175
2176void MoveGroupInterface::setTrajectoryConstraints(const moveit_msgs::msg::TrajectoryConstraints& constraint)
2177{
2178 impl_->setTrajectoryConstraints(constraint);
2179}
2180
2185
2186void MoveGroupInterface::setConstraintsDatabase(const std::string& host, unsigned int port)
2187{
2188 impl_->initializeConstraintsStorage(host, port);
2189}
2190
2191void MoveGroupInterface::setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
2192{
2193 impl_->setWorkspace(minx, miny, minz, maxx, maxy, maxz);
2194}
2195
2198{
2199 impl_->setPlanningTime(seconds);
2200}
2201
2204{
2205 return impl_->getPlanningTime();
2206}
2207
2208const rclcpp::Node::SharedPtr& MoveGroupInterface::getNode() const
2209{
2210 return impl_->node_;
2211}
2212
2214{
2215 return impl_->getRobotModel()->getModelFrame();
2216}
2217
2218const std::vector<std::string>& MoveGroupInterface::getJointModelGroupNames() const
2219{
2220 return impl_->getRobotModel()->getJointModelGroupNames();
2221}
2222
2223bool MoveGroupInterface::attachObject(const std::string& object, const std::string& link)
2224{
2225 return attachObject(object, link, std::vector<std::string>());
2226}
2227
2228bool MoveGroupInterface::attachObject(const std::string& object, const std::string& link,
2229 const std::vector<std::string>& touch_links)
2230{
2231 return impl_->attachObject(object, link, touch_links);
2232}
2233
2234bool MoveGroupInterface::detachObject(const std::string& name)
2235{
2236 return impl_->detachObject(name);
2237}
2238
2239void MoveGroupInterface::constructRobotState(moveit_msgs::msg::RobotState& state)
2240{
2241 impl_->constructRobotState(state);
2242}
2243
2244void MoveGroupInterface::constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest& goal_out)
2245{
2246 impl_->constructMotionPlanRequest(goal_out);
2247}
2248
2249} // namespace planning_interface
2250} // namespace moveit
bool isChain() const
Check if this group is a linear chain.
const std::vector< std::string > & getActiveJointModelNames() const
Get the names of the active joints in this group. These are the names of the joints returned by getJo...
const std::vector< std::string > & getJointModelNames() const
Get the names of the joints in this group. These are the names of the joints returned by getJointMode...
void getVariableRandomPositions(random_numbers::RandomNumberGenerator &rng, double *values) const
Compute random values for the state of the joint group.
const std::pair< std::string, std::string > & getEndEffectorParentGroup() const
Get the name of the group this end-effector attaches to (first) and the name of the link in that grou...
const std::string & getName() const
Get the name of the joint group.
const std::vector< std::string > & getVariableNames() const
Get the names of the variables that make up the joints included in this group. The number of returned...
const JointModel * getJointModel(const std::string &joint) const
Get a joint by its name. Throw an exception if the joint is not part of this group.
bool hasLinkModel(const std::string &link) const
Check if a link is part of this group.
unsigned int getVariableCount() const
Get the number of variables that describe this joint group. This includes variables necessary for mim...
const std::vector< std::string > & getLinkModelNames() const
Get the names of the links that are part of this joint group.
bool getVariableDefaultPositions(const std::string &name, std::map< std::string, double > &values) const
Get the values that correspond to a named state as read from the URDF. Return false on failure.
const std::vector< std::string > & getDefaultStateNames() const
Get the names of the known default states (as specified in the SRDF)
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
std::size_t getVariableCount() const
Get the number of variables that describe this joint.
A link from the robot. Contains the constant transform applied to the link and its geometry.
a wrapper around moveit_msgs::MoveItErrorCodes to make it easier to return an error code message from...
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void setVariablePositions(const double *position)
It is assumed positions is an array containing the new positions for all variables in this state....
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
void copyJointGroupPositions(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the position values of the variables that make up the group into another loca...
const Eigen::Isometry3d & getFrameTransform(const std::string &frame_id, bool *frame_found=nullptr)
Get the transformation matrix from the model frame (root of model) to the frame identified by frame_i...
void setToRandomPositions()
Set all joints to random values. Values will be within default bounds.
bool satisfiesBounds(double margin=0.0) const
void setToDefaultValues()
Set all joints to their default positions. The default position is 0, or if that is not within bounds...
random_numbers::RandomNumberGenerator & getRandomNumberGenerator()
Return the instance of a random number generator.
bool setFromIK(const JointModelGroup *group, const geometry_msgs::msg::Pose &pose, double timeout=0.0, const GroupStateValidityCallbackFn &constraint=GroupStateValidityCallbackFn(), const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions(), const kinematics::KinematicsBase::IKCostFn &cost_function=kinematics::KinematicsBase::IKCostFn())
If the group this state corresponds to is a chain and a solver is available, then the joint values ca...
void setJointPositions(const std::string &joint_name, const double *position)
static bool sameFrame(const std::string &frame1, const std::string &frame2)
Check if two frames end up being the same once the missing / are added as prefix (if they are missing...
rclcpp_action::Client< moveit_msgs::action::MoveGroup > & getMoveGroupClient() const
void constructGoal(moveit_msgs::action::MoveGroup::Goal &goal) const
void setMaxScalingFactor(double &variable, const double target_value, const char *factor_name, double fallback_value)
bool getCurrentState(moveit::core::RobotStatePtr &current_state, double wait_seconds=1.0)
bool attachObject(const std::string &object, const std::string &link, const std::vector< std::string > &touch_links)
std::map< std::string, std::string > getPlannerParams(const std::string &planner_id, const std::string &group="")
void initializeConstraintsStorage(const std::string &host, unsigned int port)
void setPathConstraints(const moveit_msgs::msg::Constraints &constraint)
double computeCartesianPath(const std::vector< geometry_msgs::msg::Pose > &waypoints, double step, moveit_msgs::msg::RobotTrajectory &msg, const moveit_msgs::msg::Constraints &path_constraints, bool avoid_collisions, moveit_msgs::msg::MoveItErrorCodes &error_code)
void setTrajectoryConstraints(const moveit_msgs::msg::TrajectoryConstraints &constraint)
void constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest &request) const
MoveGroupInterfaceImpl(const rclcpp::Node::SharedPtr &node, const Options &opt, const std::shared_ptr< tf2_ros::Buffer > &tf_buffer, const rclcpp::Duration &wait_for_servers)
bool setPoseTargets(const std::vector< geometry_msgs::msg::PoseStamped > &poses, const std::string &end_effector_link)
const geometry_msgs::msg::PoseStamped & getPoseTarget(const std::string &end_effector_link) const
moveit::core::MoveItErrorCode execute(const moveit_msgs::msg::RobotTrajectory &trajectory, bool wait, const std::vector< std::string > &controllers=std::vector< std::string >())
bool getInterfaceDescription(moveit_msgs::msg::PlannerInterfaceDescription &desc)
void setStartState(const moveit_msgs::msg::RobotState &start_state)
const std::vector< geometry_msgs::msg::PoseStamped > & getPoseTargets(const std::string &end_effector_link) const
bool setJointValueTarget(const geometry_msgs::msg::Pose &eef_pose, const std::string &end_effector_link, const std::string &frame, bool approx)
void setPlannerParams(const std::string &planner_id, const std::string &group, const std::map< std::string, std::string > &params, bool replace=false)
bool getInterfaceDescriptions(std::vector< moveit_msgs::msg::PlannerInterfaceDescription > &desc)
void setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
Client class to conveniently use the ROS interfaces provided by the move_group node.
std::vector< double > getRandomJointValues() const
Get random joint values for the joints planned for by this instance (see getJoints())
double computeCartesianPath(const std::vector< geometry_msgs::msg::Pose > &waypoints, double eef_step, double, moveit_msgs::msg::RobotTrajectory &trajectory, bool avoid_collisions=true, moveit_msgs::msg::MoveItErrorCodes *error_code=nullptr)
Compute a Cartesian path that follows specified waypoints with a step size of at most eef_step meters...
void setMaxVelocityScalingFactor(double max_velocity_scaling_factor)
Set a scaling factor for optionally reducing the maximum joint velocity. Allowed values are in (0,...
const std::string & getEndEffectorLink() const
Get the current end-effector link. This returns the value set by setEndEffectorLink() (or indirectly ...
static const std::string ROBOT_DESCRIPTION
Default ROS parameter name from where to read the robot's URDF. Set to 'robot_description'.
const std::vector< std::string > & getNamedTargets() const
Get the names of the named robot states available as targets, both either remembered states or defaul...
std::map< std::string, std::string > getPlannerParams(const std::string &planner_id, const std::string &group="") const
Get the planner parameters for given group and planner_id.
void stop()
Stop any trajectory execution, if one is active.
MoveGroupInterface(const rclcpp::Node::SharedPtr &node, const Options &opt, const std::shared_ptr< tf2_ros::Buffer > &tf_buffer=std::shared_ptr< tf2_ros::Buffer >(), const rclcpp::Duration &wait_for_servers=rclcpp::Duration::from_seconds(-1))
Construct a MoveGroupInterface instance call using a specified set of options opt.
const std::string & getPlannerId() const
Get the current planner_id.
void setReplanDelay(double delay)
Sleep this duration between replanning attempts (in walltime seconds)
MoveGroupInterface & operator=(const MoveGroupInterface &)=delete
moveit::core::MoveItErrorCode plan(Plan &plan)
Compute a motion plan that takes the group declared in the constructor from the current state to the ...
void setGoalTolerance(double tolerance)
Set the tolerance that is used for reaching the goal. For joint state goals, this will be distance fo...
void setGoalPositionTolerance(double tolerance)
Set the position tolerance that is used for reaching the goal when moving to a pose.
const std::string & getPlanningFrame() const
Get the name of the frame in which the robot is planning.
bool setPoseTargets(const EigenSTL::vector_Isometry3d &end_effector_pose, const std::string &end_effector_link="")
Set goal poses for end_effector_link.
bool setPoseTarget(const Eigen::Isometry3d &end_effector_pose, const std::string &end_effector_link="")
Set the goal pose of the end-effector end_effector_link.
moveit::core::MoveItErrorCode asyncMove()
Plan and execute a trajectory that takes the group of joints declared in the constructor to the speci...
void setPlanningPipelineId(const std::string &pipeline_id)
Specify a planning pipeline to be used for further planning.
double getGoalJointTolerance() const
Get the tolerance that is used for reaching a joint goal. This is distance for each joint in configur...
bool setEndEffectorLink(const std::string &end_effector_link)
Specify the parent link of the end-effector. This end_effector_link will be used in calls to pose tar...
void setStartStateToCurrentState()
Set the starting state for planning to be that reported by the robot's joint state publication.
bool getInterfaceDescriptions(std::vector< moveit_msgs::msg::PlannerInterfaceDescription > &desc) const
Get the descriptions of all planning plugins loaded by the action server.
void setMaxAccelerationScalingFactor(double max_acceleration_scaling_factor)
Set a scaling factor for optionally reducing the maximum joint acceleration. Allowed values are in (0...
bool setPositionTarget(double x, double y, double z, const std::string &end_effector_link="")
Set the goal position of the end-effector end_effector_link to be (x, y, z).
const std::string & getEndEffector() const
Get the current end-effector name. This returns the value set by setEndEffector() (or indirectly by s...
void clearPathConstraints()
Specify that no path constraints are to be used. This removes any path constraints set in previous ca...
bool attachObject(const std::string &object, const std::string &link="")
Given the name of an object in the planning scene, make the object attached to a link of the robot....
moveit_msgs::msg::Constraints getPathConstraints() const
Get the actual set of constraints in use with this MoveGroupInterface.
void setNumPlanningAttempts(unsigned int num_planning_attempts)
Set the number of times the motion plan is to be computed from scratch before the shortest solution i...
rclcpp_action::Client< moveit_msgs::action::MoveGroup > & getMoveGroupClient() const
Get the move_group action client used by the MoveGroupInterface. The client can be used for querying ...
std::vector< double > getCurrentJointValues() const
Get the current joint values for the joints planned for by this instance (see getJoints())
bool setNamedTarget(const std::string &name)
Set the current joint values to be ones previously remembered by rememberJointValues() or,...
const std::vector< std::string > & getJointNames() const
Get vector of names of joints available in move group.
moveit::core::MoveItErrorCode move()
Plan and execute a trajectory that takes the group of joints declared in the constructor to the speci...
void setReplanAttempts(int32_t attempts)
Maximum number of replanning attempts.
void allowReplanning(bool flag)
Specify whether the robot is allowed to replan if it detects changes in the environment.
moveit::core::RobotModelConstPtr getRobotModel() const
Get the RobotModel object.
moveit::core::MoveItErrorCode execute(const Plan &plan, const std::vector< std::string > &controllers=std::vector< std::string >())
Given a plan, execute it while waiting for completion.
void constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest &request)
Build the MotionPlanRequest that would be sent to the move_group action with plan() or move() and sto...
bool setOrientationTarget(double x, double y, double z, double w, const std::string &end_effector_link="")
Set the goal orientation of the end-effector end_effector_link to be the quaternion (x,...
bool setJointValueTarget(const std::vector< double > &group_variable_values)
Set the JointValueTarget and use it for future planning requests.
const rclcpp::Node::SharedPtr & getNode() const
Get the ROS node handle of this instance operates on.
bool setRPYTarget(double roll, double pitch, double yaw, const std::string &end_effector_link="")
Set the goal orientation of the end-effector end_effector_link to be (roll,pitch,yaw) radians.
void setGoalOrientationTolerance(double tolerance)
Set the orientation tolerance that is used for reaching the goal when moving to a pose.
void clearPoseTarget(const std::string &end_effector_link="")
Forget pose(s) specified for end_effector_link.
const geometry_msgs::msg::PoseStamped & getPoseTarget(const std::string &end_effector_link="") const
void setGoalJointTolerance(double tolerance)
Set the joint tolerance (for each joint) that is used for reaching the goal when moving to a joint va...
std::string getDefaultPlannerId(const std::string &group="") const
Get the default planner of the current planning pipeline for the given group (or the pipeline's defau...
void setRandomTarget()
Set the joint state goal to a random joint configuration.
moveit::core::RobotStatePtr getCurrentState(double wait=1) const
Get the current state of the robot within the duration specified by wait.
void getJointValueTarget(std::vector< double > &group_variable_values) const
Get the current joint state goal in a form compatible to setJointValueTarget()
const std::vector< std::string > & getActiveJoints() const
Get only the active (actuated) joints this instance operates on.
void rememberJointValues(const std::string &name)
Remember the current joint values (of the robot being monitored) under name. These can be used by set...
void setLookAroundAttempts(int32_t attempts)
How often is the system allowed to move the camera to update environment model when looking.
bool getInterfaceDescription(moveit_msgs::msg::PlannerInterfaceDescription &desc) const
Get the description of the default planning plugin loaded by the action server.
const std::string & getName() const
Get the name of the group this instance operates on.
moveit::core::MoveItErrorCode asyncExecute(const Plan &plan, const std::vector< std::string > &controllers=std::vector< std::string >())
Given a plan, execute it without waiting for completion.
const std::vector< std::string > & getJoints() const
Get all the joints this instance operates on (including fixed joints)
bool detachObject(const std::string &name="")
Detach an object. name specifies the name of the object attached to this group, or the name of the li...
void setPoseReferenceFrame(const std::string &pose_reference_frame)
Specify which reference frame to assume for poses specified without a reference frame.
const std::shared_ptr< tf2_ros::Buffer > & getTF() const
Get the tf2_ros::Buffer.
const std::vector< geometry_msgs::msg::PoseStamped > & getPoseTargets(const std::string &end_effector_link="") const
double getMaxVelocityScalingFactor() const
Get the max velocity scaling factor set by setMaxVelocityScalingFactor().
moveit_msgs::msg::TrajectoryConstraints getTrajectoryConstraints() const
const std::vector< std::string > & getLinkNames() const
Get vector of names of links available in move group.
double getMaxAccelerationScalingFactor() const
Get the max acceleration scaling factor set by setMaxAccelerationScalingFactor().
void setStartState(const moveit_msgs::msg::RobotState &start_state)
If a different start state should be considered instead of the current state of the robot,...
bool setPathConstraints(const std::string &constraint)
Specify a set of path constraints to use. The constraints are looked up by name from the Mongo databa...
void clearPoseTargets()
Forget any poses specified for all end-effectors.
void setPlannerId(const std::string &planner_id)
Specify a planner to be used for further planning.
bool setEndEffector(const std::string &eef_name)
Specify the name of the end-effector to use. This is equivalent to setting the EndEffectorLink to the...
const std::string & getPoseReferenceFrame() const
Get the reference frame set by setPoseReferenceFrame(). By default this is the reference frame of the...
const std::string & getPlanningPipelineId() const
Get the current planning_pipeline_id.
void setConstraintsDatabase(const std::string &host, unsigned int port)
Specify where the database server that holds known constraints resides.
std::vector< double > getCurrentRPY(const std::string &end_effector_link="") const
Get the roll-pitch-yaw (XYZ) for the end-effector end_effector_link. If end_effector_link is empty (t...
void forgetJointValues(const std::string &name)
Forget the joint values remembered under name.
std::vector< std::string > getKnownConstraints() const
Get the names of the known constraints as read from the Mongo database, if a connection was achieved.
void setTrajectoryConstraints(const moveit_msgs::msg::TrajectoryConstraints &constraint)
const moveit::core::RobotState & getTargetRobotState() const
geometry_msgs::msg::PoseStamped getRandomPose(const std::string &end_effector_link="") const
Get a random reachable pose for the end-effector end_effector_link. If end_effector_link is empty (th...
double getGoalOrientationTolerance() const
Get the tolerance that is used for reaching an orientation goal. This is the tolerance for roll,...
void allowLooking(bool flag)
Specify whether the robot is allowed to look around before moving if it determines it should (default...
std::map< std::string, double > getNamedTargetValues(const std::string &name) const
Get the joint angles for targets specified by name.
geometry_msgs::msg::PoseStamped getCurrentPose(const std::string &end_effector_link="") const
Get the pose for the end-effector end_effector_link. If end_effector_link is empty (the default value...
bool startStateMonitor(double wait=1.0)
When reasoning about the current state of a robot, a CurrentStateMonitor instance is automatically co...
unsigned int getVariableCount() const
Get the number of variables used to describe the state of this group. This is larger or equal to the ...
double getGoalPositionTolerance() const
Get the tolerance that is used for reaching a position goal. This is be the radius of a sphere where ...
double getPlanningTime() const
Get the number of seconds set by setPlanningTime()
void setPlanningTime(double seconds)
Specify the maximum amount of time to use when planning.
bool setApproximateJointValueTarget(const geometry_msgs::msg::Pose &eef_pose, const std::string &end_effector_link="")
Set the joint state goal for a particular joint by computing IK.
void constructRobotState(moveit_msgs::msg::RobotState &state)
Build a RobotState message for use with plan() or computeCartesianPath() If the move_group has a cust...
void setPlannerParams(const std::string &planner_id, const std::string &group, const std::map< std::string, std::string > &params, bool bReplace=false)
Set the planner parameters for given group and planner_id.
void setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
Specify the workspace bounding box. The box is specified in the planning frame (i....
const std::vector< std::string > & getJointModelGroupNames() const
Get the available planning group names.
static const std::string DEFAULT_ATTACHED_COLLISION_OBJECT_TOPIC
The name of the topic used by default for attached collision objects.
moveit_msgs::msg::Constraints constructGoalConstraints(const moveit::core::RobotState &state, const moveit::core::JointModelGroup *jmg, double tolerance_below, double tolerance_above)
Generates a constraint message intended to be used as a goal constraint for a joint group....
Definition utils.cpp:152
moveit_msgs::msg::Constraints mergeConstraints(const moveit_msgs::msg::Constraints &first, const moveit_msgs::msg::Constraints &second)
Merge two sets of constraints into one.
Definition utils.cpp:64
void robotStateToRobotStateMsg(const RobotState &state, moveit_msgs::msg::RobotState &robot_state, bool copy_attached_bodies=true)
Convert a MoveIt robot state to a robot state message.
std::function< bool(RobotState *robot_state, const JointModelGroup *joint_group, const double *joint_group_variable_values)> GroupStateValidityCallbackFn
Signature for functions that can verify that if the group joint_group in robot_state is set to joint_...
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::msg::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
Convert a robot state msg (with accompanying extra transforms) to a MoveIt robot state.
moveit::core::RobotModelConstPtr getSharedRobotModel(const rclcpp::Node::SharedPtr &node, const std::string &robot_description)
std::shared_ptr< tf2_ros::Buffer > getSharedTF()
planning_scene_monitor::CurrentStateMonitorPtr getSharedStateMonitor(const rclcpp::Node::SharedPtr &node, const moveit::core::RobotModelConstPtr &robot_model, const std::shared_ptr< tf2_ros::Buffer > &tf_buffer)
getSharedStateMonitor
const std::string GRASP_PLANNING_SERVICE_NAME
warehouse_ros::DatabaseConnection::Ptr loadDatabase(const rclcpp::Node::SharedPtr &node)
Load a database connection.
warehouse_ros::MessageWithMetadata< moveit_msgs::msg::Constraints >::ConstPtr ConstraintsWithMetadata
Main namespace for MoveIt.
This namespace includes the base class for MoveIt planners.
std::string append(const std::string &left, const std::string &right)
A set of options for the kinematics solver.
Specification of options to use when constructing the MoveGroupInterface class.
std::string move_group_namespace
The namespace for the move group node.
std::string robot_description
The robot description parameter name (if different from default)
moveit::core::RobotModelConstPtr robot_model
Optionally, an instance of the RobotModel to use can be also specified.
std::string group_name
The group to construct the class instance for.
The representation of a motion plan (as ROS messages)