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#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
53#include <moveit_msgs/action/execute_trajectory.hpp>
54#include <moveit_msgs/srv/query_planner_interfaces.hpp>
55#include <moveit_msgs/srv/get_cartesian_path.hpp>
56#include <moveit_msgs/srv/grasp_planning.hpp>
57#include <moveit_msgs/srv/get_planner_params.hpp>
58#include <moveit_msgs/srv/set_planner_params.hpp>
61
62#include <std_msgs/msg/string.hpp>
63#include <geometry_msgs/msg/transform_stamped.hpp>
64#include <tf2/utils.h>
65#include <tf2_eigen/tf2_eigen.hpp>
66#include <tf2_ros/transform_listener.h>
67#include <rclcpp/rclcpp.hpp>
68#include <rclcpp/version.h>
69
70namespace moveit
71{
72namespace planning_interface
73{
75 "robot_description"; // name of the robot description (a param name, so it can be changed externally)
76
77const std::string GRASP_PLANNING_SERVICE_NAME = "plan_grasps"; // name of the service that can be used to plan grasps
78
79namespace
80{
81enum ActiveTargetType
82{
83 JOINT,
84 POSE,
85 POSITION,
86 ORIENTATION
87};
88
89// Function to support both Rolling and Humble on the main branch
90// Rolling has deprecated the version of the create_client method that takes
91// rmw_qos_profile_services_default for the QoS argument
92#if RCLCPP_VERSION_GTE(17, 0, 0) // Rolling
93auto qosDefault()
94{
95 return rclcpp::SystemDefaultsQoS();
96}
97#else // Humble
98auto qosDefault()
99{
100 return rmw_qos_profile_services_default;
101}
102#endif
103
104} // namespace
105
107{
108 friend MoveGroupInterface;
109
110public:
111 MoveGroupInterfaceImpl(const rclcpp::Node::SharedPtr& node, const Options& opt,
112 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer, const rclcpp::Duration& wait_for_servers)
113 : opt_(opt), node_(node), logger_(moveit::getLogger("moveit.ros.move_group_interface")), tf_buffer_(tf_buffer)
114 {
115 // We have no control on how the passed node is getting executed. To make sure MGI is functional, we're creating
116 // our own callback group which is managed in a separate callback thread
117 callback_group_ = node_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive,
118 false /* don't spin with node executor */);
119 callback_executor_.add_callback_group(callback_group_, node->get_node_base_interface());
120 callback_thread_ = std::thread([this]() { callback_executor_.spin(); });
121
122 robot_model_ = opt.robot_model ? opt.robot_model : getSharedRobotModel(node_, opt.robot_description);
123 if (!getRobotModel())
124 {
125 std::string error = "Unable to construct robot model. Please make sure all needed information is on the "
126 "parameter server.";
127 RCLCPP_FATAL_STREAM(logger_, error);
128 throw std::runtime_error(error);
129 }
130
131 if (!getRobotModel()->hasJointModelGroup(opt.group_name))
132 {
133 std::string error = "Group '" + opt.group_name + "' was not found.";
134 RCLCPP_FATAL_STREAM(logger_, error);
135 throw std::runtime_error(error);
136 }
137
139 joint_model_group_ = getRobotModel()->getJointModelGroup(opt.group_name);
140
141 joint_state_target_ = std::make_shared<moveit::core::RobotState>(getRobotModel());
142 joint_state_target_->setToDefaultValues();
143 active_target_ = JOINT;
144 can_look_ = false;
145 look_around_attempts_ = 0;
146 can_replan_ = false;
147 replan_delay_ = 2.0;
148 replan_attempts_ = 1;
149 goal_joint_tolerance_ = 1e-4;
150 goal_position_tolerance_ = 1e-4; // 0.1 mm
151 goal_orientation_tolerance_ = 1e-3; // ~0.1 deg
152 allowed_planning_time_ = 5.0;
153 num_planning_attempts_ = 1;
154 node_->get_parameter_or<double>("robot_description_planning.default_velocity_scaling_factor",
155 max_velocity_scaling_factor_, 0.1);
156 node_->get_parameter_or<double>("robot_description_planning.default_acceleration_scaling_factor",
157 max_acceleration_scaling_factor_, 0.1);
158 initializing_constraints_ = false;
159
160 if (joint_model_group_->isChain())
161 end_effector_link_ = joint_model_group_->getLinkModelNames().back();
162 pose_reference_frame_ = getRobotModel()->getModelFrame();
163 // Append the slash between two topic components
164 trajectory_event_publisher_ = node_->create_publisher<std_msgs::msg::String>(
167 1);
168 attached_object_publisher_ = node_->create_publisher<moveit_msgs::msg::AttachedCollisionObject>(
171 1);
172
173 current_state_monitor_ = getSharedStateMonitor(node_, robot_model_, tf_buffer_);
174
175 move_action_client_ = rclcpp_action::create_client<moveit_msgs::action::MoveGroup>(
176 node_, rclcpp::names::append(opt_.move_group_namespace, move_group::MOVE_ACTION), callback_group_);
177 move_action_client_->wait_for_action_server(wait_for_servers.to_chrono<std::chrono::duration<double>>());
178 execute_action_client_ = rclcpp_action::create_client<moveit_msgs::action::ExecuteTrajectory>(
179 node_, rclcpp::names::append(opt_.move_group_namespace, move_group::EXECUTE_ACTION_NAME), callback_group_);
180 execute_action_client_->wait_for_action_server(wait_for_servers.to_chrono<std::chrono::duration<double>>());
181
182 query_service_ = node_->create_client<moveit_msgs::srv::QueryPlannerInterfaces>(
183 rclcpp::names::append(opt_.move_group_namespace, move_group::QUERY_PLANNERS_SERVICE_NAME), qosDefault(),
184 callback_group_);
185 get_params_service_ = node_->create_client<moveit_msgs::srv::GetPlannerParams>(
186 rclcpp::names::append(opt_.move_group_namespace, move_group::GET_PLANNER_PARAMS_SERVICE_NAME), qosDefault(),
187 callback_group_);
188 set_params_service_ = node_->create_client<moveit_msgs::srv::SetPlannerParams>(
189 rclcpp::names::append(opt_.move_group_namespace, move_group::SET_PLANNER_PARAMS_SERVICE_NAME), qosDefault(),
190 callback_group_);
191 cartesian_path_service_ = node_->create_client<moveit_msgs::srv::GetCartesianPath>(
192 rclcpp::names::append(opt_.move_group_namespace, move_group::CARTESIAN_PATH_SERVICE_NAME), qosDefault(),
193 callback_group_);
194
195 RCLCPP_INFO_STREAM(logger_, "Ready to take commands for planning group " << opt.group_name << '.');
196 }
197
199 {
200 if (constraints_init_thread_)
201 constraints_init_thread_->join();
202
203 callback_executor_.cancel();
204
205 if (callback_thread_.joinable())
206 callback_thread_.join();
207 }
208
209 const std::shared_ptr<tf2_ros::Buffer>& getTF() const
210 {
211 return tf_buffer_;
212 }
213
214 const Options& getOptions() const
215 {
216 return opt_;
217 }
218
219 const moveit::core::RobotModelConstPtr& getRobotModel() const
220 {
221 return robot_model_;
222 }
223
225 {
226 return joint_model_group_;
227 }
228
229 rclcpp_action::Client<moveit_msgs::action::MoveGroup>& getMoveGroupClient() const
230 {
231 return *move_action_client_;
232 }
233
234 bool getInterfaceDescription(moveit_msgs::msg::PlannerInterfaceDescription& desc)
235 {
236 auto req = std::make_shared<moveit_msgs::srv::QueryPlannerInterfaces::Request>();
237 auto future_response = query_service_->async_send_request(req);
238
239 if (future_response.valid())
240 {
241 const auto& response = future_response.get();
242 if (!response->planner_interfaces.empty())
243 {
244 desc = response->planner_interfaces.front();
245 return true;
246 }
247 }
248 return false;
249 }
250
251 bool getInterfaceDescriptions(std::vector<moveit_msgs::msg::PlannerInterfaceDescription>& desc)
252 {
253 auto req = std::make_shared<moveit_msgs::srv::QueryPlannerInterfaces::Request>();
254 auto future_response = query_service_->async_send_request(req);
255 if (future_response.valid())
256 {
257 const auto& response = future_response.get();
258 if (!response->planner_interfaces.empty())
259 {
260 desc = response->planner_interfaces;
261 return true;
262 }
263 }
264 return false;
265 }
266
267 std::map<std::string, std::string> getPlannerParams(const std::string& planner_id, const std::string& group = "")
268 {
269 auto req = std::make_shared<moveit_msgs::srv::GetPlannerParams::Request>();
270 moveit_msgs::srv::GetPlannerParams::Response::SharedPtr response;
271 req->planner_config = planner_id;
272 req->group = group;
273 std::map<std::string, std::string> result;
274
275 auto future_response = get_params_service_->async_send_request(req);
276 if (future_response.valid())
277 {
278 response = future_response.get();
279 for (unsigned int i = 0, end = response->params.keys.size(); i < end; ++i)
280 result[response->params.keys[i]] = response->params.values[i];
281 }
282 return result;
283 }
284
285 void setPlannerParams(const std::string& planner_id, const std::string& group,
286 const std::map<std::string, std::string>& params, bool replace = false)
287 {
288 auto req = std::make_shared<moveit_msgs::srv::SetPlannerParams::Request>();
289 req->planner_config = planner_id;
290 req->group = group;
291 req->replace = replace;
292 for (const std::pair<const std::string, std::string>& param : params)
293 {
294 req->params.keys.push_back(param.first);
295 req->params.values.push_back(param.second);
296 }
297 set_params_service_->async_send_request(req);
298 }
299
301 {
302 std::string default_planning_pipeline;
303 node_->get_parameter("move_group.default_planning_pipeline", default_planning_pipeline);
304 return default_planning_pipeline;
305 }
306
307 void setPlanningPipelineId(const std::string& pipeline_id)
308 {
309 if (pipeline_id != planning_pipeline_id_)
310 {
311 planning_pipeline_id_ = pipeline_id;
312
313 // Reset planner_id if planning pipeline changed
314 planner_id_ = "";
315 }
316 }
317
318 const std::string& getPlanningPipelineId() const
319 {
320 return planning_pipeline_id_;
321 }
322
323 std::string getDefaultPlannerId(const std::string& group) const
324 {
325 // Check what planning pipeline config should be used
326 std::string pipeline_id = getDefaultPlanningPipelineId();
327 if (!planning_pipeline_id_.empty())
328 pipeline_id = planning_pipeline_id_;
329
330 std::stringstream param_name;
331 param_name << "move_group";
332 if (!pipeline_id.empty())
333 param_name << "/planning_pipelines/" << pipeline_id;
334 if (!group.empty())
335 param_name << '.' << group;
336 param_name << ".default_planner_config";
337
338 std::string default_planner_config;
339 node_->get_parameter(param_name.str(), default_planner_config);
340 return default_planner_config;
341 }
342
343 void setPlannerId(const std::string& planner_id)
344 {
345 planner_id_ = planner_id;
346 }
347
348 const std::string& getPlannerId() const
349 {
350 return planner_id_;
351 }
352
353 void setNumPlanningAttempts(unsigned int num_planning_attempts)
354 {
355 num_planning_attempts_ = num_planning_attempts;
356 }
357
359 {
360 setMaxScalingFactor(max_velocity_scaling_factor_, value, "velocity_scaling_factor", 0.1);
361 }
362
364 {
365 return max_velocity_scaling_factor_;
366 }
367
369 {
370 setMaxScalingFactor(max_acceleration_scaling_factor_, value, "acceleration_scaling_factor", 0.1);
371 }
372
374 {
375 return max_acceleration_scaling_factor_;
376 }
377
378 void setMaxScalingFactor(double& variable, const double target_value, const char* factor_name, double fallback_value)
379 {
380 if (target_value > 1.0)
381 {
382 RCLCPP_WARN(logger_, "Limiting max_%s (%.2f) to 1.0.", factor_name, target_value);
383 variable = 1.0;
384 }
385 else if (target_value <= 0.0)
386 {
387 node_->get_parameter_or<double>(std::string("robot_description_planning.default_") + factor_name, variable,
388 fallback_value);
389 if (target_value < 0.0)
390 {
391 RCLCPP_WARN(logger_, "max_%s < 0.0! Setting to default: %.2f.", factor_name, variable);
392 }
393 }
394 else
395 {
396 variable = target_value;
397 }
398 }
399
401 {
402 return *joint_state_target_;
403 }
404
406 {
407 return *joint_state_target_;
408 }
409
410 void setStartState(const moveit_msgs::msg::RobotState& start_state)
411 {
412 considered_start_state_ = start_state;
413 }
414
416 {
417 considered_start_state_ = moveit_msgs::msg::RobotState();
418 moveit::core::robotStateToRobotStateMsg(start_state, considered_start_state_, true);
419 }
420
422 {
423 // set message to empty diff
424 considered_start_state_ = moveit_msgs::msg::RobotState();
425 considered_start_state_.is_diff = true;
426 }
427
428 moveit::core::RobotStatePtr getStartState()
429 {
430 moveit::core::RobotStatePtr s;
432 moveit::core::robotStateMsgToRobotState(considered_start_state_, *s, true);
433 return s;
434 }
435
436 bool setJointValueTarget(const geometry_msgs::msg::Pose& eef_pose, const std::string& end_effector_link,
437 const std::string& frame, bool approx)
438 {
439 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
440 // this only works if we have an end-effector
441 if (!eef.empty())
442 {
443 // first we set the goal to be the same as the start state
444 moveit::core::RobotStatePtr c = getStartState();
445 if (c)
446 {
447 setTargetType(JOINT);
448 c->enforceBounds();
449 getTargetRobotState() = *c;
450 if (!getTargetRobotState().satisfiesBounds(getGoalJointTolerance()))
451 return false;
452 }
453 else
454 return false;
455
456 // we may need to do approximate IK
459
460 // if no frame transforms are needed, call IK directly
461 if (frame.empty() || moveit::core::Transforms::sameFrame(frame, getRobotModel()->getModelFrame()))
462 {
463 return getTargetRobotState().setFromIK(getJointModelGroup(), eef_pose, eef, 0.0,
465 }
466 else
467 {
468 // transform the pose into the model frame, then do IK
469 bool frame_found;
470 const Eigen::Isometry3d& t = getTargetRobotState().getFrameTransform(frame, &frame_found);
471 if (frame_found)
472 {
473 Eigen::Isometry3d p;
474 tf2::fromMsg(eef_pose, p);
475 return getTargetRobotState().setFromIK(getJointModelGroup(), t * p, eef, 0.0,
477 }
478 else
479 {
480 RCLCPP_ERROR(logger_, "Unable to transform from frame '%s' to frame '%s'", frame.c_str(),
481 getRobotModel()->getModelFrame().c_str());
482 return false;
483 }
484 }
485 }
486 else
487 return false;
488 }
489
490 void setEndEffectorLink(const std::string& end_effector)
491 {
492 end_effector_link_ = end_effector;
493 }
494
495 void clearPoseTarget(const std::string& end_effector_link)
496 {
497 pose_targets_.erase(end_effector_link);
498 }
499
501 {
502 pose_targets_.clear();
503 }
504
505 const std::string& getEndEffectorLink() const
506 {
507 return end_effector_link_;
508 }
509
510 const std::string& getEndEffector() const
511 {
512 if (!end_effector_link_.empty())
513 {
514 const std::vector<std::string>& possible_eefs =
515 getRobotModel()->getJointModelGroup(opt_.group_name)->getAttachedEndEffectorNames();
516 for (const std::string& possible_eef : possible_eefs)
517 {
518 if (getRobotModel()->getEndEffector(possible_eef)->hasLinkModel(end_effector_link_))
519 return possible_eef;
520 }
521 }
522 static std::string empty;
523 return empty;
524 }
525
526 bool setPoseTargets(const std::vector<geometry_msgs::msg::PoseStamped>& poses, const std::string& end_effector_link)
527 {
528 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
529 if (eef.empty())
530 {
531 RCLCPP_ERROR(logger_, "No end-effector to set the pose for");
532 return false;
533 }
534 else
535 {
536 pose_targets_[eef] = poses;
537 // make sure we don't store an actual stamp, since that will become stale can potentially cause tf errors
538 std::vector<geometry_msgs::msg::PoseStamped>& stored_poses = pose_targets_[eef];
539 for (geometry_msgs::msg::PoseStamped& stored_pose : stored_poses)
540 stored_pose.header.stamp = rclcpp::Time(0);
541 }
542 return true;
543 }
544
545 bool hasPoseTarget(const std::string& end_effector_link) const
546 {
547 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
548 return pose_targets_.find(eef) != pose_targets_.end();
549 }
550
551 const geometry_msgs::msg::PoseStamped& getPoseTarget(const std::string& end_effector_link) const
552 {
553 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
554
555 // if multiple pose targets are set, return the first one
556 std::map<std::string, std::vector<geometry_msgs::msg::PoseStamped>>::const_iterator jt = pose_targets_.find(eef);
557 if (jt != pose_targets_.end())
558 {
559 if (!jt->second.empty())
560 return jt->second.at(0);
561 }
562
563 // or return an error
564 static const geometry_msgs::msg::PoseStamped UNKNOWN;
565 RCLCPP_ERROR(logger_, "Pose for end-effector '%s' not known.", eef.c_str());
566 return UNKNOWN;
567 }
568
569 const std::vector<geometry_msgs::msg::PoseStamped>& getPoseTargets(const std::string& end_effector_link) const
570 {
571 const std::string& eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
572
573 std::map<std::string, std::vector<geometry_msgs::msg::PoseStamped>>::const_iterator jt = pose_targets_.find(eef);
574 if (jt != pose_targets_.end())
575 {
576 if (!jt->second.empty())
577 return jt->second;
578 }
579
580 // or return an error
581 static const std::vector<geometry_msgs::msg::PoseStamped> EMPTY;
582 RCLCPP_ERROR(logger_, "Poses for end-effector '%s' are not known.", eef.c_str());
583 return EMPTY;
584 }
585
586 void setPoseReferenceFrame(const std::string& pose_reference_frame)
587 {
588 pose_reference_frame_ = pose_reference_frame;
589 }
590
591 const std::string& getPoseReferenceFrame() const
592 {
593 return pose_reference_frame_;
594 }
595
596 void setTargetType(ActiveTargetType type)
597 {
598 active_target_ = type;
599 }
600
601 ActiveTargetType getTargetType() const
602 {
603 return active_target_;
604 }
605
606 bool startStateMonitor(double wait)
607 {
608 if (!current_state_monitor_)
609 {
610 RCLCPP_ERROR(logger_, "Unable to monitor current robot state");
611 return false;
612 }
613
614 // if needed, start the monitor and wait up to 1 second for a full robot state
615 if (!current_state_monitor_->isActive())
616 current_state_monitor_->startStateMonitor();
617
618 current_state_monitor_->waitForCompleteState(opt_.group_name, wait);
619 return true;
620 }
621
622 bool getCurrentState(moveit::core::RobotStatePtr& current_state, double wait_seconds = 1.0)
623 {
624 if (!current_state_monitor_)
625 {
626 RCLCPP_ERROR(logger_, "Unable to get current robot state");
627 return false;
628 }
629
630 // if needed, start the monitor and wait up to 1 second for a full robot state
631 if (!current_state_monitor_->isActive())
632 current_state_monitor_->startStateMonitor();
633
634 if (!current_state_monitor_->waitForCurrentState(node_->now(), wait_seconds))
635 {
636 RCLCPP_ERROR(logger_, "Failed to fetch current robot state");
637 return false;
638 }
639
640 current_state = current_state_monitor_->getCurrentState();
641 return true;
642 }
643
645 {
646 if (!move_action_client_ || !move_action_client_->action_server_is_ready())
647 {
648 RCLCPP_INFO_STREAM(logger_, "MoveGroup action client/server not ready");
649 return moveit::core::MoveItErrorCode::FAILURE;
650 }
651 RCLCPP_INFO_STREAM(logger_, "MoveGroup action client/server ready");
652
653 moveit_msgs::action::MoveGroup::Goal goal;
654 constructGoal(goal);
655 goal.planning_options.plan_only = true;
656 goal.planning_options.look_around = false;
657 goal.planning_options.replan = false;
658 goal.planning_options.planning_scene_diff.is_diff = true;
659 goal.planning_options.planning_scene_diff.robot_state.is_diff = true;
660
661 bool done = false;
662 rclcpp_action::ResultCode code = rclcpp_action::ResultCode::UNKNOWN;
663 std::shared_ptr<moveit_msgs::action::MoveGroup::Result> res;
664 auto send_goal_opts = rclcpp_action::Client<moveit_msgs::action::MoveGroup>::SendGoalOptions();
665
666 send_goal_opts.goal_response_callback =
667 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::SharedPtr& goal_handle) {
668 if (!goal_handle)
669 {
670 done = true;
671 RCLCPP_INFO(logger_, "Planning request rejected");
672 }
673 else
674 RCLCPP_INFO(logger_, "Planning request accepted");
675 };
676 send_goal_opts.result_callback =
677 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::WrappedResult& result) {
678 res = result.result;
679 code = result.code;
680 done = true;
681
682 switch (result.code)
683 {
684 case rclcpp_action::ResultCode::SUCCEEDED:
685 RCLCPP_INFO(logger_, "Planning request complete!");
686 break;
687 case rclcpp_action::ResultCode::ABORTED:
688 RCLCPP_INFO(logger_, "Planning request aborted");
689 return;
690 case rclcpp_action::ResultCode::CANCELED:
691 RCLCPP_INFO(logger_, "Planning request canceled");
692 return;
693 default:
694 RCLCPP_INFO(logger_, "Planning request unknown result code");
695 return;
696 }
697 };
698
699 auto goal_handle_future = move_action_client_->async_send_goal(goal, send_goal_opts);
700
701 // wait until send_goal_opts.result_callback is called
702 while (!done)
703 {
704 std::this_thread::sleep_for(std::chrono::milliseconds(1));
705 }
706
707 if (code != rclcpp_action::ResultCode::SUCCEEDED)
708 {
709 RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::plan() failed or timeout reached");
710 return res->error_code;
711 }
712
713 plan.trajectory = res->planned_trajectory;
714 plan.start_state = res->trajectory_start;
715 plan.planning_time = res->planning_time;
716 RCLCPP_INFO(logger_, "time taken to generate plan: %g seconds", plan.planning_time);
717
718 return res->error_code;
719 }
720
722 {
723 if (!move_action_client_ || !move_action_client_->action_server_is_ready())
724 {
725 RCLCPP_INFO_STREAM(logger_, "MoveGroup action client/server not ready");
726 return moveit::core::MoveItErrorCode::FAILURE;
727 }
728
729 moveit_msgs::action::MoveGroup::Goal goal;
730 constructGoal(goal);
731 goal.planning_options.plan_only = false;
732 goal.planning_options.look_around = can_look_;
733 goal.planning_options.replan = can_replan_;
734 goal.planning_options.replan_delay = replan_delay_;
735 goal.planning_options.planning_scene_diff.is_diff = true;
736 goal.planning_options.planning_scene_diff.robot_state.is_diff = true;
737
738 bool done = false;
739 rclcpp_action::ResultCode code = rclcpp_action::ResultCode::UNKNOWN;
740 std::shared_ptr<moveit_msgs::action::MoveGroup_Result> res;
741 auto send_goal_opts = rclcpp_action::Client<moveit_msgs::action::MoveGroup>::SendGoalOptions();
742
743 send_goal_opts.goal_response_callback =
744 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::SharedPtr& goal_handle) {
745 if (!goal_handle)
746 {
747 done = true;
748 RCLCPP_INFO(logger_, "Plan and Execute request rejected");
749 }
750 else
751 RCLCPP_INFO(logger_, "Plan and Execute request accepted");
752 };
753 send_goal_opts.result_callback =
754 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::MoveGroup>::WrappedResult& result) {
755 res = result.result;
756 code = result.code;
757 done = true;
758
759 switch (result.code)
760 {
761 case rclcpp_action::ResultCode::SUCCEEDED:
762 RCLCPP_INFO(logger_, "Plan and Execute request complete!");
763 break;
764 case rclcpp_action::ResultCode::ABORTED:
765 RCLCPP_INFO(logger_, "Plan and Execute request aborted");
766 return;
767 case rclcpp_action::ResultCode::CANCELED:
768 RCLCPP_INFO(logger_, "Plan and Execute request canceled");
769 return;
770 default:
771 RCLCPP_INFO(logger_, "Plan and Execute request unknown result code");
772 return;
773 }
774 };
775 auto goal_handle_future = move_action_client_->async_send_goal(goal, send_goal_opts);
776 if (!wait)
777 return moveit::core::MoveItErrorCode::SUCCESS;
778
779 // wait until send_goal_opts.result_callback is called
780 while (!done)
781 {
782 std::this_thread::sleep_for(std::chrono::milliseconds(1));
783 }
784
785 if (code != rclcpp_action::ResultCode::SUCCEEDED)
786 {
787 RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::move() failed or timeout reached");
788 }
789 return res->error_code;
790 }
791
792 moveit::core::MoveItErrorCode execute(const moveit_msgs::msg::RobotTrajectory& trajectory, bool wait,
793 const std::vector<std::string>& controllers = std::vector<std::string>())
794 {
795 if (!execute_action_client_ || !execute_action_client_->action_server_is_ready())
796 {
797 RCLCPP_INFO_STREAM(logger_, "execute_action_client_ client/server not ready");
798 return moveit::core::MoveItErrorCode::FAILURE;
799 }
800
801 bool done = false;
802 rclcpp_action::ResultCode code = rclcpp_action::ResultCode::UNKNOWN;
803 std::shared_ptr<moveit_msgs::action::ExecuteTrajectory_Result> res;
804 auto send_goal_opts = rclcpp_action::Client<moveit_msgs::action::ExecuteTrajectory>::SendGoalOptions();
805
806 send_goal_opts.goal_response_callback =
807 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::ExecuteTrajectory>::SharedPtr& goal_handle) {
808 if (!goal_handle)
809 {
810 done = true;
811 RCLCPP_INFO(logger_, "Execute request rejected");
812 }
813 else
814 RCLCPP_INFO(logger_, "Execute request accepted");
815 };
816 send_goal_opts.result_callback =
817 [&](const rclcpp_action::ClientGoalHandle<moveit_msgs::action::ExecuteTrajectory>::WrappedResult& result) {
818 res = result.result;
819 code = result.code;
820 done = true;
821
822 switch (result.code)
823 {
824 case rclcpp_action::ResultCode::SUCCEEDED:
825 RCLCPP_INFO(logger_, "Execute request success!");
826 break;
827 case rclcpp_action::ResultCode::ABORTED:
828 RCLCPP_INFO(logger_, "Execute request aborted");
829 return;
830 case rclcpp_action::ResultCode::CANCELED:
831 RCLCPP_INFO(logger_, "Execute request canceled");
832 return;
833 default:
834 RCLCPP_INFO(logger_, "Execute request unknown result code");
835 return;
836 }
837 };
838
839 moveit_msgs::action::ExecuteTrajectory::Goal goal;
840 goal.trajectory = trajectory;
841 goal.controller_names = controllers;
842
843 auto goal_handle_future = execute_action_client_->async_send_goal(goal, send_goal_opts);
844 if (!wait)
845 return moveit::core::MoveItErrorCode::SUCCESS;
846
847 // wait until send_goal_opts.result_callback is called
848 while (!done)
849 {
850 std::this_thread::sleep_for(std::chrono::milliseconds(1));
851 }
852
853 if (code != rclcpp_action::ResultCode::SUCCEEDED)
854 {
855 RCLCPP_ERROR_STREAM(logger_, "MoveGroupInterface::execute() failed or timeout reached");
856 }
857 return res->error_code;
858 }
859
860 double computeCartesianPath(const std::vector<geometry_msgs::msg::Pose>& waypoints, double step,
861 moveit_msgs::msg::RobotTrajectory& msg,
862 const moveit_msgs::msg::Constraints& path_constraints, bool avoid_collisions,
863 moveit_msgs::msg::MoveItErrorCodes& error_code)
864 {
865 auto req = std::make_shared<moveit_msgs::srv::GetCartesianPath::Request>();
866 moveit_msgs::srv::GetCartesianPath::Response::SharedPtr response;
867
868 req->start_state = considered_start_state_;
869 req->group_name = opt_.group_name;
870 req->header.frame_id = getPoseReferenceFrame();
871 req->header.stamp = getClock()->now();
872 req->waypoints = waypoints;
873 req->max_step = step;
874 req->path_constraints = path_constraints;
875 req->avoid_collisions = avoid_collisions;
876 req->link_name = getEndEffectorLink();
877 req->max_velocity_scaling_factor = max_velocity_scaling_factor_;
878 req->max_acceleration_scaling_factor = max_acceleration_scaling_factor_;
879
880 auto future_response = cartesian_path_service_->async_send_request(req);
881 if (future_response.valid())
882 {
883 response = future_response.get();
884 error_code = response->error_code;
885 if (response->error_code.val == moveit_msgs::msg::MoveItErrorCodes::SUCCESS)
886 {
887 msg = response->solution;
888 return response->fraction;
889 }
890 else
891 return -1.0;
892 }
893 else
894 {
895 error_code.val = error_code.FAILURE;
896 return -1.0;
897 }
898 }
899
900 void stop()
901 {
902 if (trajectory_event_publisher_)
903 {
904 std_msgs::msg::String event;
905 event.data = "stop";
906 trajectory_event_publisher_->publish(event);
907 }
908 }
909
910 bool attachObject(const std::string& object, const std::string& link, const std::vector<std::string>& touch_links)
911 {
912 std::string l = link.empty() ? getEndEffectorLink() : link;
913 if (l.empty())
914 {
915 const std::vector<std::string>& links = joint_model_group_->getLinkModelNames();
916 if (!links.empty())
917 l = links[0];
918 }
919 if (l.empty())
920 {
921 RCLCPP_ERROR(logger_, "No known link to attach object '%s' to", object.c_str());
922 return false;
923 }
924 moveit_msgs::msg::AttachedCollisionObject aco;
925 aco.object.id = object;
926 aco.link_name.swap(l);
927 if (touch_links.empty())
928 {
929 aco.touch_links.push_back(aco.link_name);
930 }
931 else
932 {
933 aco.touch_links = touch_links;
934 }
935 aco.object.operation = moveit_msgs::msg::CollisionObject::ADD;
936 attached_object_publisher_->publish(aco);
937 return true;
938 }
939
940 bool detachObject(const std::string& name)
941 {
942 moveit_msgs::msg::AttachedCollisionObject aco;
943 // if name is a link
944 if (!name.empty() && joint_model_group_->hasLinkModel(name))
945 {
946 aco.link_name = name;
947 }
948 else
949 {
950 aco.object.id = name;
951 }
952 aco.object.operation = moveit_msgs::msg::CollisionObject::REMOVE;
953 if (aco.link_name.empty() && aco.object.id.empty())
954 {
955 // we only want to detach objects for this group
956 const std::vector<std::string>& lnames = joint_model_group_->getLinkModelNames();
957 for (const std::string& lname : lnames)
958 {
959 aco.link_name = lname;
960 attached_object_publisher_->publish(aco);
961 }
962 }
963 else
964 {
965 attached_object_publisher_->publish(aco);
966 }
967 return true;
968 }
969
971 {
972 return goal_position_tolerance_;
973 }
974
976 {
977 return goal_orientation_tolerance_;
978 }
979
981 {
982 return goal_joint_tolerance_;
983 }
984
985 void setGoalJointTolerance(double tolerance)
986 {
987 goal_joint_tolerance_ = tolerance;
988 }
989
990 void setGoalPositionTolerance(double tolerance)
991 {
992 goal_position_tolerance_ = tolerance;
993 }
994
995 void setGoalOrientationTolerance(double tolerance)
996 {
997 goal_orientation_tolerance_ = tolerance;
998 }
999
1000 void setPlanningTime(double seconds)
1001 {
1002 if (seconds > 0.0)
1003 allowed_planning_time_ = seconds;
1004 }
1005
1006 double getPlanningTime() const
1007 {
1008 return allowed_planning_time_;
1009 }
1010
1011 void constructRobotState(moveit_msgs::msg::RobotState& state) const
1012 {
1013 state = considered_start_state_;
1014 }
1015
1016 void constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest& request) const
1017 {
1018 request.group_name = opt_.group_name;
1019 request.num_planning_attempts = num_planning_attempts_;
1020 request.max_velocity_scaling_factor = max_velocity_scaling_factor_;
1021 request.max_acceleration_scaling_factor = max_acceleration_scaling_factor_;
1022 request.allowed_planning_time = allowed_planning_time_;
1023 request.pipeline_id = planning_pipeline_id_;
1024 request.planner_id = planner_id_;
1025 request.workspace_parameters = workspace_parameters_;
1026 request.start_state = considered_start_state_;
1027
1028 if (active_target_ == JOINT)
1029 {
1030 request.goal_constraints.resize(1);
1031 request.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(
1032 getTargetRobotState(), joint_model_group_, goal_joint_tolerance_);
1033 }
1034 else if (active_target_ == POSE || active_target_ == POSITION || active_target_ == ORIENTATION)
1035 {
1036 // find out how many goals are specified
1037 std::size_t goal_count = 0;
1038 for (const auto& pose_target : pose_targets_)
1039 goal_count = std::max(goal_count, pose_target.second.size());
1040
1041 // start filling the goals;
1042 // each end effector has a number of possible poses (K) as valid goals
1043 // but there could be multiple end effectors specified, so we want each end effector
1044 // to reach the goal that corresponds to the goals of the other end effectors
1045 request.goal_constraints.resize(goal_count);
1046
1047 for (const auto& pose_target : pose_targets_)
1048 {
1049 for (std::size_t i = 0; i < pose_target.second.size(); ++i)
1050 {
1051 moveit_msgs::msg::Constraints c = kinematic_constraints::constructGoalConstraints(
1052 pose_target.first, pose_target.second[i], goal_position_tolerance_, goal_orientation_tolerance_);
1053 if (active_target_ == ORIENTATION)
1054 c.position_constraints.clear();
1055 if (active_target_ == POSITION)
1056 c.orientation_constraints.clear();
1057 request.goal_constraints[i] = kinematic_constraints::mergeConstraints(request.goal_constraints[i], c);
1058 }
1059 }
1060 }
1061 else
1062 RCLCPP_ERROR(logger_, "Unable to construct MotionPlanRequest representation");
1063
1064 if (path_constraints_)
1065 request.path_constraints = *path_constraints_;
1066 if (trajectory_constraints_)
1067 request.trajectory_constraints = *trajectory_constraints_;
1068 }
1069
1070 void constructGoal(moveit_msgs::action::MoveGroup::Goal& goal) const
1071 {
1072 constructMotionPlanRequest(goal.request);
1073 }
1074
1075 void setPathConstraints(const moveit_msgs::msg::Constraints& constraint)
1076 {
1077 path_constraints_ = std::make_unique<moveit_msgs::msg::Constraints>(constraint);
1078 }
1079
1080 bool setPathConstraints(const std::string& constraint)
1081 {
1082 if (constraints_storage_)
1083 {
1085 if (constraints_storage_->getConstraints(msg_m, constraint, robot_model_->getName(), opt_.group_name))
1086 {
1087 path_constraints_ =
1088 std::make_unique<moveit_msgs::msg::Constraints>(static_cast<moveit_msgs::msg::Constraints>(*msg_m));
1089 return true;
1090 }
1091 else
1092 return false;
1093 }
1094 else
1095 return false;
1096 }
1097
1099 {
1100 path_constraints_.reset();
1101 }
1102
1103 void setTrajectoryConstraints(const moveit_msgs::msg::TrajectoryConstraints& constraint)
1104 {
1105 trajectory_constraints_ = std::make_unique<moveit_msgs::msg::TrajectoryConstraints>(constraint);
1106 }
1107
1109 {
1110 trajectory_constraints_.reset();
1111 }
1112
1113 std::vector<std::string> getKnownConstraints() const
1114 {
1115 while (initializing_constraints_)
1116 {
1117 std::chrono::duration<double> d(0.01);
1118 rclcpp::sleep_for(std::chrono::duration_cast<std::chrono::nanoseconds>(d), rclcpp::Context::SharedPtr(nullptr));
1119 }
1120
1121 std::vector<std::string> c;
1122 if (constraints_storage_)
1123 constraints_storage_->getKnownConstraints(c, robot_model_->getName(), opt_.group_name);
1124
1125 return c;
1126 }
1127
1128 moveit_msgs::msg::Constraints getPathConstraints() const
1129 {
1130 if (path_constraints_)
1131 {
1132 return *path_constraints_;
1133 }
1134 else
1135 {
1136 return moveit_msgs::msg::Constraints();
1137 }
1138 }
1139
1140 moveit_msgs::msg::TrajectoryConstraints getTrajectoryConstraints() const
1141 {
1142 if (trajectory_constraints_)
1143 {
1144 return *trajectory_constraints_;
1145 }
1146 else
1147 {
1148 return moveit_msgs::msg::TrajectoryConstraints();
1149 }
1150 }
1151
1152 void initializeConstraintsStorage(const std::string& host, unsigned int port)
1153 {
1154 initializing_constraints_ = true;
1155 if (constraints_init_thread_)
1156 constraints_init_thread_->join();
1157 constraints_init_thread_ =
1158 std::make_unique<std::thread>([this, host, port] { initializeConstraintsStorageThread(host, port); });
1159 }
1160
1161 void setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
1162 {
1163 workspace_parameters_.header.frame_id = getRobotModel()->getModelFrame();
1164 workspace_parameters_.header.stamp = getClock()->now();
1165 workspace_parameters_.min_corner.x = minx;
1166 workspace_parameters_.min_corner.y = miny;
1167 workspace_parameters_.min_corner.z = minz;
1168 workspace_parameters_.max_corner.x = maxx;
1169 workspace_parameters_.max_corner.y = maxy;
1170 workspace_parameters_.max_corner.z = maxz;
1171 }
1172
1173 rclcpp::Clock::SharedPtr getClock()
1174 {
1175 return node_->get_clock();
1176 }
1177
1178private:
1179 void initializeConstraintsStorageThread(const std::string& host, unsigned int port)
1180 {
1181 // Set up db
1182 try
1183 {
1184 warehouse_ros::DatabaseConnection::Ptr conn = moveit_warehouse::loadDatabase(node_);
1185 conn->setParams(host, port);
1186 if (conn->connect())
1187 {
1188 constraints_storage_ = std::make_unique<moveit_warehouse::ConstraintsStorage>(conn);
1189 }
1190 }
1191 catch (std::exception& ex)
1192 {
1193 RCLCPP_ERROR(logger_, "%s", ex.what());
1194 }
1195 initializing_constraints_ = false;
1196 }
1197
1198 Options opt_;
1199 rclcpp::Node::SharedPtr node_;
1200 rclcpp::Logger logger_;
1201 rclcpp::CallbackGroup::SharedPtr callback_group_;
1202 rclcpp::executors::SingleThreadedExecutor callback_executor_;
1203 std::thread callback_thread_;
1204 std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
1205 moveit::core::RobotModelConstPtr robot_model_;
1206 planning_scene_monitor::CurrentStateMonitorPtr current_state_monitor_;
1207
1208 std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::MoveGroup>> move_action_client_;
1209 // std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::Pickup>> pick_action_client_;
1210 // std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::Place>> place_action_client_;
1211 std::shared_ptr<rclcpp_action::Client<moveit_msgs::action::ExecuteTrajectory>> execute_action_client_;
1212
1213 // general planning params
1214 moveit_msgs::msg::RobotState considered_start_state_;
1215 moveit_msgs::msg::WorkspaceParameters workspace_parameters_;
1216 double allowed_planning_time_;
1217 std::string planning_pipeline_id_;
1218 std::string planner_id_;
1219 unsigned int num_planning_attempts_;
1220 double max_velocity_scaling_factor_;
1221 double max_acceleration_scaling_factor_;
1222 double goal_joint_tolerance_;
1223 double goal_position_tolerance_;
1224 double goal_orientation_tolerance_;
1225 bool can_look_;
1226 int32_t look_around_attempts_;
1227 bool can_replan_;
1228 int32_t replan_attempts_;
1229 double replan_delay_;
1230
1231 // joint state goal
1232 moveit::core::RobotStatePtr joint_state_target_;
1233 const moveit::core::JointModelGroup* joint_model_group_;
1234
1235 // pose goal;
1236 // for each link we have a set of possible goal locations;
1237 std::map<std::string, std::vector<geometry_msgs::msg::PoseStamped>> pose_targets_;
1238
1239 // common properties for goals
1240 ActiveTargetType active_target_;
1241 std::unique_ptr<moveit_msgs::msg::Constraints> path_constraints_;
1242 std::unique_ptr<moveit_msgs::msg::TrajectoryConstraints> trajectory_constraints_;
1243 std::string end_effector_link_;
1244 std::string pose_reference_frame_;
1245
1246 // ROS communication
1247 rclcpp::Publisher<std_msgs::msg::String>::SharedPtr trajectory_event_publisher_;
1248 rclcpp::Publisher<moveit_msgs::msg::AttachedCollisionObject>::SharedPtr attached_object_publisher_;
1249 rclcpp::Client<moveit_msgs::srv::QueryPlannerInterfaces>::SharedPtr query_service_;
1250 rclcpp::Client<moveit_msgs::srv::GetPlannerParams>::SharedPtr get_params_service_;
1251 rclcpp::Client<moveit_msgs::srv::SetPlannerParams>::SharedPtr set_params_service_;
1252 rclcpp::Client<moveit_msgs::srv::GetCartesianPath>::SharedPtr cartesian_path_service_;
1253 // rclcpp::Client<moveit_msgs::srv::GraspPlanning>::SharedPtr plan_grasps_service_;
1254 std::unique_ptr<moveit_warehouse::ConstraintsStorage> constraints_storage_;
1255 std::unique_ptr<std::thread> constraints_init_thread_;
1256 bool initializing_constraints_;
1257};
1258
1259MoveGroupInterface::MoveGroupInterface(const rclcpp::Node::SharedPtr& node, const std::string& group_name,
1260 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
1261 const rclcpp::Duration& wait_for_servers)
1262 : logger_(moveit::getLogger("moveit.ros.move_group_interface"))
1263{
1264 if (!rclcpp::ok())
1265 throw std::runtime_error("ROS does not seem to be running");
1266 impl_ =
1267 new MoveGroupInterfaceImpl(node, Options(group_name), tf_buffer ? tf_buffer : getSharedTF(), wait_for_servers);
1268}
1269
1270MoveGroupInterface::MoveGroupInterface(const rclcpp::Node::SharedPtr& node, const Options& opt,
1271 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
1272 const rclcpp::Duration& wait_for_servers)
1273 : logger_(moveit::getLogger("moveit.ros.move_group_interface"))
1274{
1275 impl_ = new MoveGroupInterfaceImpl(node, opt, tf_buffer ? tf_buffer : getSharedTF(), wait_for_servers);
1276}
1277
1279{
1280 delete impl_;
1281}
1282
1284 : remembered_joint_values_(std::move(other.remembered_joint_values_))
1285 , impl_(other.impl_)
1286 , logger_(std::move(other.logger_))
1287{
1288 other.impl_ = nullptr;
1289}
1290
1292{
1293 if (this != &other)
1294 {
1295 delete impl_;
1296 impl_ = other.impl_;
1297 logger_ = other.logger_;
1298 remembered_joint_values_ = std::move(other.remembered_joint_values_);
1299 other.impl_ = nullptr;
1300 }
1301
1302 return *this;
1303}
1304
1305const std::string& MoveGroupInterface::getName() const
1306{
1307 return impl_->getOptions().group_name;
1308}
1309
1310const std::vector<std::string>& MoveGroupInterface::getNamedTargets() const
1311{
1312 // The pointer returned by getJointModelGroup is guaranteed by the class
1313 // constructor to always be non-null
1314 return impl_->getJointModelGroup()->getDefaultStateNames();
1315}
1316
1317const std::shared_ptr<tf2_ros::Buffer>& MoveGroupInterface::getTF() const
1318{
1319 return impl_->getTF();
1320}
1321
1322moveit::core::RobotModelConstPtr MoveGroupInterface::getRobotModel() const
1323{
1324 return impl_->getRobotModel();
1325}
1326
1327bool MoveGroupInterface::getInterfaceDescription(moveit_msgs::msg::PlannerInterfaceDescription& desc) const
1328{
1329 return impl_->getInterfaceDescription(desc);
1330}
1331
1332bool MoveGroupInterface::getInterfaceDescriptions(std::vector<moveit_msgs::msg::PlannerInterfaceDescription>& desc) const
1333{
1334 return impl_->getInterfaceDescriptions(desc);
1335}
1336
1337std::map<std::string, std::string> MoveGroupInterface::getPlannerParams(const std::string& planner_id,
1338 const std::string& group) const
1339{
1340 return impl_->getPlannerParams(planner_id, group);
1341}
1342
1343void MoveGroupInterface::setPlannerParams(const std::string& planner_id, const std::string& group,
1344 const std::map<std::string, std::string>& params, bool replace)
1345{
1346 impl_->setPlannerParams(planner_id, group, params, replace);
1347}
1348
1350{
1351 return impl_->getDefaultPlanningPipelineId();
1352}
1353
1354void MoveGroupInterface::setPlanningPipelineId(const std::string& pipeline_id)
1355{
1356 impl_->setPlanningPipelineId(pipeline_id);
1357}
1358
1360{
1361 return impl_->getPlanningPipelineId();
1362}
1363
1364std::string MoveGroupInterface::getDefaultPlannerId(const std::string& group) const
1365{
1366 return impl_->getDefaultPlannerId(group);
1367}
1368
1369void MoveGroupInterface::setPlannerId(const std::string& planner_id)
1370{
1371 impl_->setPlannerId(planner_id);
1372}
1373
1374const std::string& MoveGroupInterface::getPlannerId() const
1375{
1376 return impl_->getPlannerId();
1377}
1378
1379void MoveGroupInterface::setNumPlanningAttempts(unsigned int num_planning_attempts)
1380{
1381 impl_->setNumPlanningAttempts(num_planning_attempts);
1382}
1383
1384void MoveGroupInterface::setMaxVelocityScalingFactor(double max_velocity_scaling_factor)
1385{
1386 impl_->setMaxVelocityScalingFactor(max_velocity_scaling_factor);
1387}
1388
1393
1394void MoveGroupInterface::setMaxAccelerationScalingFactor(double max_acceleration_scaling_factor)
1395{
1396 impl_->setMaxAccelerationScalingFactor(max_acceleration_scaling_factor);
1397}
1398
1403
1408
1409rclcpp_action::Client<moveit_msgs::action::MoveGroup>& MoveGroupInterface::getMoveGroupClient() const
1410{
1411 return impl_->getMoveGroupClient();
1412}
1413
1415{
1416 return impl_->move(true);
1417}
1418
1420 const std::vector<std::string>& controllers)
1421{
1422 return impl_->execute(plan.trajectory, false, controllers);
1423}
1424
1425moveit::core::MoveItErrorCode MoveGroupInterface::asyncExecute(const moveit_msgs::msg::RobotTrajectory& trajectory,
1426 const std::vector<std::string>& controllers)
1427{
1428 return impl_->execute(trajectory, false, controllers);
1429}
1430
1431moveit::core::MoveItErrorCode MoveGroupInterface::execute(const Plan& plan, const std::vector<std::string>& controllers)
1432{
1433 return impl_->execute(plan.trajectory, true, controllers);
1434}
1435
1436moveit::core::MoveItErrorCode MoveGroupInterface::execute(const moveit_msgs::msg::RobotTrajectory& trajectory,
1437 const std::vector<std::string>& controllers)
1438{
1439 return impl_->execute(trajectory, true, controllers);
1440}
1441
1446
1447double MoveGroupInterface::computeCartesianPath(const std::vector<geometry_msgs::msg::Pose>& waypoints, double eef_step,
1448 moveit_msgs::msg::RobotTrajectory& trajectory, bool avoid_collisions,
1449 moveit_msgs::msg::MoveItErrorCodes* error_code)
1450{
1451 moveit_msgs::msg::Constraints path_constraints_tmp;
1452 return computeCartesianPath(waypoints, eef_step, trajectory, moveit_msgs::msg::Constraints(), avoid_collisions,
1453 error_code);
1454}
1455
1456double MoveGroupInterface::computeCartesianPath(const std::vector<geometry_msgs::msg::Pose>& waypoints, double eef_step,
1457 moveit_msgs::msg::RobotTrajectory& trajectory,
1458 const moveit_msgs::msg::Constraints& path_constraints,
1459 bool avoid_collisions, moveit_msgs::msg::MoveItErrorCodes* error_code)
1460{
1461 if (error_code)
1462 {
1463 return impl_->computeCartesianPath(waypoints, eef_step, trajectory, path_constraints, avoid_collisions, *error_code);
1464 }
1465 else
1466 {
1467 moveit_msgs::msg::MoveItErrorCodes err_tmp;
1468 err_tmp.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
1469 moveit_msgs::msg::MoveItErrorCodes& err = error_code ? *error_code : err_tmp;
1470 return impl_->computeCartesianPath(waypoints, eef_step, trajectory, path_constraints, avoid_collisions, err);
1471 }
1472}
1473
1475{
1476 impl_->stop();
1477}
1478
1479void MoveGroupInterface::setStartState(const moveit_msgs::msg::RobotState& start_state)
1480{
1481 impl_->setStartState(start_state);
1482}
1483
1485{
1486 impl_->setStartState(start_state);
1487}
1488
1493
1499
1500const std::vector<std::string>& MoveGroupInterface::getJointNames() const
1501{
1502 return impl_->getJointModelGroup()->getVariableNames();
1503}
1504
1505const std::vector<std::string>& MoveGroupInterface::getLinkNames() const
1506{
1507 return impl_->getJointModelGroup()->getLinkModelNames();
1508}
1509
1510std::map<std::string, double> MoveGroupInterface::getNamedTargetValues(const std::string& name) const
1511{
1512 std::map<std::string, std::vector<double>>::const_iterator it = remembered_joint_values_.find(name);
1513 std::map<std::string, double> positions;
1514
1515 if (it != remembered_joint_values_.cend())
1516 {
1517 std::vector<std::string> names = impl_->getJointModelGroup()->getVariableNames();
1518 for (size_t x = 0; x < names.size(); ++x)
1519 {
1520 positions[names[x]] = it->second[x];
1521 }
1522 }
1523 else
1524 {
1525 if (!impl_->getJointModelGroup()->getVariableDefaultPositions(name, positions))
1526 {
1527 RCLCPP_ERROR(logger_, "The requested named target '%s' does not exist, returning empty positions.", name.c_str());
1528 }
1529 }
1530 return positions;
1531}
1532
1533bool MoveGroupInterface::setNamedTarget(const std::string& name)
1534{
1535 std::map<std::string, std::vector<double>>::const_iterator it = remembered_joint_values_.find(name);
1536 if (it != remembered_joint_values_.end())
1537 {
1538 return setJointValueTarget(it->second);
1539 }
1540 else
1541 {
1542 if (impl_->getTargetRobotState().setToDefaultValues(impl_->getJointModelGroup(), name))
1543 {
1544 impl_->setTargetType(JOINT);
1545 return true;
1546 }
1547 RCLCPP_ERROR(logger_, "The requested named target '%s' does not exist", name.c_str());
1548 return false;
1549 }
1550}
1551
1552void MoveGroupInterface::getJointValueTarget(std::vector<double>& group_variable_values) const
1553{
1554 impl_->getTargetRobotState().copyJointGroupPositions(impl_->getJointModelGroup(), group_variable_values);
1555}
1556
1557bool MoveGroupInterface::setJointValueTarget(const std::vector<double>& joint_values)
1558{
1559 const auto n_group_joints = impl_->getJointModelGroup()->getVariableCount();
1560 if (joint_values.size() != n_group_joints)
1561 {
1562 RCLCPP_DEBUG_STREAM(logger_, "Provided joint value list has length " << joint_values.size() << " but group "
1563 << impl_->getJointModelGroup()->getName()
1564 << " has " << n_group_joints << " joints");
1565 return false;
1566 }
1567 impl_->setTargetType(JOINT);
1568 impl_->getTargetRobotState().setJointGroupPositions(impl_->getJointModelGroup(), joint_values);
1570}
1571
1572bool MoveGroupInterface::setJointValueTarget(const std::map<std::string, double>& variable_values)
1573{
1574 const auto& allowed = impl_->getJointModelGroup()->getVariableNames();
1575 for (const auto& pair : variable_values)
1576 {
1577 if (std::find(allowed.begin(), allowed.end(), pair.first) == allowed.end())
1578 {
1579 RCLCPP_ERROR_STREAM(logger_, "joint variable " << pair.first << " is not part of group "
1580 << impl_->getJointModelGroup()->getName());
1581 return false;
1582 }
1583 }
1584
1585 impl_->setTargetType(JOINT);
1586 impl_->getTargetRobotState().setVariablePositions(variable_values);
1588}
1589
1590bool MoveGroupInterface::setJointValueTarget(const std::vector<std::string>& variable_names,
1591 const std::vector<double>& variable_values)
1592{
1593 if (variable_names.size() != variable_values.size())
1594 {
1595 RCLCPP_ERROR_STREAM(logger_, "sizes of name and position arrays do not match");
1596 return false;
1597 }
1598 const auto& allowed = impl_->getJointModelGroup()->getVariableNames();
1599 for (const auto& variable_name : variable_names)
1600 {
1601 if (std::find(allowed.begin(), allowed.end(), variable_name) == allowed.end())
1602 {
1603 RCLCPP_ERROR_STREAM(logger_, "joint variable " << variable_name << " is not part of group "
1604 << impl_->getJointModelGroup()->getName());
1605 return false;
1606 }
1607 }
1608
1609 impl_->setTargetType(JOINT);
1610 impl_->getTargetRobotState().setVariablePositions(variable_names, variable_values);
1612}
1613
1615{
1616 impl_->setTargetType(JOINT);
1617 impl_->getTargetRobotState() = rstate;
1619}
1620
1621bool MoveGroupInterface::setJointValueTarget(const std::string& joint_name, double value)
1622{
1623 std::vector<double> values(1, value);
1624 return setJointValueTarget(joint_name, values);
1625}
1626
1627bool MoveGroupInterface::setJointValueTarget(const std::string& joint_name, const std::vector<double>& values)
1628{
1629 impl_->setTargetType(JOINT);
1630 const moveit::core::JointModel* jm = impl_->getJointModelGroup()->getJointModel(joint_name);
1631 if (jm && jm->getVariableCount() == values.size())
1632 {
1633 impl_->getTargetRobotState().setJointPositions(jm, values);
1634 return impl_->getTargetRobotState().satisfiesBounds(jm, impl_->getGoalJointTolerance());
1635 }
1636
1637 RCLCPP_ERROR_STREAM(logger_,
1638 "joint " << joint_name << " is not part of group " << impl_->getJointModelGroup()->getName());
1639 return false;
1640}
1641
1642bool MoveGroupInterface::setJointValueTarget(const sensor_msgs::msg::JointState& state)
1643{
1644 return setJointValueTarget(state.name, state.position);
1645}
1646
1647bool MoveGroupInterface::setJointValueTarget(const geometry_msgs::msg::Pose& eef_pose,
1648 const std::string& end_effector_link)
1649{
1650 return impl_->setJointValueTarget(eef_pose, end_effector_link, "", false);
1651}
1652
1653bool MoveGroupInterface::setJointValueTarget(const geometry_msgs::msg::PoseStamped& eef_pose,
1654 const std::string& end_effector_link)
1655{
1656 return impl_->setJointValueTarget(eef_pose.pose, end_effector_link, eef_pose.header.frame_id, false);
1657}
1658
1659bool MoveGroupInterface::setJointValueTarget(const Eigen::Isometry3d& eef_pose, const std::string& end_effector_link)
1660{
1661 geometry_msgs::msg::Pose msg = tf2::toMsg(eef_pose);
1662 return setJointValueTarget(msg, end_effector_link);
1663}
1664
1665bool MoveGroupInterface::setApproximateJointValueTarget(const geometry_msgs::msg::Pose& eef_pose,
1666 const std::string& end_effector_link)
1667{
1668 return impl_->setJointValueTarget(eef_pose, end_effector_link, "", true);
1669}
1670
1671bool MoveGroupInterface::setApproximateJointValueTarget(const geometry_msgs::msg::PoseStamped& eef_pose,
1672 const std::string& end_effector_link)
1673{
1674 return impl_->setJointValueTarget(eef_pose.pose, end_effector_link, eef_pose.header.frame_id, true);
1675}
1676
1677bool MoveGroupInterface::setApproximateJointValueTarget(const Eigen::Isometry3d& eef_pose,
1678 const std::string& end_effector_link)
1679{
1680 geometry_msgs::msg::Pose msg = tf2::toMsg(eef_pose);
1681 return setApproximateJointValueTarget(msg, end_effector_link);
1682}
1683
1688
1690{
1691 return impl_->getEndEffectorLink();
1692}
1693
1694const std::string& MoveGroupInterface::getEndEffector() const
1695{
1696 return impl_->getEndEffector();
1697}
1698
1699bool MoveGroupInterface::setEndEffectorLink(const std::string& link_name)
1700{
1701 if (impl_->getEndEffectorLink().empty() || link_name.empty())
1702 return false;
1703 impl_->setEndEffectorLink(link_name);
1704 impl_->setTargetType(POSE);
1705 return true;
1706}
1707
1708bool MoveGroupInterface::setEndEffector(const std::string& eef_name)
1709{
1710 const moveit::core::JointModelGroup* jmg = impl_->getRobotModel()->getEndEffector(eef_name);
1711 if (jmg)
1712 return setEndEffectorLink(jmg->getEndEffectorParentGroup().second);
1713 return false;
1714}
1715
1716void MoveGroupInterface::clearPoseTarget(const std::string& end_effector_link)
1717{
1718 impl_->clearPoseTarget(end_effector_link);
1719}
1720
1725
1726bool MoveGroupInterface::setPoseTarget(const Eigen::Isometry3d& pose, const std::string& end_effector_link)
1727{
1728 std::vector<geometry_msgs::msg::PoseStamped> pose_msg(1);
1729 pose_msg[0].pose = tf2::toMsg(pose);
1730 pose_msg[0].header.frame_id = getPoseReferenceFrame();
1731 pose_msg[0].header.stamp = impl_->getClock()->now();
1732 return setPoseTargets(pose_msg, end_effector_link);
1733}
1734
1735bool MoveGroupInterface::setPoseTarget(const geometry_msgs::msg::Pose& target, const std::string& end_effector_link)
1736{
1737 std::vector<geometry_msgs::msg::PoseStamped> pose_msg(1);
1738 pose_msg[0].pose = target;
1739 pose_msg[0].header.frame_id = getPoseReferenceFrame();
1740 pose_msg[0].header.stamp = impl_->getClock()->now();
1741 return setPoseTargets(pose_msg, end_effector_link);
1742}
1743
1744bool MoveGroupInterface::setPoseTarget(const geometry_msgs::msg::PoseStamped& target,
1745 const std::string& end_effector_link)
1746{
1747 std::vector<geometry_msgs::msg::PoseStamped> targets(1, target);
1748 return setPoseTargets(targets, end_effector_link);
1749}
1750
1751bool MoveGroupInterface::setPoseTargets(const EigenSTL::vector_Isometry3d& target, const std::string& end_effector_link)
1752{
1753 std::vector<geometry_msgs::msg::PoseStamped> pose_out(target.size());
1754 rclcpp::Time tm = impl_->getClock()->now();
1755 const std::string& frame_id = getPoseReferenceFrame();
1756 for (std::size_t i = 0; i < target.size(); ++i)
1757 {
1758 pose_out[i].pose = tf2::toMsg(target[i]);
1759 pose_out[i].header.stamp = tm;
1760 pose_out[i].header.frame_id = frame_id;
1761 }
1762 return setPoseTargets(pose_out, end_effector_link);
1763}
1764
1765bool MoveGroupInterface::setPoseTargets(const std::vector<geometry_msgs::msg::Pose>& target,
1766 const std::string& end_effector_link)
1767{
1768 std::vector<geometry_msgs::msg::PoseStamped> target_stamped(target.size());
1769 rclcpp::Time tm = impl_->getClock()->now();
1770 const std::string& frame_id = getPoseReferenceFrame();
1771 for (std::size_t i = 0; i < target.size(); ++i)
1772 {
1773 target_stamped[i].pose = target[i];
1774 target_stamped[i].header.stamp = tm;
1775 target_stamped[i].header.frame_id = frame_id;
1776 }
1777 return setPoseTargets(target_stamped, end_effector_link);
1778}
1779
1780bool MoveGroupInterface::setPoseTargets(const std::vector<geometry_msgs::msg::PoseStamped>& target,
1781 const std::string& end_effector_link)
1782{
1783 if (target.empty())
1784 {
1785 RCLCPP_ERROR(logger_, "No pose specified as goal target");
1786 return false;
1787 }
1788 else
1789 {
1790 impl_->setTargetType(POSE);
1791 return impl_->setPoseTargets(target, end_effector_link);
1792 }
1793}
1794
1795const geometry_msgs::msg::PoseStamped& MoveGroupInterface::getPoseTarget(const std::string& end_effector_link) const
1796{
1797 return impl_->getPoseTarget(end_effector_link);
1798}
1799
1800const std::vector<geometry_msgs::msg::PoseStamped>&
1801MoveGroupInterface::getPoseTargets(const std::string& end_effector_link) const
1802{
1803 return impl_->getPoseTargets(end_effector_link);
1804}
1805
1806namespace
1807{
1808inline void transformPose(const tf2_ros::Buffer& tf_buffer, const std::string& desired_frame,
1809 geometry_msgs::msg::PoseStamped& target)
1810{
1811 if (desired_frame != target.header.frame_id)
1812 {
1813 geometry_msgs::msg::PoseStamped target_in(target);
1814 tf_buffer.transform(target_in, target, desired_frame);
1815 // we leave the stamp to ros::Time(0) on purpose
1816 target.header.stamp = rclcpp::Time(0);
1817 }
1818}
1819} // namespace
1820
1821bool MoveGroupInterface::setPositionTarget(double x, double y, double z, const std::string& end_effector_link)
1822{
1823 geometry_msgs::msg::PoseStamped target;
1824 if (impl_->hasPoseTarget(end_effector_link))
1825 {
1826 target = getPoseTarget(end_effector_link);
1827 transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
1828 }
1829 else
1830 {
1831 target.pose.orientation.x = 0.0;
1832 target.pose.orientation.y = 0.0;
1833 target.pose.orientation.z = 0.0;
1834 target.pose.orientation.w = 1.0;
1835 target.header.frame_id = impl_->getPoseReferenceFrame();
1836 }
1837
1838 target.pose.position.x = x;
1839 target.pose.position.y = y;
1840 target.pose.position.z = z;
1841 bool result = setPoseTarget(target, end_effector_link);
1842 impl_->setTargetType(POSITION);
1843 return result;
1844}
1845
1846bool MoveGroupInterface::setRPYTarget(double r, double p, double y, const std::string& end_effector_link)
1847{
1848 geometry_msgs::msg::PoseStamped target;
1849 if (impl_->hasPoseTarget(end_effector_link))
1850 {
1851 target = getPoseTarget(end_effector_link);
1852 transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
1853 }
1854 else
1855 {
1856 target.pose.position.x = 0.0;
1857 target.pose.position.y = 0.0;
1858 target.pose.position.z = 0.0;
1859 target.header.frame_id = impl_->getPoseReferenceFrame();
1860 }
1861 tf2::Quaternion q;
1862 q.setRPY(r, p, y);
1863 target.pose.orientation = tf2::toMsg(q);
1864 bool result = setPoseTarget(target, end_effector_link);
1865 impl_->setTargetType(ORIENTATION);
1866 return result;
1867}
1868
1869bool MoveGroupInterface::setOrientationTarget(double x, double y, double z, double w,
1870 const std::string& end_effector_link)
1871{
1872 geometry_msgs::msg::PoseStamped target;
1873 if (impl_->hasPoseTarget(end_effector_link))
1874 {
1875 target = getPoseTarget(end_effector_link);
1876 transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
1877 }
1878 else
1879 {
1880 target.pose.position.x = 0.0;
1881 target.pose.position.y = 0.0;
1882 target.pose.position.z = 0.0;
1883 target.header.frame_id = impl_->getPoseReferenceFrame();
1884 }
1885
1886 target.pose.orientation.x = x;
1887 target.pose.orientation.y = y;
1888 target.pose.orientation.z = z;
1889 target.pose.orientation.w = w;
1890 bool result = setPoseTarget(target, end_effector_link);
1891 impl_->setTargetType(ORIENTATION);
1892 return result;
1893}
1894
1895void MoveGroupInterface::setPoseReferenceFrame(const std::string& pose_reference_frame)
1896{
1897 impl_->setPoseReferenceFrame(pose_reference_frame);
1898}
1899
1901{
1902 return impl_->getPoseReferenceFrame();
1903}
1904
1906{
1907 return impl_->getGoalJointTolerance();
1908}
1909
1911{
1912 return impl_->getGoalPositionTolerance();
1913}
1914
1919
1921{
1922 setGoalJointTolerance(tolerance);
1923 setGoalPositionTolerance(tolerance);
1924 setGoalOrientationTolerance(tolerance);
1925}
1926
1928{
1929 impl_->setGoalJointTolerance(tolerance);
1930}
1931
1933{
1934 impl_->setGoalPositionTolerance(tolerance);
1935}
1936
1938{
1939 impl_->setGoalOrientationTolerance(tolerance);
1940}
1941
1942void MoveGroupInterface::rememberJointValues(const std::string& name)
1943{
1945}
1946
1948{
1949 return impl_->startStateMonitor(wait);
1950}
1951
1953{
1954 moveit::core::RobotStatePtr current_state;
1955 std::vector<double> values;
1956 if (impl_->getCurrentState(current_state))
1957 current_state->copyJointGroupPositions(getName(), values);
1958 return values;
1959}
1960
1962{
1963 std::vector<double> r;
1965 return r;
1966}
1967
1968geometry_msgs::msg::PoseStamped MoveGroupInterface::getRandomPose(const std::string& end_effector_link) const
1969{
1970 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
1971 Eigen::Isometry3d pose;
1972 pose.setIdentity();
1973 if (eef.empty())
1974 {
1975 RCLCPP_ERROR(logger_, "No end-effector specified");
1976 }
1977 else
1978 {
1979 moveit::core::RobotStatePtr current_state;
1980 if (impl_->getCurrentState(current_state))
1981 {
1982 current_state->setToRandomPositions(impl_->getJointModelGroup());
1983 const moveit::core::LinkModel* lm = current_state->getLinkModel(eef);
1984 if (lm)
1985 pose = current_state->getGlobalLinkTransform(lm);
1986 }
1987 }
1988 geometry_msgs::msg::PoseStamped pose_msg;
1989 pose_msg.header.stamp = impl_->getClock()->now();
1990 pose_msg.header.frame_id = impl_->getRobotModel()->getModelFrame();
1991 pose_msg.pose = tf2::toMsg(pose);
1992 return pose_msg;
1993}
1994
1995geometry_msgs::msg::PoseStamped MoveGroupInterface::getCurrentPose(const std::string& end_effector_link) const
1996{
1997 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
1998 Eigen::Isometry3d pose;
1999 pose.setIdentity();
2000 if (eef.empty())
2001 {
2002 RCLCPP_ERROR(logger_, "No end-effector specified");
2003 }
2004 else
2005 {
2006 moveit::core::RobotStatePtr current_state;
2007 if (impl_->getCurrentState(current_state))
2008 {
2009 const moveit::core::LinkModel* lm = current_state->getLinkModel(eef);
2010 if (lm)
2011 pose = current_state->getGlobalLinkTransform(lm);
2012 }
2013 }
2014 geometry_msgs::msg::PoseStamped pose_msg;
2015 pose_msg.header.stamp = impl_->getClock()->now();
2016 pose_msg.header.frame_id = impl_->getRobotModel()->getModelFrame();
2017 pose_msg.pose = tf2::toMsg(pose);
2018 return pose_msg;
2019}
2020
2021std::vector<double> MoveGroupInterface::getCurrentRPY(const std::string& end_effector_link) const
2022{
2023 std::vector<double> result;
2024 const std::string& eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
2025 if (eef.empty())
2026 {
2027 RCLCPP_ERROR(logger_, "No end-effector specified");
2028 }
2029 else
2030 {
2031 moveit::core::RobotStatePtr current_state;
2032 if (impl_->getCurrentState(current_state))
2033 {
2034 const moveit::core::LinkModel* lm = current_state->getLinkModel(eef);
2035 if (lm)
2036 {
2037 result.resize(3);
2038 geometry_msgs::msg::TransformStamped tfs = tf2::eigenToTransform(current_state->getGlobalLinkTransform(lm));
2039 double pitch, roll, yaw;
2040 tf2::getEulerYPR<geometry_msgs::msg::Quaternion>(tfs.transform.rotation, yaw, pitch, roll);
2041 result[0] = roll;
2042 result[1] = pitch;
2043 result[2] = yaw;
2044 }
2045 }
2046 }
2047 return result;
2048}
2049
2050const std::vector<std::string>& MoveGroupInterface::getActiveJoints() const
2051{
2053}
2054
2055const std::vector<std::string>& MoveGroupInterface::getJoints() const
2056{
2057 return impl_->getJointModelGroup()->getJointModelNames();
2058}
2059
2061{
2062 return impl_->getJointModelGroup()->getVariableCount();
2063}
2064
2065moveit::core::RobotStatePtr MoveGroupInterface::getCurrentState(double wait) const
2066{
2067 moveit::core::RobotStatePtr current_state;
2068 impl_->getCurrentState(current_state, wait);
2069 return current_state;
2070}
2071
2072void MoveGroupInterface::rememberJointValues(const std::string& name, const std::vector<double>& values)
2073{
2074 remembered_joint_values_[name] = values;
2075}
2076
2077void MoveGroupInterface::forgetJointValues(const std::string& name)
2078{
2079 remembered_joint_values_.erase(name);
2080}
2081
2083{
2084 impl_->can_look_ = flag;
2085 RCLCPP_DEBUG(logger_, "Looking around: %s", flag ? "yes" : "no");
2086}
2087
2089{
2090 if (attempts < 0)
2091 {
2092 RCLCPP_ERROR(logger_, "Tried to set negative number of look-around attempts");
2093 }
2094 else
2095 {
2096 RCLCPP_DEBUG_STREAM(logger_, "Look around attempts: " << attempts);
2097 impl_->look_around_attempts_ = attempts;
2098 }
2099}
2100
2102{
2103 impl_->can_replan_ = flag;
2104 RCLCPP_DEBUG(logger_, "Replanning: %s", flag ? "yes" : "no");
2105}
2106
2108{
2109 if (attempts < 0)
2110 {
2111 RCLCPP_ERROR(logger_, "Tried to set negative number of replan attempts");
2112 }
2113 else
2114 {
2115 RCLCPP_DEBUG_STREAM(logger_, "Replan Attempts: " << attempts);
2116 impl_->replan_attempts_ = attempts;
2117 }
2118}
2119
2121{
2122 if (delay < 0.0)
2123 {
2124 RCLCPP_ERROR(logger_, "Tried to set negative replan delay");
2125 }
2126 else
2127 {
2128 RCLCPP_DEBUG_STREAM(logger_, "Replan Delay: " << delay);
2129 impl_->replan_delay_ = delay;
2130 }
2131}
2132
2133std::vector<std::string> MoveGroupInterface::getKnownConstraints() const
2134{
2135 return impl_->getKnownConstraints();
2136}
2137
2138moveit_msgs::msg::Constraints MoveGroupInterface::getPathConstraints() const
2139{
2140 return impl_->getPathConstraints();
2141}
2142
2143bool MoveGroupInterface::setPathConstraints(const std::string& constraint)
2144{
2145 return impl_->setPathConstraints(constraint);
2146}
2147
2148void MoveGroupInterface::setPathConstraints(const moveit_msgs::msg::Constraints& constraint)
2149{
2150 impl_->setPathConstraints(constraint);
2151}
2152
2157
2158moveit_msgs::msg::TrajectoryConstraints MoveGroupInterface::getTrajectoryConstraints() const
2159{
2160 return impl_->getTrajectoryConstraints();
2161}
2162
2163void MoveGroupInterface::setTrajectoryConstraints(const moveit_msgs::msg::TrajectoryConstraints& constraint)
2164{
2165 impl_->setTrajectoryConstraints(constraint);
2166}
2167
2172
2173void MoveGroupInterface::setConstraintsDatabase(const std::string& host, unsigned int port)
2174{
2175 impl_->initializeConstraintsStorage(host, port);
2176}
2177
2178void MoveGroupInterface::setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
2179{
2180 impl_->setWorkspace(minx, miny, minz, maxx, maxy, maxz);
2181}
2182
2185{
2186 impl_->setPlanningTime(seconds);
2187}
2188
2191{
2192 return impl_->getPlanningTime();
2193}
2194
2195const rclcpp::Node::SharedPtr& MoveGroupInterface::getNode() const
2196{
2197 return impl_->node_;
2198}
2199
2201{
2202 return impl_->getRobotModel()->getModelFrame();
2203}
2204
2205const std::vector<std::string>& MoveGroupInterface::getJointModelGroupNames() const
2206{
2207 return impl_->getRobotModel()->getJointModelGroupNames();
2208}
2209
2210bool MoveGroupInterface::attachObject(const std::string& object, const std::string& link)
2211{
2212 return attachObject(object, link, std::vector<std::string>());
2213}
2214
2215bool MoveGroupInterface::attachObject(const std::string& object, const std::string& link,
2216 const std::vector<std::string>& touch_links)
2217{
2218 return impl_->attachObject(object, link, touch_links);
2219}
2220
2221bool MoveGroupInterface::detachObject(const std::string& name)
2222{
2223 return impl_->detachObject(name);
2224}
2225
2226void MoveGroupInterface::constructRobotState(moveit_msgs::msg::RobotState& state)
2227{
2228 impl_->constructRobotState(state);
2229}
2230
2231void MoveGroupInterface::constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest& goal_out)
2232{
2233 impl_->constructMotionPlanRequest(goal_out);
2234}
2235
2236} // namespace planning_interface
2237} // 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.
Definition link_model.h:72
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.
Definition robot_state.h:90
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_...
Definition robot_state.h:70
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.
Definition exceptions.h:43
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)