moveit2
The MoveIt Motion Planning Framework for ROS 2.
trajectory_execution_manager.h
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 #pragma once
38 
42 #include <moveit_msgs/msg/robot_trajectory.hpp>
43 #include <sensor_msgs/msg/joint_state.hpp>
44 #include <std_msgs/msg/string.hpp>
45 #include <rclcpp/rclcpp.hpp>
47 #include <pluginlib/class_loader.hpp>
48 
49 #include <memory>
50 #include <deque>
51 #include <thread>
52 
53 #include <moveit_trajectory_execution_manager_export.h>
54 
56 {
57 MOVEIT_CLASS_FORWARD(TrajectoryExecutionManager); // Defines TrajectoryExecutionManagerPtr, ConstPtr, WeakPtr... etc
58 
59 // Two modes:
60 // Managed controllers
61 // Unmanaged controllers: given the trajectory,
62 class MOVEIT_TRAJECTORY_EXECUTION_MANAGER_EXPORT TrajectoryExecutionManager
63 {
64 public:
65  static const std::string EXECUTION_EVENT_TOPIC;
66 
70 
73  using PathSegmentCompleteCallback = std::function<void(std::size_t)>;
74 
77  {
79  std::vector<std::string> controllers_;
80 
81  // The trajectory to execute, split in different parts (by joints), each set of joints corresponding to one
82  // controller
83  std::vector<moveit_msgs::msg::RobotTrajectory> trajectory_parts_;
84  };
85 
87  TrajectoryExecutionManager(const rclcpp::Node::SharedPtr& node, const moveit::core::RobotModelConstPtr& robot_model,
88  const planning_scene_monitor::CurrentStateMonitorPtr& csm);
89 
91  TrajectoryExecutionManager(const rclcpp::Node::SharedPtr& node, const moveit::core::RobotModelConstPtr& robot_model,
92  const planning_scene_monitor::CurrentStateMonitorPtr& csm, bool manage_controllers);
93 
96 
98  bool isManagingControllers() const;
99 
101  const moveit_controller_manager::MoveItControllerManagerPtr& getControllerManager() const;
102 
104  void processEvent(const std::string& event);
105 
110  bool ensureActiveControllersForGroup(const std::string& group);
111 
116  bool ensureActiveControllersForJoints(const std::vector<std::string>& joints);
117 
121  bool ensureActiveController(const std::string& controller);
122 
126  bool ensureActiveControllers(const std::vector<std::string>& controllers);
127 
129  bool isControllerActive(const std::string& controller);
130 
132  bool areControllersActive(const std::vector<std::string>& controllers);
133 
136  bool push(const moveit_msgs::msg::RobotTrajectory& trajectory, const std::string& controller = "");
137 
140  bool push(const trajectory_msgs::msg::JointTrajectory& trajectory, const std::string& controller = "");
141 
147  bool push(const trajectory_msgs::msg::JointTrajectory& trajectory, const std::vector<std::string>& controllers);
148 
154  bool push(const moveit_msgs::msg::RobotTrajectory& trajectory, const std::vector<std::string>& controllers);
155 
157  const std::vector<TrajectoryExecutionContext*>& getTrajectories() const;
158 
160  void execute(const ExecutionCompleteCallback& callback = ExecutionCompleteCallback(), bool auto_clear = true);
161 
164  void execute(const ExecutionCompleteCallback& callback, const PathSegmentCompleteCallback& part_callback,
165  bool auto_clear = true);
166 
169  moveit_controller_manager::ExecutionStatus executeAndWait(bool auto_clear = true);
170 
174 
181  std::pair<int, int> getCurrentExpectedTrajectoryIndex() const;
182 
184  moveit_controller_manager::ExecutionStatus getLastExecutionStatus() const;
185 
187  void stopExecution(bool auto_clear = true);
188 
190  void clear();
191 
194  void enableExecutionDurationMonitoring(bool flag);
195 
198  void setAllowedExecutionDurationScaling(double scaling);
199 
202  void setAllowedGoalDurationMargin(double margin);
203 
206  void setExecutionVelocityScaling(double scaling);
207 
209  void setAllowedStartTolerance(double tolerance);
210 
212  void setWaitForTrajectoryCompletion(bool flag);
213 
214  rclcpp::Node::SharedPtr getControllerManagerNode()
215  {
216  return controller_mgr_node_;
217  }
218 
219 private:
220  struct ControllerInformation
221  {
222  std::string name_;
223  std::set<std::string> joints_;
224  std::set<std::string> overlapping_controllers_;
226  rclcpp::Time last_update_{ 0, 0, RCL_ROS_TIME };
227 
228  bool operator<(ControllerInformation& other) const
229  {
230  if (joints_.size() != other.joints_.size())
231  return joints_.size() < other.joints_.size();
232  return name_ < other.name_;
233  }
234  };
235 
236  void initialize();
237 
238  void reloadControllerInformation();
239 
241  bool validate(const TrajectoryExecutionContext& context) const;
242  bool configure(TrajectoryExecutionContext& context, const moveit_msgs::msg::RobotTrajectory& trajectory,
243  const std::vector<std::string>& controllers);
244 
245  void updateControllersState(const rclcpp::Duration& age);
246  void updateControllerState(const std::string& controller, const rclcpp::Duration& age);
247  void updateControllerState(ControllerInformation& ci, const rclcpp::Duration& age);
248 
249  bool distributeTrajectory(const moveit_msgs::msg::RobotTrajectory& trajectory,
250  const std::vector<std::string>& controllers,
251  std::vector<moveit_msgs::msg::RobotTrajectory>& parts);
252 
253  bool findControllers(const std::set<std::string>& actuated_joints, std::size_t controller_count,
254  const std::vector<std::string>& available_controllers,
255  std::vector<std::string>& selected_controllers);
256  bool checkControllerCombination(std::vector<std::string>& controllers, const std::set<std::string>& actuated_joints);
257  void generateControllerCombination(std::size_t start_index, std::size_t controller_count,
258  const std::vector<std::string>& available_controllers,
259  std::vector<std::string>& selected_controllers,
260  std::vector<std::vector<std::string> >& selected_options,
261  const std::set<std::string>& actuated_joints);
262  bool selectControllers(const std::set<std::string>& actuated_joints,
263  const std::vector<std::string>& available_controllers,
264  std::vector<std::string>& selected_controllers);
265 
266  void executeThread(const ExecutionCompleteCallback& callback, const PathSegmentCompleteCallback& part_callback,
267  bool auto_clear);
268  bool executePart(std::size_t part_index);
269  bool waitForRobotToStop(const TrajectoryExecutionContext& context, double wait_time = 1.0);
270 
271  void stopExecutionInternal();
272 
273  void receiveEvent(const std_msgs::msg::String::ConstSharedPtr& event);
274 
275  void loadControllerParams();
276 
277  // Name of this class for logging
278  const std::string name_ = "trajectory_execution_manager";
279 
280  rclcpp::Node::SharedPtr node_;
281  rclcpp::Logger logger_;
282  rclcpp::Node::SharedPtr controller_mgr_node_;
283  std::shared_ptr<rclcpp::executors::SingleThreadedExecutor> private_executor_;
284  std::thread private_executor_thread_;
285  moveit::core::RobotModelConstPtr robot_model_;
286  planning_scene_monitor::CurrentStateMonitorPtr csm_;
287  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr event_topic_subscriber_;
288  std::map<std::string, ControllerInformation> known_controllers_;
289  bool manage_controllers_;
290 
291  // thread used to execute trajectories using the execute() command
292  std::unique_ptr<std::thread> execution_thread_;
293 
294  std::mutex execution_state_mutex_;
295  std::mutex execution_thread_mutex_;
296 
297  // this condition is used to notify the completion of execution for given trajectories
298  std::condition_variable execution_complete_condition_;
299 
300  moveit_controller_manager::ExecutionStatus last_execution_status_;
301  std::vector<moveit_controller_manager::MoveItControllerHandlePtr> active_handles_;
302  int current_context_;
303  std::vector<rclcpp::Time> time_index_; // used to find current expected trajectory location
304  mutable std::mutex time_index_mutex_;
305  bool execution_complete_;
306 
307  std::vector<TrajectoryExecutionContext*> trajectories_;
308 
309  std::unique_ptr<pluginlib::ClassLoader<moveit_controller_manager::MoveItControllerManager> > controller_manager_loader_;
310  moveit_controller_manager::MoveItControllerManagerPtr controller_manager_;
311 
312  bool verbose_;
313 
314  bool execution_duration_monitoring_;
315  // 'global' values
316  double allowed_execution_duration_scaling_;
317  double allowed_goal_duration_margin_;
318  // controller-specific values
319  // override the 'global' values
320  std::map<std::string, double> controller_allowed_execution_duration_scaling_;
321  std::map<std::string, double> controller_allowed_goal_duration_margin_;
322 
323  double allowed_start_tolerance_; // joint tolerance for validate(): radians for revolute joints
324  double execution_velocity_scaling_;
325  bool wait_for_trajectory_completion_;
326 
327  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr callback_handler_;
328 };
329 } // namespace trajectory_execution_manager
std::function< void(const moveit_controller_manager::ExecutionStatus &)> ExecutionCompleteCallback
std::vector< std::vector< std::string > > selected_options
MOVEIT_CLASS_FORWARD(TrajectoryExecutionManager)
Each controller known to MoveIt has a state. This structure describes that controller's state.
Data structure that represents information necessary to execute a trajectory.
std::vector< std::string > controllers_
The controllers to use for executing the different trajectory parts;.