moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
plan_execution.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2012, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Ioan Sucan */
36
37#include <cstdint>
44#include <boost/algorithm/string/join.hpp>
45#include <rclcpp/logger.hpp>
46#include <rclcpp/logging.hpp>
47#include <rclcpp/node.hpp>
48#include <rclcpp/parameter_value.hpp>
49#include <rclcpp/rate.hpp>
50#include <rclcpp/utilities.hpp>
52
53// #include <dynamic_reconfigure/server.h>
54// #include <moveit_ros_planning/PlanExecutionDynamicReconfigureConfig.hpp>
55
56namespace plan_execution
57{
58
59// class PlanExecution::DynamicReconfigureImpl
60// {
61// public:
62// DynamicReconfigureImpl(PlanExecution* owner)
63// : owner_(owner) //, dynamic_reconfigure_server_(ros::NodeHandle("~/plan_execution"))
64// {
65// // dynamic_reconfigure_server_.setCallback(
66// // [this](const auto& config, uint32_t level) { dynamicReconfigureCallback(config, level); });
67// }
68//
69// private:
70// // void dynamicReconfigureCallback(const PlanExecutionDynamicReconfigureConfig& config, uint32_t level)
71// // {
72// // owner_->setMaxReplanAttempts(config.max_replan_attempts);
73// // owner_->setTrajectoryStateRecordingFrequency(config.record_trajectory_state_frequency);
74// // }
75//
76// PlanExecution* owner_;
77// // dynamic_reconfigure::Server<PlanExecutionDynamicReconfigureConfig> dynamic_reconfigure_server_;
78// };
79} // namespace plan_execution
80
82 const rclcpp::Node::SharedPtr& node, const planning_scene_monitor::PlanningSceneMonitorPtr& planning_scene_monitor,
83 const trajectory_execution_manager::TrajectoryExecutionManagerPtr& trajectory_execution)
84 : node_(node)
85 , planning_scene_monitor_(planning_scene_monitor)
86 , trajectory_execution_manager_(trajectory_execution)
87 , logger_(moveit::getLogger("moveit.ros.plan_execution"))
88{
89 if (!trajectory_execution_manager_)
90 {
91 trajectory_execution_manager_ = std::make_shared<trajectory_execution_manager::TrajectoryExecutionManager>(
92 node_, planning_scene_monitor_->getRobotModel(), planning_scene_monitor_->getStateMonitor());
93 }
94
95 default_max_replan_attempts_ = 5;
96
97 new_scene_update_ = false;
98
99 // we want to be notified when new information is available
100 planning_scene_monitor_->addUpdateCallback(
102 planningSceneUpdatedCallback(update_type);
103 });
104
105 // start the dynamic-reconfigure server
106 // reconfigure_impl_ = new DynamicReconfigureImpl(this);
107}
108
110{
111 // delete reconfigure_impl_;
112}
113
115{
116 preempt_.request();
117}
118
120{
121 plan.planning_scene_monitor = planning_scene_monitor_;
122 plan.planning_scene = planning_scene_monitor_->getPlanningScene();
123 planAndExecuteHelper(plan, opt);
124}
125
127 const moveit_msgs::msg::PlanningScene& scene_diff,
128 const Options& opt)
129{
130 if (moveit::core::isEmpty(scene_diff))
131 {
132 planAndExecute(plan, opt);
133 }
134 else
135 {
136 plan.planning_scene_monitor = planning_scene_monitor_;
137 {
138 planning_scene_monitor::LockedPlanningSceneRO lscene(planning_scene_monitor_); // lock the scene so that it does
139 // not modify the world
140 // representation while diff() is
141 // called
142 plan.planning_scene = lscene->diff(scene_diff);
143 }
144 planAndExecuteHelper(plan, opt);
145 }
146}
147
148void plan_execution::PlanExecution::planAndExecuteHelper(ExecutableMotionPlan& plan, const Options& opt)
149{
150 // perform initial configuration steps & various checks
151 preempt_.checkAndClear(); // clear any previous preempt_ request
152
153 bool preempt_requested = false;
154
155 // run the actual motion plan & execution
156 unsigned int max_replan_attempts =
157 opt.replan ? (opt.replan_attemps > 0 ? opt.replan_attemps : default_max_replan_attempts_) : 1;
158 unsigned int replan_attempts = 0;
159 bool previously_solved = false;
160
161 // run a planning loop for at most the maximum replanning attempts;
162 // re-planning is executed only in case of known types of failures (e.g., environment changed)
163 do
164 {
165 replan_attempts++;
166 RCLCPP_INFO(logger_, "Planning attempt %u of at most %u", replan_attempts, max_replan_attempts);
167
168 if (opt.before_plan_callback_)
169 opt.before_plan_callback_();
170
171 new_scene_update_ = false; // we clear any scene updates to be evaluated because we are about to compute a new
172 // plan, which should consider most recent updates already
173
174 // if we never had a solved plan, or there is no specified way of fixing plans, just call the planner; otherwise,
175 // try to repair the plan we previously had;
176 bool solved =
177 (!previously_solved || !opt.repair_plan_callback_) ?
178 opt.plan_callback(plan) :
179 opt.repair_plan_callback_(plan, trajectory_execution_manager_->getCurrentExpectedTrajectoryIndex());
180
181 preempt_requested = preempt_.checkAndClear();
182 if (preempt_requested)
183 break;
184
185 // if planning fails in a manner that is not recoverable, we exit the loop,
186 // otherwise, we attempt to continue, if replanning attempts are left
187 if (plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::PLANNING_FAILED ||
188 plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::INVALID_MOTION_PLAN ||
189 plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::UNABLE_TO_AQUIRE_SENSOR_DATA)
190 {
191 if (plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::UNABLE_TO_AQUIRE_SENSOR_DATA &&
192 opt.replan_delay > 0.0)
193 {
194 auto replan_delay_seconds = std::chrono::duration<double>(opt.replan_delay);
195 rclcpp::sleep_for(std::chrono::duration_cast<std::chrono::nanoseconds>(replan_delay_seconds));
196 }
197 continue;
198 }
199
200 // abort if no plan was found
201 if (solved)
202 {
203 previously_solved = true;
204 }
205 else
206 {
207 break;
208 }
209
210 if (plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::SUCCESS)
211 {
212 if (opt.before_execution_callback_)
213 opt.before_execution_callback_();
214
215 preempt_requested = preempt_.checkAndClear();
216 if (preempt_requested)
217 break;
218
219 // execute the trajectory, and monitor its execution
220 plan.error_code = executeAndMonitor(plan, false);
221 }
222
223 if (plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::PREEMPTED)
224 preempt_requested = true;
225
226 // if execution succeeded or failed in a manner that we do not consider recoverable, we exit the loop (with failure)
227 if (plan.error_code.val != moveit_msgs::msg::MoveItErrorCodes::MOTION_PLAN_INVALIDATED_BY_ENVIRONMENT_CHANGE)
228 {
229 break;
230 }
231 else
232 {
233 // otherwise, we wait (if needed)
234 if (opt.replan_delay > 0.0)
235 {
236 RCLCPP_INFO(logger_, "Waiting for a %lf seconds before attempting a new plan ...", opt.replan_delay);
237 auto replan_delay_seconds = std::chrono::duration<double>(opt.replan_delay);
238 rclcpp::sleep_for(std::chrono::duration_cast<std::chrono::nanoseconds>(replan_delay_seconds));
239 RCLCPP_INFO(logger_, "Done waiting");
240 }
241 }
242
243 preempt_requested = preempt_.checkAndClear();
244 if (preempt_requested)
245 break;
246
247 } while (replan_attempts < max_replan_attempts);
248
249 if (preempt_requested)
250 {
251 RCLCPP_DEBUG(logger_, "PlanExecution was preempted");
252 plan.error_code.val = moveit_msgs::msg::MoveItErrorCodes::PREEMPTED;
253 }
254
255 if (opt.done_callback_)
256 opt.done_callback_();
257
258 if (plan.error_code.val == moveit_msgs::msg::MoveItErrorCodes::SUCCESS)
259 {
260 RCLCPP_DEBUG(logger_, "PlanExecution finished successfully.");
261 }
262 else
263 {
264 RCLCPP_DEBUG(logger_, "PlanExecution terminating with error code %d - '%s'", plan.error_code.val,
266 }
267}
268
269bool plan_execution::PlanExecution::isRemainingPathValid(const ExecutableMotionPlan& plan,
270 const std::pair<int, int>& path_segment)
271{
272 if (path_segment.first >= 0 &&
273 plan.plan_components[path_segment.first].trajectory_monitoring) // If path_segment.second <= 0, the function
274 // will fallback to check the entire trajectory
275 {
276 planning_scene_monitor::LockedPlanningSceneRO lscene(plan.planning_scene_monitor); // lock the scene so that it
277 // does not modify the world
278 // representation while
279 // isStateValid() is called
280 const robot_trajectory::RobotTrajectory& t = *plan.plan_components[path_segment.first].trajectory;
281 const collision_detection::AllowedCollisionMatrix* acm =
282 plan.plan_components[path_segment.first].allowed_collision_matrix.get();
283 std::size_t wpc = t.getWayPointCount();
284 collision_detection::CollisionRequest req;
285 req.group_name = t.getGroupName();
286 req.pad_environment_collisions = false;
287 moveit::core::RobotState start_state = plan.planning_scene->getCurrentState();
288 std::map<std::string, const moveit::core::AttachedBody*> current_attached_objects, waypoint_attached_objects;
289 start_state.getAttachedBodies(current_attached_objects);
290 if (plan_components_attached_objects_.size() > static_cast<size_t>(path_segment.first))
291 waypoint_attached_objects = plan_components_attached_objects_[path_segment.first];
292 moveit::core::RobotState waypoint_state(start_state);
293 for (std::size_t i = std::max(path_segment.second - 1, 0); i < wpc; ++i)
294 {
295 collision_detection::CollisionResult res;
296 waypoint_attached_objects.clear(); // clear out the last waypoints attached objects
297 waypoint_state = t.getWayPoint(i);
298 if (plan_components_attached_objects_[path_segment.first].empty())
299 {
300 waypoint_state.getAttachedBodies(waypoint_attached_objects);
301 }
302
303 // If sample state has attached objects that are not in the current state, remove them from the sample state
304 for (const auto& [name, object] : waypoint_attached_objects)
305 {
306 if (current_attached_objects.find(name) == current_attached_objects.end())
307 {
308 RCLCPP_DEBUG(logger_, "Attached object '%s' is not in the current scene. Removing it.", name.c_str());
309 waypoint_state.clearAttachedBody(name);
310 }
311 }
312
313 // If current state has attached objects that are not in the sample state, add them to the sample state
314 for (const auto& [name, object] : current_attached_objects)
315 {
316 if (waypoint_attached_objects.find(name) == waypoint_attached_objects.end())
317 {
318 RCLCPP_DEBUG(logger_, "Attached object '%s' is not in the robot state. Adding it.", name.c_str());
319 waypoint_state.attachBody(std::make_unique<moveit::core::AttachedBody>(*object));
320 }
321 }
322
323 if (acm)
324 {
325 plan.planning_scene->checkCollision(req, res, waypoint_state, *acm);
326 }
327 else
328 {
329 plan.planning_scene->checkCollision(req, res, waypoint_state);
330 }
331
332 if (res.collision || !plan.planning_scene->isStateFeasible(waypoint_state, false))
333 {
334 RCLCPP_INFO(logger_, "Trajectory component '%s' is invalid for waypoint %ld out of %ld",
335 plan.plan_components[path_segment.first].description.c_str(), i, wpc);
336
337 // call the same functions again, in verbose mode, to show what issues have been detected
338 plan.planning_scene->isStateFeasible(waypoint_state, true);
339 req.verbose = true;
340 res.clear();
341 if (acm)
342 {
343 plan.planning_scene->checkCollision(req, res, waypoint_state, *acm);
344 }
345 else
346 {
347 plan.planning_scene->checkCollision(req, res, waypoint_state);
348 }
349 return false;
350 }
351 }
352 }
353 return true;
354}
355
357 bool reset_preempted)
358{
359 if (reset_preempted)
360 preempt_.checkAndClear();
361
362 if (!plan.planning_scene_monitor)
363 plan.planning_scene_monitor = planning_scene_monitor_;
364 if (!plan.planning_scene)
365 plan.planning_scene = planning_scene_monitor_->getPlanningScene();
366
367 moveit_msgs::msg::MoveItErrorCodes result;
368
369 // try to execute the trajectory
370 execution_complete_ = true;
371
372 if (!trajectory_execution_manager_)
373 {
374 RCLCPP_ERROR(logger_, "No trajectory execution manager");
375 result.val = moveit_msgs::msg::MoveItErrorCodes::CONTROL_FAILED;
376 return result;
377 }
378
379 if (plan.plan_components.empty())
380 {
381 result.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
382 return result;
383 }
384
385 execution_complete_ = false;
386
387 // push the trajectories we have slated for execution to the trajectory execution manager
388 int prev = -1;
389 for (size_t component_idx = 0; component_idx < plan.plan_components.size(); ++component_idx)
390 {
391 // \todo should this be in trajectory_execution ? Maybe. Then that will have to use kinematic_trajectory too;
392 // splitting trajectories for controllers becomes interesting: tied to groups instead of joints. this could cause
393 // some problems
394 // in the meantime we do a hack:
395
396 bool unwound = false;
397 for (int prev_component = component_idx - 1; prev_component >= 0; --prev_component)
398 {
399 // Search backward for a previous component having the same group.
400 // If the group is the same, unwind this component based on the last waypoint of the previous one.
401 if (plan.plan_components.at(prev_component).trajectory &&
402 plan.plan_components.at(prev_component).trajectory->getGroup() ==
403 plan.plan_components.at(prev_component).trajectory->getGroup() &&
404 !plan.plan_components.at(prev_component).trajectory->empty())
405 {
406 plan.plan_components.at(component_idx)
407 .trajectory->unwind(plan.plan_components.at(prev_component).trajectory->getLastWayPoint());
408 unwound = true;
409 // Break so each component is only unwound once
410 break;
411 }
412 }
413
414 if (!unwound)
415 {
416 // unwind the path to execute based on the current state of the system
417 if (prev < 0)
418 {
419 plan.plan_components[component_idx].trajectory->unwind(
420 plan.planning_scene_monitor && plan.planning_scene_monitor->getStateMonitor() ?
421 *plan.planning_scene_monitor->getStateMonitor()->getCurrentState() :
422 plan.planning_scene->getCurrentState());
423 }
424 else
425 {
426 plan.plan_components[component_idx].trajectory->unwind(plan.plan_components[prev].trajectory->getLastWayPoint());
427 }
428 }
429
430 if (plan.plan_components[component_idx].trajectory && !plan.plan_components[component_idx].trajectory->empty())
431 prev = component_idx;
432
433 // convert to message, pass along
434 moveit_msgs::msg::RobotTrajectory msg;
435 plan.plan_components[component_idx].trajectory->getRobotTrajectoryMsg(msg);
436 if (!trajectory_execution_manager_->push(msg, plan.plan_components[component_idx].controller_name))
437 {
438 RCLCPP_ERROR(logger_, "Apparently trajectory initialization failed");
439 execution_complete_ = true;
440 result.val = moveit_msgs::msg::MoveItErrorCodes::CONTROL_FAILED;
441 return result;
442 }
443 }
444
445 if (!trajectory_monitor_ && planning_scene_monitor_->getStateMonitor())
446 {
447 // Pass current value of reconfigurable parameter plan_execution/record_trajectory_state_frequency
448 double sampling_frequency = 0.0;
449 node_->get_parameter_or("plan_execution.record_trajectory_state_frequency", sampling_frequency, 0.0);
450 trajectory_monitor_ = std::make_shared<planning_scene_monitor::TrajectoryMonitor>(
451 planning_scene_monitor_->getStateMonitor(), sampling_frequency);
452 }
453
454 // start recording trajectory states
455 if (trajectory_monitor_)
456 trajectory_monitor_->startTrajectoryMonitor();
457
458 // start a trajectory execution thread
459 trajectory_execution_manager_->execute(
460 [this](const moveit_controller_manager::ExecutionStatus& status) { doneWithTrajectoryExecution(status); },
461 [this, &plan](std::size_t index) { successfulTrajectorySegmentExecution(plan, index); });
462 // wait for path to be done, while checking that the path does not become invalid
463 rclcpp::WallRate r(100);
464 path_became_invalid_ = false;
465 bool preempt_requested = false;
466
467 // Check that attached objects remain consistent throughout the trajectory and store them.
468 // This avoids querying the scene for attached objects at each waypoint whenever possible.
469 // If a change in attached objects is detected, they will be queried at each waypoint.
470 plan_components_attached_objects_.clear();
471 plan_components_attached_objects_.reserve(plan.plan_components.size());
472 for (const auto& component : plan.plan_components)
473 {
474 const auto& trajectory = component.trajectory;
475 std::map<std::string, const moveit::core::AttachedBody*> trajectory_attached_objects;
476 if (trajectory && trajectory->getWayPointCount() > 0)
477 {
478 std::map<std::string, const moveit::core::AttachedBody*> attached_objects;
479 trajectory->getWayPoint(0).getAttachedBodies(trajectory_attached_objects);
480 for (std::size_t i = 1; i < trajectory->getWayPointCount(); ++i)
481 {
482 trajectory->getWayPoint(i).getAttachedBodies(attached_objects);
483 if (attached_objects != trajectory_attached_objects)
484 {
485 trajectory_attached_objects.clear();
486 break;
487 }
488 }
489 }
490 if (!trajectory_attached_objects.empty())
491 plan_components_attached_objects_.push_back(trajectory_attached_objects);
492 }
493
494 while (rclcpp::ok() && !execution_complete_ && !path_became_invalid_)
495 {
496 r.sleep();
497 // check the path if there was an environment update in the meantime
498 if (new_scene_update_)
499 {
500 new_scene_update_ = false;
501 std::pair<int, int> current_index = trajectory_execution_manager_->getCurrentExpectedTrajectoryIndex();
502 if (!isRemainingPathValid(plan, current_index))
503 {
504 RCLCPP_INFO(logger_, "Trajectory component '%s' is invalid after scene update",
505 plan.plan_components[current_index.first].description.c_str());
506 path_became_invalid_ = true;
507 break;
508 }
509 }
510
511 preempt_requested = preempt_.checkAndClear();
512 if (preempt_requested)
513 break;
514 }
515
516 // stop execution if needed
517 if (preempt_requested)
518 {
519 RCLCPP_INFO(logger_, "Stopping execution due to preempt request");
520 trajectory_execution_manager_->stopExecution();
521 }
522 else if (path_became_invalid_)
523 {
524 RCLCPP_INFO(logger_, "Stopping execution because the path to execute became invalid"
525 "(probably the environment changed)");
526 trajectory_execution_manager_->stopExecution();
527 }
528 else if (!execution_complete_)
529 {
530 RCLCPP_WARN(logger_, "Stopping execution due to unknown reason."
531 "Possibly the node is about to shut down.");
532 trajectory_execution_manager_->stopExecution();
533 }
534
535 // stop recording trajectory states
536 if (trajectory_monitor_)
537 {
538 trajectory_monitor_->stopTrajectoryMonitor();
539 plan.executed_trajectory =
540 std::make_shared<robot_trajectory::RobotTrajectory>(planning_scene_monitor_->getRobotModel(), "");
541 trajectory_monitor_->swapTrajectory(*plan.executed_trajectory);
542 }
543
544 // decide return value
545 if (path_became_invalid_)
546 {
547 result.val = moveit_msgs::msg::MoveItErrorCodes::MOTION_PLAN_INVALIDATED_BY_ENVIRONMENT_CHANGE;
548 }
549 else
550 {
551 if (preempt_requested)
552 {
553 result.val = moveit_msgs::msg::MoveItErrorCodes::PREEMPTED;
554 }
555 else
556 {
557 if (trajectory_execution_manager_->getLastExecutionStatus() ==
559 {
560 result.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
561 }
562 else if (trajectory_execution_manager_->getLastExecutionStatus() ==
564 {
565 result.val = moveit_msgs::msg::MoveItErrorCodes::TIMED_OUT;
566 }
567 else
568 {
569 result.val = moveit_msgs::msg::MoveItErrorCodes::CONTROL_FAILED;
570 }
571 }
572 }
573 return result;
574}
575
576void plan_execution::PlanExecution::planningSceneUpdatedCallback(
578{
581 new_scene_update_ = true;
582}
583
584void plan_execution::PlanExecution::doneWithTrajectoryExecution(
586{
587 execution_complete_ = true;
588}
589
590void plan_execution::PlanExecution::successfulTrajectorySegmentExecution(const ExecutableMotionPlan& plan,
591 std::size_t index)
592{
593 if (plan.plan_components.empty())
594 {
595 RCLCPP_WARN(logger_, "Length of provided motion plan is zero.");
596 return;
597 }
598
599 // if any side-effects are associated to the trajectory part that just completed, execute them
600 RCLCPP_DEBUG(logger_, "Completed '%s'", plan.plan_components[index].description.c_str());
601 if (plan.plan_components[index].effect_on_success)
602 {
603 if (!plan.plan_components[index].effect_on_success(&plan))
604 {
605 // execution of side-effect failed
606 RCLCPP_ERROR(logger_, "Execution of path-completion side-effect failed. Preempting.");
607 preempt_.request();
608 return;
609 }
610 }
611
612 // if there is a next trajectory, check it for validity, before we start execution
613 ++index;
614 if (index < plan.plan_components.size() && plan.plan_components[index].trajectory &&
615 !plan.plan_components[index].trajectory->empty())
616 {
617 std::pair<int, int> next_index(static_cast<int>(index), 0);
618 if (!isRemainingPathValid(plan, next_index))
619 {
620 RCLCPP_INFO(logger_, "Upcoming trajectory component '%s' is invalid",
621 plan.plan_components[next_index.first].description.c_str());
622 path_became_invalid_ = true;
623 }
624 }
625}
void getAttachedBodies(std::vector< const AttachedBody * > &attached_bodies) const
Get all bodies attached to the model corresponding to this state.
void planAndExecute(ExecutableMotionPlan &plan, const Options &opt)
PlanExecution(const rclcpp::Node::SharedPtr &node, const planning_scene_monitor::PlanningSceneMonitorPtr &planning_scene_monitor, const trajectory_execution_manager::TrajectoryExecutionManagerPtr &trajectory_execution)
moveit_msgs::msg::MoveItErrorCodes executeAndMonitor(ExecutableMotionPlan &plan, bool reset_preempted=true)
Execute and monitor a previously created plan.
This is a convenience class for obtaining access to an instance of a locked PlanningScene.
@ UPDATE_GEOMETRY
The geometry of the scene was updated. This includes receiving new octomaps, collision objects,...
@ UPDATE_TRANSFORMS
The maintained set of fixed transforms in the monitored scene was updated.
const std::string & getGroupName() const
const moveit::core::RobotState & getWayPoint(std::size_t index) const
bool isEmpty(const moveit_msgs::msg::PlanningScene &msg)
Check if a message includes any information about a planning scene, or whether it is empty.
std::string errorCodeToString(const MoveItErrorCode &error_code)
Convenience function to translated error message into string.
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)
Main namespace for MoveIt.
This namespace includes functionality specific to the execution and monitoring of motion plans.
name
Definition setup.py:7
std::string group_name
The group name to check collisions for (optional; if empty, assume the complete robot)....
bool verbose
Flag indicating whether information about detected collisions should be reported.
bool pad_environment_collisions
If true, use padded collision environment.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void clear()
Clear a previously stored result.
bool collision
True if collision was found, false otherwise.
A generic representation on what a computed motion plan looks like.
moveit::core::MoveItErrorCode error_code
robot_trajectory::RobotTrajectoryPtr trajectory