67 auto node =
context_->moveit_cpp_->getNode();
68 execute_action_server_ = rclcpp_action::create_server<MGAction>(
70 [](
const rclcpp_action::GoalUUID& ,
const std::shared_ptr<const MGAction::Goal>& ) {
71 RCLCPP_INFO(
getLogger(),
"MoveGroupMoveAction: Received request");
72 return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
74 [
this](
const std::shared_ptr<MGActionGoal>& ) {
75 RCLCPP_INFO(
getLogger(),
"MoveGroupMoveAction: Received request to cancel goal");
76 preemptMoveCallback();
77 return rclcpp_action::CancelResponse::ACCEPT;
79 [
this](
const std::shared_ptr<MGActionGoal>& goal) {
80 std::thread{ [
this](
const std::shared_ptr<move_group::MGActionGoal>& goal) { executeMoveCallback(goal); }, goal }
85void MoveGroupMoveAction::executeMoveCallback(
const std::shared_ptr<MGActionGoal>& goal)
91 auto node =
context_->moveit_cpp_->getNode();
92 context_->planning_scene_monitor_->waitForCurrentRobotState(node->get_clock()->now());
93 context_->planning_scene_monitor_->updateFrameTransforms();
95 auto action_res = std::make_shared<MGAction::Result>();
96 if (goal->get_goal()->planning_options.plan_only || !
context_->allow_trajectory_execution_)
98 if (!goal->get_goal()->planning_options.plan_only)
100 RCLCPP_WARN(
getLogger(),
"This instance of MoveGroup is not allowed to execute trajectories "
101 "but the goal request has plan_only set to false. "
102 "Only a motion plan will be computed anyway.");
104 executeMoveCallbackPlanOnly(goal, action_res);
108 executeMoveCallbackPlanAndExecute(goal, action_res);
114 goal->get_goal()->planning_options.plan_only));
115 if (action_res->error_code.val == moveit_msgs::msg::MoveItErrorCodes::SUCCESS)
117 goal->succeed(action_res);
119 else if (action_res->error_code.val == moveit_msgs::msg::MoveItErrorCodes::PREEMPTED)
121 goal->canceled(action_res);
125 goal->abort(action_res);
128 setMoveState(
IDLE, goal_);
129 preempt_requested_ =
false;
133void MoveGroupMoveAction::executeMoveCallbackPlanAndExecute(
const std::shared_ptr<MGActionGoal>& goal,
134 std::shared_ptr<MGAction::Result>& action_res)
136 RCLCPP_INFO(
getLogger(),
"Combined planning and execution request received for MoveGroup action. "
137 "Forwarding to planning and execution pipeline.");
141 planning_scene_monitor::LockedPlanningSceneRO lscene(
context_->planning_scene_monitor_);
142 const moveit::core::RobotState& current_state = lscene->getCurrentState();
145 for (std::size_t i = 0; i < goal->get_goal()->request.goal_constraints.size(); ++i)
147 if (lscene->isStateConstrained(
149 goal->get_goal()->request.path_constraints)))
151 RCLCPP_INFO(
getLogger(),
"Goal constraints are already satisfied. No need to plan or execute any motions");
152 action_res->error_code.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
158 plan_execution::PlanExecution::Options opt;
160 const moveit_msgs::msg::MotionPlanRequest& motion_plan_request =
163 const moveit_msgs::msg::PlanningScene& planning_scene_diff =
165 goal->get_goal()->planning_options.planning_scene_diff :
168 opt.
replan = goal->get_goal()->planning_options.replan;
169 opt.
replan_attemps = goal->get_goal()->planning_options.replan_attempts;
170 opt.
replan_delay = goal->get_goal()->planning_options.replan_delay;
173 opt.
plan_callback = [
this, &motion_plan_request](plan_execution::ExecutableMotionPlan&
plan) {
174 return planUsingPlanningPipeline(motion_plan_request, plan);
177 plan_execution::ExecutableMotionPlan
plan;
178 if (preempt_requested_)
180 RCLCPP_INFO(
getLogger(),
"Preempt requested before the goal is planned and executed.");
181 action_res->error_code.val = moveit_msgs::msg::MoveItErrorCodes::PREEMPTED;
185 context_->plan_execution_->planAndExecute(plan, planning_scene_diff, opt);
187 convertToMsg(
plan.plan_components, action_res->trajectory_start, action_res->planned_trajectory);
188 if (
plan.executed_trajectory)
189 plan.executed_trajectory->getRobotTrajectoryMsg(action_res->executed_trajectory);
193void MoveGroupMoveAction::executeMoveCallbackPlanOnly(
const std::shared_ptr<MGActionGoal>& goal,
194 std::shared_ptr<MGAction::Result>& action_res)
196 RCLCPP_INFO(
getLogger(),
"Planning request received for MoveGroup action. Forwarding to planning pipeline.");
198 planning_interface::MotionPlanResponse res;
200 if (preempt_requested_)
202 RCLCPP_INFO(
getLogger(),
"Preempt requested before the goal is planned.");
203 action_res->error_code.val = moveit_msgs::msg::MoveItErrorCodes::PREEMPTED;
208 const planning_pipeline::PlanningPipelinePtr planning_pipeline =
210 if (!planning_pipeline)
212 action_res->error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
219 context_->planning_scene_monitor_->copyPlanningScene(goal->get_goal()->planning_options.planning_scene_diff);
220 if (!planning_pipeline->generatePlan(scene, goal->get_goal()->request, res,
context_->debug_))
222 RCLCPP_ERROR(
getLogger(),
"Generating a plan with planning pipeline failed.");
223 res.
error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
226 catch (std::exception& ex)
228 RCLCPP_ERROR(
getLogger(),
"Planning pipeline threw an exception: %s", ex.what());
229 res.
error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
238 plan_execution::ExecutableMotionPlan& plan)
243 planning_interface::MotionPlanResponse res;
247 if (!planning_pipeline)
249 res.
error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
255 solved = planning_pipeline->generatePlan(
plan.copyPlanningScene(), req, res,
context_->debug_);
257 catch (std::exception& ex)
259 RCLCPP_ERROR(
getLogger(),
"Planning pipeline threw an exception: %s", ex.what());
260 res.
error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
264 plan.plan_components.resize(1);
266 plan.plan_components[0].description =
"plan";
273void MoveGroupMoveAction::startMoveExecutionCallback()
278void MoveGroupMoveAction::startMoveLookCallback()
280 setMoveState(
LOOK, goal_);
283void MoveGroupMoveAction::preemptMoveCallback()
285 preempt_requested_ =
true;
289void MoveGroupMoveAction::setMoveState(
MoveGroupState state,
const std::shared_ptr<MGActionGoal>& goal)
295 auto move_feedback = std::make_shared<MGAction::Feedback>();
297 goal->publish_feedback(move_feedback);
302#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(cached_ik_kinematics_plugin::CachedIKKinematicsPlugin< kdl_kinematics_plugin::KDLKinematicsPlugin >, kinematics::KinematicsBase)
moveit_msgs::msg::PlanningScene clearSceneRobotState(const moveit_msgs::msg::PlanningScene &scene) const
planning_interface::MotionPlanRequest clearRequestStartState(const planning_interface::MotionPlanRequest &request) const
void convertToMsg(const std::vector< plan_execution::ExecutableTrajectory > &trajectory, moveit_msgs::msg::RobotState &first_state_msg, std::vector< moveit_msgs::msg::RobotTrajectory > &trajectory_msg) const
MoveGroupContextPtr context_
std::string getActionResultString(const moveit_msgs::msg::MoveItErrorCodes &error_code, bool planned_trajectory_empty, bool plan_only)
std::string stateToStr(MoveGroupState state) const
planning_pipeline::PlanningPipelinePtr resolvePlanningPipeline(const std::string &pipeline_id) const
MoveGroupCapability(const std::string &capability_name)
void initialize() override
moveit_msgs::msg::Constraints mergeConstraints(const moveit_msgs::msg::Constraints &first, const moveit_msgs::msg::Constraints &second)
Merge two sets of constraints into one.
bool isEmpty(const moveit_msgs::msg::PlanningScene &msg)
Check if a message includes any information about a planning scene, or whether it is empty.
planning_interface::MotionPlanResponse plan(std::shared_ptr< moveit_cpp::PlanningComponent > &planning_component, std::shared_ptr< moveit_cpp::PlanningComponent::PlanRequestParameters > &single_plan_parameters, std::shared_ptr< moveit_cpp::PlanningComponent::MultiPipelinePlanRequestParameters > &multi_plan_parameters, std::shared_ptr< planning_scene::PlanningScene > &planning_scene, std::optional< const moveit::planning_pipeline_interfaces::SolutionSelectionFunction > solution_selection_function, std::optional< moveit::planning_pipeline_interfaces::StoppingCriterionFunction > stopping_criterion_callback)
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
bool isTrajectoryEmpty(const moveit_msgs::msg::RobotTrajectory &trajectory)
Checks if a robot trajectory is empty.
double replan_delay
The amount of time to wait in between replanning attempts (in seconds).
unsigned int replan_attemps
ExecutableMotionPlanComputationFn plan_callback
Callback for computing motion plans. This callback must always be specified.
std::function< void()> before_execution_callback_
bool replan
Flag indicating whether replanning is allowed.
moveit::core::MoveItErrorCode error_code
robot_trajectory::RobotTrajectoryPtr trajectory
rclcpp::Logger getLogger()