ompl_interface.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, 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 
42 #include <fstream>
43 
44 namespace ompl_interface
45 {
46 constexpr char LOGNAME[] = "ompl_interface";
47 } // namespace ompl_interface
48 
49 ompl_interface::OMPLInterface::OMPLInterface(const moveit::core::RobotModelConstPtr& robot_model,
50  const ros::NodeHandle& nh)
51  : nh_(nh)
52  , robot_model_(robot_model)
53  , constraint_sampler_manager_(new constraint_samplers::ConstraintSamplerManager())
54  , context_manager_(robot_model, constraint_sampler_manager_)
55  , use_constraints_approximations_(true)
56  , simplify_solutions_(true)
57 {
58  ROS_DEBUG_NAMED(LOGNAME, "Initializing OMPL interface using ROS parameters");
61 }
62 
63 ompl_interface::OMPLInterface::OMPLInterface(const moveit::core::RobotModelConstPtr& robot_model,
65  const ros::NodeHandle& nh)
66  : nh_(nh)
67  , robot_model_(robot_model)
68  , constraint_sampler_manager_(new constraint_samplers::ConstraintSamplerManager())
69  , context_manager_(robot_model, constraint_sampler_manager_)
70  , use_constraints_approximations_(true)
71  , simplify_solutions_(true)
72 {
73  ROS_DEBUG_NAMED(LOGNAME, "Initializing OMPL interface using specified configuration");
74  setPlannerConfigurations(pconfig);
76 }
77 
79 
81 {
83 
84  // construct default configurations for planning groups that don't have configs already passed in
85  for (const moveit::core::JointModelGroup* group : robot_model_->getJointModelGroups())
86  {
87  if (pconfig.find(group->getName()) == pconfig.end())
88  {
90  empty.name = empty.group = group->getName();
91  pconfig2[empty.name] = empty;
92  }
93  }
94 
95  context_manager_.setPlannerConfigurations(pconfig2);
96 }
97 
98 ompl_interface::ModelBasedPlanningContextPtr
99 ompl_interface::OMPLInterface::getPlanningContext(const planning_scene::PlanningSceneConstPtr& planning_scene,
100  const planning_interface::MotionPlanRequest& req) const
101 {
102  moveit_msgs::MoveItErrorCodes dummy;
103  return getPlanningContext(planning_scene, req, dummy);
104 }
105 
106 ompl_interface::ModelBasedPlanningContextPtr
107 ompl_interface::OMPLInterface::getPlanningContext(const planning_scene::PlanningSceneConstPtr& planning_scene,
109  moveit_msgs::MoveItErrorCodes& error_code) const
110 {
111  ModelBasedPlanningContextPtr ctx =
112  context_manager_.getPlanningContext(planning_scene, req, error_code, nh_, use_constraints_approximations_);
113  if (ctx)
114  configureContext(ctx);
115  return ctx;
116 }
117 
118 void ompl_interface::OMPLInterface::configureContext(const ModelBasedPlanningContextPtr& context) const
119 {
120  context->simplifySolutions(simplify_solutions_);
121 }
122 
124 {
125  constraint_sampler_manager_loader_ =
126  std::make_shared<constraint_sampler_manager_loader::ConstraintSamplerManagerLoader>(constraint_sampler_manager_);
127 }
128 
130  const std::string& group_name, const std::string& planner_id,
131  const std::map<std::string, std::string>& group_params,
133 {
134  XmlRpc::XmlRpcValue xml_config;
135  if (!nh_.getParam("planner_configs/" + planner_id, xml_config))
136  {
137  ROS_ERROR_NAMED(LOGNAME, "Could not find the planner configuration '%s' on the param server", planner_id.c_str());
138  return false;
139  }
140 
141  if (xml_config.getType() != XmlRpc::XmlRpcValue::TypeStruct)
142  {
143  ROS_ERROR_NAMED(LOGNAME, "A planning configuration should be of type XmlRpc Struct type (for configuration '%s')",
144  planner_id.c_str());
145  return false;
146  }
147 
148  planner_config.name = group_name + "[" + planner_id + "]";
149  planner_config.group = group_name;
150 
151  // default to specified parameters of the group (overridden by configuration specific parameters)
152  planner_config.config = group_params;
153 
154  // read parameters specific for this configuration
155  for (std::pair<const std::string, XmlRpc::XmlRpcValue>& element : xml_config)
156  {
157  if (element.second.getType() == XmlRpc::XmlRpcValue::TypeString)
158  planner_config.config[element.first] = static_cast<std::string>(element.second);
159  else if (element.second.getType() == XmlRpc::XmlRpcValue::TypeDouble)
160  planner_config.config[element.first] = moveit::core::toString(static_cast<double>(element.second));
161  else if (element.second.getType() == XmlRpc::XmlRpcValue::TypeInt)
162  planner_config.config[element.first] = std::to_string(static_cast<int>(element.second));
163  else if (element.second.getType() == XmlRpc::XmlRpcValue::TypeBoolean)
164  planner_config.config[element.first] = std::to_string(static_cast<bool>(element.second));
165  }
166 
167  return true;
168 }
169 
171 {
172  // read the planning configuration for each group
174  pconfig.clear();
175 
176  for (const std::string& group_name : robot_model_->getJointModelGroupNames())
177  {
178  // the set of planning parameters that can be specific for the group (inherited by configurations of that group)
179  static const std::string KNOWN_GROUP_PARAMS[] = { "projection_evaluator", "longest_valid_segment_fraction",
180  "enforce_joint_model_state_space" };
181 
182  // get parameters specific for the robot planning group
183  std::map<std::string, std::string> specific_group_params;
184  for (const std::string& k : KNOWN_GROUP_PARAMS)
185  {
186  std::string param_name{ group_name };
187  param_name += "/";
188  param_name += k;
189 
190  if (nh_.hasParam(param_name))
191  {
192  std::string value;
193  if (nh_.getParam(param_name, value))
194  {
195  if (!value.empty())
196  specific_group_params[k] = value;
197  continue;
198  }
199 
200  double value_d;
201  if (nh_.getParam(param_name, value_d))
202  {
203  // convert to string using no locale
204  specific_group_params[k] = moveit::core::toString(value_d);
205  continue;
206  }
207 
208  int value_i;
209  if (nh_.getParam(param_name, value_i))
210  {
211  specific_group_params[k] = std::to_string(value_i);
212  continue;
213  }
214 
215  bool value_b;
216  if (nh_.getParam(param_name, value_b))
217  {
218  specific_group_params[k] = std::to_string(value_b);
219  continue;
220  }
221  }
222  }
223 
224  // add default planner configuration
226  std::string default_planner_id;
227  if (nh_.getParam(group_name + "/default_planner_config", default_planner_id))
228  {
229  if (!loadPlannerConfiguration(group_name, default_planner_id, specific_group_params, default_pc))
230  default_planner_id = "";
231  }
232 
233  if (default_planner_id.empty())
234  {
235  default_pc.group = group_name;
236  default_pc.config = specific_group_params;
237  default_pc.config["type"] = "geometric::RRTConnect";
238  }
239 
240  default_pc.name = group_name; // this is the name of the default config
241  pconfig[default_pc.name] = default_pc;
242 
243  // get parameters specific to each planner type
244  XmlRpc::XmlRpcValue config_names;
245  if (nh_.getParam(group_name + "/planner_configs", config_names))
246  {
247  if (config_names.getType() != XmlRpc::XmlRpcValue::TypeArray)
248  {
250  "The planner_configs argument of a group configuration "
251  "should be an array of strings (for group '%s')",
252  group_name.c_str());
253  continue;
254  }
255 
256  for (int j = 0; j < config_names.size(); ++j) // NOLINT(modernize-loop-convert)
257  {
258  if (config_names[j].getType() != XmlRpc::XmlRpcValue::TypeString)
259  {
260  ROS_ERROR_NAMED(LOGNAME, "Planner configuration names must be of type string (for group '%s')",
261  group_name.c_str());
262  continue;
263  }
264 
265  const std::string planner_id = static_cast<std::string>(config_names[j]);
266 
268  if (loadPlannerConfiguration(group_name, planner_id, specific_group_params, pc))
269  pconfig[pc.name] = pc;
270  }
271  }
272  }
273 
274  for (const std::pair<const std::string, planning_interface::PlannerConfigurationSettings>& config : pconfig)
275  {
276  ROS_DEBUG_STREAM_NAMED(LOGNAME, "Parameters for configuration '" << config.first << "'");
277 
278  for (const std::pair<const std::string, std::string>& parameters : config.second.config)
279  ROS_DEBUG_STREAM_NAMED(LOGNAME, " - " << parameters.first << " = " << parameters.second);
280  }
281 
282  setPlannerConfigurations(pconfig);
283 }
284 
286 {
287  ROS_INFO_NAMED(LOGNAME, "OMPL ROS interface is running.");
288 }
XmlRpc::XmlRpcValue::size
int size() const
lexical_casts.h
ompl_interface::OMPLInterface::~OMPLInterface
virtual ~OMPLInterface()
ompl_interface::OMPLInterface::loadPlannerConfigurations
void loadPlannerConfigurations()
Configure the planners.
Definition: ompl_interface.cpp:170
utils.h
ROS_DEBUG_STREAM_NAMED
#define ROS_DEBUG_STREAM_NAMED(name, args)
ompl_interface::OMPLInterface::loadConstraintSamplers
void loadConstraintSamplers()
Load the additional plugins for sampling constraints.
Definition: ompl_interface.cpp:123
ompl_interface::OMPLInterface::setPlannerConfigurations
void setPlannerConfigurations(const planning_interface::PlannerConfigurationMap &pconfig)
Specify configurations for the planners.
Definition: ompl_interface.cpp:80
ompl_interface::OMPLInterface::printStatus
void printStatus()
Print the status of this node.
Definition: ompl_interface.cpp:285
ompl_interface
The MoveIt interface to OMPL.
Definition: constrained_goal_sampler.h:46
XmlRpc::XmlRpcValue::TypeInt
TypeInt
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
ompl_interface.h
ompl_interface::OMPLInterface::OMPLInterface
OMPLInterface(const moveit::core::RobotModelConstPtr &robot_model, const ros::NodeHandle &nh=ros::NodeHandle("~"))
Initialize OMPL-based planning for a particular robot model. ROS configuration is read from the speci...
Definition: ompl_interface.cpp:49
planning_interface::PlannerConfigurationMap
std::map< std::string, PlannerConfigurationSettings > PlannerConfigurationMap
planning_interface::PlannerConfigurationSettings::name
std::string name
XmlRpc::XmlRpcValue::TypeStruct
TypeStruct
XmlRpc::XmlRpcValue::TypeDouble
TypeDouble
ROS_INFO_NAMED
#define ROS_INFO_NAMED(name,...)
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
ompl_interface::LOGNAME
constexpr char LOGNAME[]
Definition: constrained_goal_sampler.cpp:78
planning_interface::PlannerConfigurationSettings::config
std::map< std::string, std::string > config
constraint_samplers
XmlRpc::XmlRpcValue::TypeString
TypeString
ompl_interface::OMPLInterface::configureContext
void configureContext(const ModelBasedPlanningContextPtr &context) const
Definition: ompl_interface.cpp:118
planning_interface::MotionPlanRequest
moveit_msgs::MotionPlanRequest MotionPlanRequest
XmlRpc::XmlRpcValue::getType
const Type & getType() const
XmlRpc::XmlRpcValue::TypeArray
TypeArray
ompl_interface::OMPLInterface::getPlanningContext
ModelBasedPlanningContextPtr getPlanningContext(const planning_scene::PlanningSceneConstPtr &planning_scene, const planning_interface::MotionPlanRequest &req) const
Definition: ompl_interface.cpp:99
ompl_interface::OMPLInterface::loadPlannerConfiguration
bool loadPlannerConfiguration(const std::string &group_name, const std::string &planner_id, const std::map< std::string, std::string > &group_params, planning_interface::PlannerConfigurationSettings &planner_config)
Load planner configurations for specified group into planner_config.
Definition: ompl_interface.cpp:129
moveit::core::JointModelGroup
conversions.h
XmlRpc::XmlRpcValue::TypeBoolean
TypeBoolean
planning_interface::PlannerConfigurationSettings
profiler.h
planning_interface::PlannerConfigurationSettings::group
std::string group
planning_scene
moveit::core::toString
std::string toString(double d)
XmlRpc::XmlRpcValue
ros::NodeHandle


ompl
Author(s): Ioan Sucan
autogenerated on Fri May 3 2024 02:29:39