moveit2
The MoveIt Motion Planning Framework for ROS 2.
local_planner_component.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2020, PickNik 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 PickNik Inc. 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: Sebastian Jahr
36  Description: A local planner component node that is customizable through plugins that implement the local planning
37  problem solver algorithm and the trajectory matching and blending.
38  */
39 
40 #pragma once
41 
42 #include <rclcpp/rclcpp.hpp>
43 #include <rclcpp_action/rclcpp_action.hpp>
44 
45 #include <pluginlib/class_loader.hpp>
46 
47 #include <moveit_msgs/action/local_planner.hpp>
48 #include <moveit_msgs/msg/motion_plan_response.hpp>
49 #include <moveit_msgs/msg/robot_trajectory.hpp>
50 
51 #include <std_msgs/msg/float64.hpp>
52 #include <std_msgs/msg/float64_multi_array.hpp>
53 
54 #include <trajectory_msgs/msg/joint_trajectory.hpp>
55 
60 
61 #include <tf2_ros/buffer.h>
62 #include <tf2_ros/transform_listener.h>
63 
65 {
66 // TODO(sjahr) Refactor and use repository wide solution
67 template <typename T>
68 void declareOrGetParam(const std::string& param_name, T& output_value, const T& default_value,
69  const rclcpp::Node::SharedPtr& node)
70 {
71  try
72  {
73  if (node->has_parameter(param_name))
74  node->get_parameter<T>(param_name, output_value);
75  else
76  output_value = node->declare_parameter<T>(param_name, default_value);
77  }
78  catch (const rclcpp::exceptions::InvalidParameterTypeException& e)
79  {
80  RCLCPP_ERROR_STREAM(node->get_logger(),
81  "Error getting parameter '" << param_name << "', check parameter type in YAML file");
82  throw e;
83  }
84 }
85 
88 enum class LocalPlannerState : int8_t
89 {
90  ABORT = -1,
91  ERROR = 0,
92  UNCONFIGURED = 1,
95 };
96 
101 {
102 public:
105  {
106  void load(const rclcpp::Node::SharedPtr& node)
107  {
108  std::string undefined = "<undefined>";
109  declareOrGetParam<std::string>("group_name", group_name, undefined, node);
110  declareOrGetParam<std::string>("trajectory_operator_plugin_name", trajectory_operator_plugin_name, undefined,
111  node);
112  declareOrGetParam<std::string>("local_constraint_solver_plugin_name", local_constraint_solver_plugin_name,
113  undefined, node);
114  declareOrGetParam<std::string>("local_planning_action_name", local_planning_action_name, undefined, node);
115  declareOrGetParam<double>("local_planning_frequency", local_planning_frequency, 1.0, node);
116  declareOrGetParam<std::string>("global_solution_topic", global_solution_topic, undefined, node);
117  declareOrGetParam<std::string>("local_solution_topic", local_solution_topic, undefined, node);
118  declareOrGetParam<std::string>("local_solution_topic_type", local_solution_topic_type, undefined, node);
119  declareOrGetParam<bool>("publish_joint_positions", publish_joint_positions, false, node);
120  declareOrGetParam<bool>("publish_joint_velocities", publish_joint_velocities, false, node);
121  // Planning scene monitor options
122  declareOrGetParam<std::string>("monitored_planning_scene", monitored_planning_scene_topic, undefined, node);
123  declareOrGetParam<std::string>("collision_object_topic", collision_object_topic, undefined, node);
124  declareOrGetParam<std::string>("joint_states_topic", joint_states_topic, undefined, node);
125  }
126 
127  std::string group_name;
128  std::string robot_description;
135  std::string local_solution_topic;
142  std::string joint_states_topic;
143  };
144 
146  LocalPlannerComponent(const rclcpp::NodeOptions& options);
147 
150  {
151  // Join the thread used for long-running callbacks
152  if (long_callback_thread_.joinable())
153  {
154  long_callback_thread_.join();
155  }
156  }
157 
164  bool initialize();
165 
169  void executeIteration();
170 
171  // This function is required to make this class a valid NodeClass
172  // see https://docs.ros2.org/foxy/api/rclcpp_components/register__node__macro_8hpp.html
173  rclcpp::node_interfaces::NodeBaseInterface::SharedPtr get_node_base_interface() // NOLINT
174  {
175  return node_->get_node_base_interface(); // NOLINT
176  }
177 
178 private:
180  void reset();
181 
182  std::shared_ptr<rclcpp::Node> node_;
183 
184  // Planner configuration
185  LocalPlannerConfig config_;
186 
187  // Current planner state. Must be thread-safe
188  std::atomic<LocalPlannerState> state_;
189 
190  // Timer to periodically call executeIteration()
191  rclcpp::TimerBase::SharedPtr timer_;
192 
193  // Latest action goal handle
194  std::shared_ptr<rclcpp_action::ServerGoalHandle<moveit_msgs::action::LocalPlanner>> local_planning_goal_handle_;
195 
196  // Local planner feedback
197  std::shared_ptr<moveit_msgs::action::LocalPlanner::Feedback> local_planner_feedback_;
198 
199  // Planning scene monitor to get the current planning scene
200  planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_;
201 
202  // TF
203  std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
204  std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
205 
206  // Global solution listener
207  rclcpp::Subscription<moveit_msgs::msg::MotionPlanResponse>::SharedPtr global_solution_subscriber_;
208 
209  // Local planning request action server
210  rclcpp_action::Server<moveit_msgs::action::LocalPlanner>::SharedPtr local_planning_request_server_;
211 
212  // Local solution publisher
213  rclcpp::Publisher<trajectory_msgs::msg::JointTrajectory>::SharedPtr local_trajectory_publisher_;
214  rclcpp::Publisher<std_msgs::msg::Float64MultiArray>::SharedPtr local_solution_publisher_;
215 
216  // Local constraint solver plugin loader
217  std::unique_ptr<pluginlib::ClassLoader<LocalConstraintSolverInterface>> local_constraint_solver_plugin_loader_;
218 
219  // Local constrain solver instance to compute a local solution each iteration
220  std::shared_ptr<LocalConstraintSolverInterface> local_constraint_solver_instance_;
221 
222  // Trajectory operator plugin
223  std::unique_ptr<pluginlib::ClassLoader<TrajectoryOperatorInterface>> trajectory_operator_loader_;
224 
225  // Trajectory_operator instance handle trajectory matching and blending
226  std::shared_ptr<TrajectoryOperatorInterface> trajectory_operator_instance_;
227 
228  // This thread is used for long-running callbacks. It's a member so they do not go out of scope.
229  std::thread long_callback_thread_;
230 
231  // A unique callback group, to avoid mixing callbacks with other action servers
232  rclcpp::CallbackGroup::SharedPtr cb_group_;
233 };
234 } // namespace moveit::hybrid_planning
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr get_node_base_interface()
LocalPlannerComponent(const rclcpp::NodeOptions &options)
Constructor.
void declareOrGetParam(const std::string &param_name, T &output_value, const T &default_value, const rclcpp::Node::SharedPtr &node)
Struct that contains configuration of the local planner component node.