pipeline_planner.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Bielefeld University
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 Bielefeld University 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 /* Authors: Robert Haschke
36  Desc: plan using MoveIt's PlanningPipeline
37 */
38 
43 #include <moveit_msgs/MotionPlanRequest.h>
45 #include <tf2_eigen/tf2_eigen.h>
46 
47 namespace moveit {
48 namespace task_constructor {
49 namespace solvers {
50 
51 struct PlannerCache
52 {
53  using PlannerID = std::tuple<std::string, std::string>;
54  using PlannerMap = std::map<PlannerID, std::weak_ptr<planning_pipeline::PlanningPipeline> >;
55  using ModelList = std::list<std::pair<std::weak_ptr<const moveit::core::RobotModel>, PlannerMap> >;
57 
58  PlannerMap::mapped_type& retrieve(const moveit::core::RobotModelConstPtr& model, const PlannerID& id) {
59  // find model in cache_ and remove expired entries while doing so
60  ModelList::iterator model_it = cache_.begin();
61  while (model_it != cache_.end()) {
62  if (model_it->first.expired()) {
63  model_it = cache_.erase(model_it);
64  continue;
65  }
66  if (model_it->first.lock() == model)
67  break;
68  ++model_it;
69  }
70  if (model_it == cache_.end()) // if not found, create a new PlannerMap for this model
71  model_it = cache_.insert(cache_.begin(), std::make_pair(model, PlannerMap()));
72 
73  return model_it->second.insert(std::make_pair(id, PlannerMap::mapped_type())).first->second;
74  }
75 };
76 
77 planning_pipeline::PlanningPipelinePtr PipelinePlanner::create(const PipelinePlanner::Specification& spec) {
78  static PlannerCache cache;
79 
80  static constexpr char const* PLUGIN_PARAMETER_NAME = "planning_plugin";
81 
82  std::string pipeline_ns = spec.ns + "/planning_pipelines/" + spec.pipeline;
83  // fallback to old structure for pipeline parameters in MoveIt
84  if (!ros::NodeHandle(pipeline_ns).hasParam(PLUGIN_PARAMETER_NAME)) {
85  ROS_WARN("Failed to find '%s/%s'. %s", pipeline_ns.c_str(), PLUGIN_PARAMETER_NAME,
86  "Attempting to load pipeline from old parameter structure. Please update your MoveIt config.");
87  pipeline_ns = spec.ns;
88  }
89 
90  PlannerCache::PlannerID id(pipeline_ns, spec.adapter_param);
91 
92  std::weak_ptr<planning_pipeline::PlanningPipeline>& entry = cache.retrieve(spec.model, id);
93  planning_pipeline::PlanningPipelinePtr planner = entry.lock();
94  if (!planner) {
95  // create new entry
96  planner = std::make_shared<planning_pipeline::PlanningPipeline>(spec.model, ros::NodeHandle(pipeline_ns),
97  PLUGIN_PARAMETER_NAME, spec.adapter_param);
98  // store in cache
99  entry = planner;
100  }
101  return planner;
102 }
103 
104 PipelinePlanner::PipelinePlanner(const std::string& pipeline_name) : pipeline_name_{ pipeline_name } {
105  auto& p = properties();
106  p.declare<std::string>("planner", "", "planner id");
107 
108  p.declare<uint>("num_planning_attempts", 1u, "number of planning attempts");
109  p.declare<moveit_msgs::WorkspaceParameters>("workspace_parameters", moveit_msgs::WorkspaceParameters(),
110  "allowed workspace of mobile base?");
111 
112  p.declare<double>("goal_joint_tolerance", 1e-4, "tolerance for reaching joint goals");
113  p.declare<double>("goal_position_tolerance", 1e-4, "tolerance for reaching position goals");
114  p.declare<double>("goal_orientation_tolerance", 1e-4, "tolerance for reaching orientation goals");
115 
116  p.declare<bool>("display_motion_plans", false,
117  "publish generated solutions on topic " + planning_pipeline::PlanningPipeline::DISPLAY_PATH_TOPIC);
118  p.declare<bool>("publish_planning_requests", false,
119  "publish motion planning requests on topic " +
121 }
122 
123 PipelinePlanner::PipelinePlanner(const planning_pipeline::PlanningPipelinePtr& planning_pipeline) : PipelinePlanner() {
124  planner_ = planning_pipeline;
125 }
126 
127 void PipelinePlanner::init(const core::RobotModelConstPtr& robot_model) {
128  if (!planner_) {
129  Specification spec;
130  spec.model = robot_model;
131  spec.pipeline = pipeline_name_;
132  planner_ = create(spec);
133  } else if (robot_model != planner_->getRobotModel()) {
134  throw std::runtime_error(
135  "The robot model of the planning pipeline isn't the same as the task's robot model -- "
136  "use Task::setRobotModel for setting the robot model when using custom planning pipeline");
137  }
138  planner_->displayComputedMotionPlans(properties().get<bool>("display_motion_plans"));
139  planner_->publishReceivedRequests(properties().get<bool>("publish_planning_requests"));
140 }
141 
142 void initMotionPlanRequest(moveit_msgs::MotionPlanRequest& req, const PropertyMap& p,
143  const moveit::core::JointModelGroup* jmg, double timeout) {
144  req.group_name = jmg->getName();
145  req.planner_id = p.get<std::string>("planner");
146  req.allowed_planning_time = std::min(timeout, p.get<double>("timeout"));
147  req.start_state.is_diff = true; // we don't specify an extra start state
148 
149  req.num_planning_attempts = p.get<uint>("num_planning_attempts");
150  req.max_velocity_scaling_factor = p.get<double>("max_velocity_scaling_factor");
151  req.max_acceleration_scaling_factor = p.get<double>("max_acceleration_scaling_factor");
152  req.workspace_parameters = p.get<moveit_msgs::WorkspaceParameters>("workspace_parameters");
153 }
154 
155 PlannerInterface::Result PipelinePlanner::plan(const planning_scene::PlanningSceneConstPtr& from,
156  const planning_scene::PlanningSceneConstPtr& to,
157  const moveit::core::JointModelGroup* jmg, double timeout,
158  robot_trajectory::RobotTrajectoryPtr& result,
159  const moveit_msgs::Constraints& path_constraints) {
160  const auto& props = properties();
161  moveit_msgs::MotionPlanRequest req;
162  initMotionPlanRequest(req, props, jmg, timeout);
163 
164  req.goal_constraints.resize(1);
165  req.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(to->getCurrentState(), jmg,
166  props.get<double>("goal_joint_tolerance"));
167  req.path_constraints = path_constraints;
168 
169  return plan(from, req, result);
170 }
171 
172 PlannerInterface::Result PipelinePlanner::plan(const planning_scene::PlanningSceneConstPtr& from,
173  const moveit::core::LinkModel& link, const Eigen::Isometry3d& offset,
174  const Eigen::Isometry3d& target_eigen,
175  const moveit::core::JointModelGroup* jmg, double timeout,
176  robot_trajectory::RobotTrajectoryPtr& result,
177  const moveit_msgs::Constraints& path_constraints) {
178  const auto& props = properties();
179  moveit_msgs::MotionPlanRequest req;
180  initMotionPlanRequest(req, props, jmg, timeout);
181 
182  geometry_msgs::PoseStamped target;
183  target.header.frame_id = from->getPlanningFrame();
184  target.pose = tf2::toMsg(target_eigen * offset.inverse());
185 
186  req.goal_constraints.resize(1);
187  req.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(
188  link.getName(), target, props.get<double>("goal_position_tolerance"),
189  props.get<double>("goal_orientation_tolerance"));
190  req.path_constraints = path_constraints;
191 
192  return plan(from, req, result);
193 }
194 
195 PlannerInterface::Result PipelinePlanner::plan(const planning_scene::PlanningSceneConstPtr& from,
196  const moveit_msgs::MotionPlanRequest& req,
197  robot_trajectory::RobotTrajectoryPtr& result) {
199  bool success = planner_->generatePlan(from, req, res);
200  result = res.trajectory_;
201  return { success, success ? std::string() : static_cast<std::string>(res.error_code_) };
202 }
203 
204 } // namespace solvers
205 } // namespace task_constructor
206 } // namespace moveit
moveit::core::LinkModel
task.h
moveit::task_constructor::solvers::PlannerCache::PlannerID
std::tuple< std::string, std::string > PlannerID
Definition: pipeline_planner.cpp:181
planning_pipeline::PlanningPipeline::DISPLAY_PATH_TOPIC
static const std::string DISPLAY_PATH_TOPIC
planning_interface::MotionPlanResponse
tf2_eigen.h
utils.h
moveit::task_constructor::solvers::PlannerInterface::Result
Definition: planner_interface.h:74
moveit::task_constructor::solvers::PipelinePlanner::PipelinePlanner
PipelinePlanner(const std::string &pipeline="ompl")
Definition: pipeline_planner.cpp:200
kinematic_constraints::constructGoalConstraints
moveit_msgs::Constraints constructGoalConstraints(const moveit::core::RobotState &state, const moveit::core::JointModelGroup *jmg, double tolerance=std::numeric_limits< double >::epsilon())
moveit::task_constructor::solvers::PipelinePlanner::create
static planning_pipeline::PlanningPipelinePtr create(const moveit::core::RobotModelConstPtr &model)
Definition: pipeline_planner.h:67
planning_pipeline::PlanningPipeline::MOTION_PLAN_REQUEST_TOPIC
static const std::string MOTION_PLAN_REQUEST_TOPIC
moveit::task_constructor::solvers::PlannerCache::cache_
ModelList cache_
Definition: pipeline_planner.cpp:184
moveit::task_constructor::solvers::initMotionPlanRequest
void initMotionPlanRequest(moveit_msgs::MotionPlanRequest &req, const PropertyMap &p, const moveit::core::JointModelGroup *jmg, double timeout)
Definition: pipeline_planner.cpp:238
moveit::task_constructor::solvers::PlannerCache::ModelList
std::list< std::pair< std::weak_ptr< const moveit::core::RobotModel >, PlannerMap > > ModelList
Definition: pipeline_planner.cpp:183
moveit::core::JointModelGroup::getName
const std::string & getName() const
res
res
ROS_WARN
#define ROS_WARN(...)
pipeline_planner.h
planning_pipeline.h
planning_pipeline
planning_scene.h
moveit::task_constructor::solvers::PlannerCache::PlannerMap
std::map< PlannerID, std::weak_ptr< planning_pipeline::PlanningPipeline > > PlannerMap
Definition: pipeline_planner.cpp:182
create
Eigen::Matrix< CustomType< Scalar >, Eigen::Dynamic, Eigen::Dynamic > create(int rows, int cols)
moveit
moveit::task_constructor::success
bool success
Definition: container.cpp:61
moveit::core::JointModelGroup
tf2::toMsg
B toMsg(const A &a)
moveit::task_constructor::solvers::PlannerCache::retrieve
PlannerMap::mapped_type & retrieve(const moveit::core::RobotModelConstPtr &model, const PlannerID &id)
Definition: pipeline_planner.cpp:186
moveit::core::LinkModel::getName
const std::string & getName() const
ros::NodeHandle


core
Author(s):
autogenerated on Sat May 3 2025 02:40:11