@@ -53,24 +53,15 @@ namespace moveit {
5353namespace task_constructor {
5454namespace solvers {
5555
56- PipelinePlanner::PipelinePlanner (const rclcpp::Node::SharedPtr& node, const std::string& pipeline_name,
57- const std::string& planner_id)
58- : PipelinePlanner(node, { { pipeline_name, planner_id } }) {}
56+ using PipelineMap = std::unordered_map<std::string, std::string>;
5957
6058PipelinePlanner::PipelinePlanner (
61- const rclcpp::Node::SharedPtr& node, const std::unordered_map<std::string, std::string>& pipeline_id_planner_id_map,
62- const std::unordered_map<std::string, planning_pipeline::PlanningPipelinePtr>& planning_pipelines,
59+ const rclcpp::Node::SharedPtr& node, const PipelineMap& pipeline_id_planner_id_map,
6360 const moveit::planning_pipeline_interfaces::StoppingCriterionFunction& stopping_criterion_callback,
6461 const moveit::planning_pipeline_interfaces::SolutionSelectionFunction& solution_selection_function)
6562 : node_(node)
66- , pipeline_id_planner_id_map_(pipeline_id_planner_id_map)
6763 , stopping_criterion_callback_(stopping_criterion_callback)
6864 , solution_selection_function_(solution_selection_function) {
69- // If the pipeline name - pipeline map is passed as constructor argument, use it. Otherwise, it will be created in
70- // the init(..) function
71- if (!planning_pipelines.empty ()) {
72- planning_pipelines_ = planning_pipelines;
73- }
7465 // Declare properties of the MotionPlanRequest
7566 properties ().declare <uint>(" num_planning_attempts" , 1u , " number of planning attempts" );
7667 properties ().declare <moveit_msgs::msg::WorkspaceParameters>(
@@ -86,21 +77,22 @@ PipelinePlanner::PipelinePlanner(
8677 properties ().declare <bool >(" publish_planning_requests" , false ,
8778 " publish motion planning requests on topic " +
8879 planning_pipeline::PlanningPipeline::MOTION_PLAN_REQUEST_TOPIC);
89- properties ().declare <std::unordered_map<std::string, std::string>>(
90- " pipeline_id_planner_id_map" , std::unordered_map<std::string, std::string>(),
91- " Set of pipelines and planners used for planning" );
80+ properties ().declare (" pipeline_id_planner_id_map" , pipeline_id_planner_id_map,
81+ " Set of pipelines and planners used for planning" );
9282}
9383
9484bool PipelinePlanner::setPlannerId (const std::string& pipeline_name, const std::string& planner_id) {
9585 // Only set ID if pipeline exists. It is not possible to create new pipelines with this command.
96- auto it = pipeline_id_planner_id_map_.find (pipeline_name);
97- if (it == pipeline_id_planner_id_map_.end ()) {
86+ PipelineMap map = properties ().get <PipelineMap>(" pipeline_id_planner_id_map" );
87+ auto it = map.find (pipeline_name);
88+ if (it == map.end ()) {
9889 RCLCPP_ERROR (node_->get_logger (),
9990 " PipelinePlanner does not have a pipeline called '%s'. Cannot set pipeline ID '%s'" ,
10091 pipeline_name.c_str (), planner_id.c_str ());
10192 return false ;
10293 }
10394 it->second = planner_id;
95+ properties ().set (" pipeline_id_planner_id_map" , std::move (map));
10496 return true ;
10597}
10698
@@ -114,28 +106,34 @@ void PipelinePlanner::setSolutionSelectionFunction(
114106}
115107
116108void PipelinePlanner::init (const core::RobotModelConstPtr& robot_model) {
117- // If no planning pipelines exist, create them based on the pipeline names provided in pipeline_id_planner_id_map_ .
118- // The assumption here is that all parameters required by the planning pipeline can be found in a namespace that
119- // equals the pipeline name.
109+ // Create planning pipelines once from pipeline_id_planner_id_map .
110+ // We assume that all parameters required by the pipeline can be found
111+ // in the namespace of the pipeline name.
120112 if (planning_pipelines_.empty ()) {
113+ auto map = properties ().get <PipelineMap>(" pipeline_id_planner_id_map" );
121114 // Create pipeline name vector from the keys of pipeline_id_planner_id_map_
122- if (pipeline_id_planner_id_map_.empty ()) {
123- throw std::runtime_error (" Cannot initialize PipelinePlanner: No planning pipeline was provided and "
124- " pipeline_id_planner_id_map_ is empty!" );
115+ if (map.empty ()) {
116+ throw std::runtime_error (" Cannot initialize PipelinePlanner: pipeline_id_planner_id_map is empty!" );
125117 }
126118
127119 std::vector<std::string> pipeline_names;
128- for (const auto & pipeline_name_planner_id_pair : pipeline_id_planner_id_map_ ) {
120+ for (const auto & pipeline_name_planner_id_pair : map ) {
129121 pipeline_names.push_back (pipeline_name_planner_id_pair.first );
130122 }
131123 planning_pipelines_ = moveit::planning_pipeline_interfaces::createPlanningPipelineMap (std::move (pipeline_names),
132124 robot_model, node_);
133- }
134-
135- // Check if it is still empty
136- if (planning_pipelines_.empty ()) {
137- throw std::runtime_error (
138- " Cannot initialize PipelinePlanner: Could not create any valid entries for planning pipeline maps!" );
125+ // Check if it is still empty
126+ if (planning_pipelines_.empty ()) {
127+ throw std::runtime_error (" Failed to initialize PipelinePlanner: Could not create any valid pipeline" );
128+ }
129+ } else {
130+ // Validate that all pipelines use the task's robot model
131+ for (const auto & pair : planning_pipelines_) {
132+ if (pair.second ->getRobotModel () != robot_model) {
133+ throw std::runtime_error (
134+ " The robot model of the planning pipeline isn't the same as the task's robot model -- " );
135+ }
136+ }
139137 }
140138
141139 // Configure all pipelines according to the configuration in properties
@@ -178,28 +176,23 @@ bool PipelinePlanner::plan(const planning_scene::PlanningSceneConstPtr& planning
178176 const moveit_msgs::msg::Constraints& goal_constraints, double timeout,
179177 robot_trajectory::RobotTrajectoryPtr& result,
180178 const moveit_msgs::msg::Constraints& path_constraints) {
179+ const auto & map = properties ().get <PipelineMap>(" pipeline_id_planner_id_map" );
180+
181181 // Create a request for every planning pipeline that should run in parallel
182182 std::vector<moveit_msgs::msg::MotionPlanRequest> requests;
183- requests.reserve (pipeline_id_planner_id_map_ .size ());
183+ requests.reserve (map .size ());
184184
185- auto const property_pipeline_id_planner_id_map =
186- properties ().get <std::unordered_map<std::string, std::string>>(" pipeline_id_planner_id_map" );
187- for (auto const & pipeline_id_planner_id_pair :
188- (!property_pipeline_id_planner_id_map.empty () ? property_pipeline_id_planner_id_map :
189- pipeline_id_planner_id_map_)) {
185+ for (const auto & [pipeline_id, planner_id] : map) {
190186 // Check that requested pipeline exists and skip it if it doesn't exist
191- if (planning_pipelines_.find (pipeline_id_planner_id_pair.first ) == planning_pipelines_.end ()) {
192- RCLCPP_WARN (
193- node_->get_logger (),
194- " Pipeline '%s' is not available of this PipelineSolver instance. Skipping a request for this pipeline." ,
195- pipeline_id_planner_id_pair.first .c_str ());
187+ if (planning_pipelines_.count (pipeline_id) == 0 ) {
188+ RCLCPP_WARN (node_->get_logger (), " Pipeline '%s' was not created. Skipping." , pipeline_id.c_str ());
196189 continue ;
197190 }
198191 // Create MotionPlanRequest for pipeline
199192 moveit_msgs::msg::MotionPlanRequest request;
200- request.pipeline_id = pipeline_id_planner_id_pair. first ;
193+ request.pipeline_id = pipeline_id ;
201194 request.group_name = joint_model_group->getName ();
202- request.planner_id = pipeline_id_planner_id_pair. second ;
195+ request.planner_id = planner_id ;
203196 request.allowed_planning_time = timeout;
204197 request.start_state .is_diff = true ; // we don't specify an extra start state
205198 request.num_planning_attempts = properties ().get <uint>(" num_planning_attempts" );
0 commit comments