The Trajectory Execution Manager
Bits of code in MoveIt! that need to deal with execution of trajectories use a helper class: the trajectory execution manager. Given a moveit_msgs::RobotTrajectory message, the trajectory execution manager is used to pass the moveit_msgs::RobotTrajectory message to a MoveIt! Controller Manager Plugin implemented as above (the plugin specified under the ROS parameter ~/moveit_controller_manager is loaded by the trajectory execution manager).
First, the set of joints that need to be moved is identified by inspecting the moveit_msgs::RobotTrajectory message to be forwarded to the MoveIt! Controller Manager plugin.
Given the set of joints to be actuated, the MoveIt! Controller Manager plugin is queried for the known controllers, and the joints each of those controllers operates on, to identify the controller moving fewest degrees of freedom that still covers all the joints that need to be actuated.
- If no such controller is identified, a set of controllers that covers the joints to be actuated is identified. If this also fails, execution of the trajectory fails.
Given a set of controllers to be used (in parallel), the input moveit_msgs::RobotTrajectory message is split into multiple moveit_msgs::RobotTrajectory messages (if needed) such that each controller to be used receives a request for execution only for joints it actuates.
Handles for controllers are constructed using the MoveIt! Controller Manager plugin for each of the controllers that are about to be sent trajectories. If any handle fails to initialize, the trajectory fails to execute.
The constructed controller handles receive the moveit_msgs::RobotTrajectory messages that are to be executed.
The trajectory execution manager waits for the amount of time declared by moveit_msgs::RobotTrajectory for the execution to complete. If that time is exceeded by a significant margin (more than 10% longer), the execution is cancelled. This behaviour can be disabled by calling enableExecutionDurationMonitoring(false) for the trajectory execution manager instance or by setting the ROS parameter ~/execution_duration_monitoring (e.g., as part of the move_group node). To scale the amount of time to wait (e.g., more than 10%), the setAllowedExecutionDurationScaling() function can be called or the ROS parameter ~/allowed_execution_duration_scaling can be set.