moveit2
The MoveIt Motion Planning Framework for ROS 2.
planning_pipeline.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, Sebastian Jahr
36  Description: Implementation of a MoveIt planning pipeline composed of a planner plugin and request and response
37  adapter plugins.
38 */
39 
40 #pragma once
41 
42 #include <atomic>
43 
47 #include <pluginlib/class_loader.hpp>
48 #include <rclcpp/rclcpp.hpp>
49 #include <moveit_msgs/msg/pipeline_state.hpp>
50 #include <memory>
51 #include <moveit_planning_pipeline_export.h>
52 #include <planning_pipeline_parameters.hpp>
53 
54 namespace planning_pipeline
55 {
64 template <class TPluginClass>
65 void loadPluginVector(const std::shared_ptr<rclcpp::Node>& node,
66  const std::unique_ptr<pluginlib::ClassLoader<TPluginClass>>& plugin_loader,
67  std::vector<std::shared_ptr<const TPluginClass>>& plugin_vector,
68  const std::vector<std::string>& plugin_names, const std::string& parameter_namespace)
69 {
70  // Try loading a plugin for each plugin name
71  for (const std::string& plugin_name : plugin_names)
72  {
73  RCLCPP_INFO(node->get_logger(), "Try loading adapter '%s'", plugin_name.c_str());
74  std::shared_ptr<TPluginClass> adapter;
75  try
76  {
77  adapter = plugin_loader->createUniqueInstance(plugin_name);
78  }
79  catch (pluginlib::PluginlibException& ex)
80  {
81  RCLCPP_FATAL(node->get_logger(), "Exception while loading planning adapter plugin '%s': %s", plugin_name.c_str(),
82  ex.what());
83  throw;
84  }
85  // If loading was successful, initialize plugin and add to vector
86  if (adapter)
87  {
88  adapter->initialize(node, parameter_namespace);
89  plugin_vector.push_back(std::move(adapter));
90  RCLCPP_INFO(node->get_logger(), "Loaded adapter '%s'", plugin_name.c_str());
91  }
92  else
93  {
94  RCLCPP_WARN(node->get_logger(), "Failed to initialize adapter '%s'. Not adding it to the chain.",
95  plugin_name.c_str());
96  }
97  }
98 };
99 
103 class MOVEIT_PLANNING_PIPELINE_EXPORT PlanningPipeline
104 {
105 public:
113  PlanningPipeline(const moveit::core::RobotModelConstPtr& model, const std::shared_ptr<rclcpp::Node>& node,
114  const std::string& parameter_namespace);
115 
126  PlanningPipeline(const moveit::core::RobotModelConstPtr& model, const std::shared_ptr<rclcpp::Node>& node,
127  const std::string& parameter_namespace, const std::vector<std::string>& planner_plugin_names,
128  const std::vector<std::string>& request_adapter_plugin_names = std::vector<std::string>(),
129  const std::vector<std::string>& response_adapter_plugin_names = std::vector<std::string>());
130 
131  /*
132  BEGIN BLOCK OF DEPRECATED FUNCTIONS: TODO(sjahr): Remove after 04/2024 (6 months from merge)
133  */
134  [[deprecated("Use generatePlan or ROS parameter API instead.")]] void displayComputedMotionPlans(bool /*flag*/){};
135  [[deprecated("Use generatePlan or ROS parameter API instead.")]] void publishReceivedRequests(bool /*flag*/){};
136  [[deprecated("Use generatePlan or ROS parameter API instead.")]] void checkSolutionPaths(bool /*flag*/){};
137  [[deprecated("Use generatePlan or ROS parameter API instead.")]] bool getDisplayComputedMotionPlans() const
138  {
139  return false;
140  }
141  [[deprecated("Use generatePlan or ROS parameter API instead.")]] bool getPublishReceivedRequests() const
142  {
143  return false;
144  }
145  [[deprecated("Use generatePlan or ROS parameter API instead.")]] bool getCheckSolutionPaths() const
146  {
147  return false;
148  }
149  [[deprecated(
150  "Please use getResponseAdapterPluginNames() or getRequestAdapterPluginNames().")]] const std::vector<std::string>&
152  {
153  return pipeline_parameters_.request_adapters;
154  }
155  [[deprecated("`check_solution_paths` and `display_computed_motion_plans` are deprecated. To validate the solution "
156  "please add the ValidatePath response adapter and to publish the path use the DisplayMotionPath "
157  "response adapter to your pipeline.")]] bool
158  generatePlan(const planning_scene::PlanningSceneConstPtr& /*planning_scene*/,
160  const bool /*publish_received_requests*/, const bool /*check_solution_paths*/,
161  const bool /*display_computed_motion_plans*/) const
162  {
163  return false;
164  }
165  [[deprecated("Please use getPlannerPluginNames().")]] const std::string& getPlannerPluginName() const
166  {
167  return pipeline_parameters_.planning_plugins.at(0);
168  }
169  [[deprecated(
170  "Please use 'getPlannerManager(const std::string& planner_name)'.")]] const planning_interface::PlannerManagerPtr&
172  {
173  return planner_map_.at(pipeline_parameters_.planning_plugins.at(0));
174  }
175  /*
176  END BLOCK OF DEPRECATED FUNCTIONS
177  */
178 
184  [[nodiscard]] bool generatePlan(const planning_scene::PlanningSceneConstPtr& planning_scene,
187  const bool publish_received_requests = false) const;
188 
190  void terminate() const;
191 
193  [[nodiscard]] const std::vector<std::string>& getPlannerPluginNames() const
194  {
195  return pipeline_parameters_.planning_plugins;
196  }
197 
199  [[nodiscard]] const std::vector<std::string>& getRequestAdapterPluginNames() const
200  {
201  return pipeline_parameters_.request_adapters;
202  }
203 
205  [[nodiscard]] const std::vector<std::string>& getResponseAdapterPluginNames() const
206  {
207  return pipeline_parameters_.response_adapters;
208  }
209 
211  [[nodiscard]] const moveit::core::RobotModelConstPtr& getRobotModel() const
212  {
213  return robot_model_;
214  }
215 
217  [[nodiscard]] bool isActive() const
218  {
219  return active_;
220  }
221 
223  [[nodiscard]] std::string getName() const
224  {
225  return parameter_namespace_;
226  }
227 
229  const planning_interface::PlannerManagerPtr getPlannerManager(const std::string& planner_name)
230  {
231  if (planner_map_.find(planner_name) == planner_map_.end())
232  {
233  RCLCPP_ERROR(node_->get_logger(), "Cannot retrieve planner because '%s' does not exist.", planner_name.c_str());
234  return nullptr;
235  }
236  return planner_map_.at(planner_name);
237  }
238 
239 private:
241  void configure();
242 
250  void publishPipelineState(moveit_msgs::msg::MotionPlanRequest req, const planning_interface::MotionPlanResponse& res,
251  const std::string& pipeline_stage) const;
252 
253  // Flag that indicates whether or not the planning pipeline is currently solving a planning problem
254  mutable std::atomic<bool> active_;
255 
256  // ROS node and parameters
257  std::shared_ptr<rclcpp::Node> node_;
258  const std::string parameter_namespace_;
259  planning_pipeline_parameters::Params pipeline_parameters_;
260 
261  // Planner plugin
262  std::unique_ptr<pluginlib::ClassLoader<planning_interface::PlannerManager>> planner_plugin_loader_;
263  std::unordered_map<std::string, planning_interface::PlannerManagerPtr> planner_map_;
264 
265  // Plan request adapters
266  std::unique_ptr<pluginlib::ClassLoader<planning_interface::PlanningRequestAdapter>> request_adapter_plugin_loader_;
267  std::vector<planning_interface::PlanningRequestAdapterConstPtr> planning_request_adapter_vector_;
268 
269  // Plan response adapters
270  std::unique_ptr<pluginlib::ClassLoader<planning_interface::PlanningResponseAdapter>> response_adapter_plugin_loader_;
271  std::vector<planning_interface::PlanningResponseAdapterConstPtr> planning_response_adapter_vector_;
272 
273  // Robot model
274  moveit::core::RobotModelConstPtr robot_model_;
275 
277  rclcpp::Publisher<moveit_msgs::msg::PipelineState>::SharedPtr progress_publisher_;
278 
279  rclcpp::Logger logger_;
280 };
281 
282 MOVEIT_CLASS_FORWARD(PlanningPipeline); // Defines PlanningPipelinePtr, ConstPtr, WeakPtr... etc
283 } // namespace planning_pipeline
This class facilitates loading planning plugins and planning adapter plugins. It implements functiona...
const std::vector< std::string > & getAdapterPluginNames() const
bool generatePlan(const planning_scene::PlanningSceneConstPtr &, const planning_interface::MotionPlanRequest &, planning_interface::MotionPlanResponse &, const bool, const bool, const bool) const
std::string getName() const
Return the parameter namespace as name of the planning pipeline.
const std::vector< std::string > & getResponseAdapterPluginNames() const
Get the names of the planning response adapter plugins in the order they are processed.
const std::vector< std::string > & getPlannerPluginNames() const
Get the names of the planning plugins used.
const planning_interface::PlannerManagerPtr getPlannerManager(const std::string &planner_name)
Get access to planner plugin.
const std::vector< std::string > & getRequestAdapterPluginNames() const
Get the names of the planning request adapter plugins used.
const planning_interface::PlannerManagerPtr & getPlannerManager()
const std::string & getPlannerPluginName() const
bool isActive() const
Get current status of the planning pipeline.
const moveit::core::RobotModelConstPtr & getRobotModel() const
Get the robot model that this pipeline is using.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
void loadPluginVector(const std::shared_ptr< rclcpp::Node > &node, const std::unique_ptr< pluginlib::ClassLoader< TPluginClass >> &plugin_loader, std::vector< std::shared_ptr< const TPluginClass >> &plugin_vector, const std::vector< std::string > &plugin_names, const std::string &parameter_namespace)
Helper function template to load a vector of plugins.
MOVEIT_CLASS_FORWARD(PlanningPipeline)
This namespace includes the central class for representing planning contexts.
Response to a planning query.