00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <moveit/ompl_interface/ompl_interface.h>
00038 #include <moveit/robot_state/conversions.h>
00039 #include <moveit/kinematic_constraints/utils.h>
00040 #include <moveit/ompl_interface/detail/constrained_valid_state_sampler.h>
00041 #include <moveit/profiler/profiler.h>
00042 #include <fstream>
00043
00044 ompl_interface::OMPLInterface::OMPLInterface(const robot_model::RobotModelConstPtr &kmodel, const ros::NodeHandle &nh) :
00045 nh_(nh),
00046 kmodel_(kmodel),
00047 constraint_sampler_manager_(new constraint_samplers::ConstraintSamplerManager()),
00048 context_manager_(kmodel, constraint_sampler_manager_),
00049 constraints_library_(new ConstraintsLibrary(context_manager_)),
00050 use_constraints_approximations_(true),
00051 simplify_solutions_(true)
00052 {
00053 ROS_INFO("Initializing OMPL interface using ROS parameters");
00054 loadPlannerConfigurations();
00055 loadConstraintApproximations();
00056 loadConstraintSamplers();
00057 }
00058
00059 ompl_interface::OMPLInterface::OMPLInterface(const robot_model::RobotModelConstPtr &kmodel, const planning_interface::PlannerConfigurationMap &pconfig, const ros::NodeHandle &nh) :
00060 nh_(nh),
00061 kmodel_(kmodel),
00062 constraint_sampler_manager_(new constraint_samplers::ConstraintSamplerManager()),
00063 context_manager_(kmodel, constraint_sampler_manager_),
00064 constraints_library_(new ConstraintsLibrary(context_manager_)),
00065 use_constraints_approximations_(true),
00066 simplify_solutions_(true)
00067 {
00068 ROS_INFO("Initializing OMPL interface using specified configuration");
00069 setPlannerConfigurations(pconfig);
00070 loadConstraintApproximations();
00071 loadConstraintSamplers();
00072 }
00073
00074 ompl_interface::OMPLInterface::~OMPLInterface()
00075 {
00076 }
00077
00078 void ompl_interface::OMPLInterface::setPlannerConfigurations(const planning_interface::PlannerConfigurationMap &pconfig)
00079 {
00080 planning_interface::PlannerConfigurationMap pconfig2 = pconfig;
00081
00082
00083 const std::map<std::string, robot_model::JointModelGroup*>& groups = kmodel_->getJointModelGroupMap();
00084 for (std::map<std::string, robot_model::JointModelGroup*>::const_iterator it = groups.begin() ; it != groups.end() ; ++it)
00085 {
00086 if (pconfig.find(it->first) == pconfig.end())
00087 {
00088 planning_interface::PlannerConfigurationSettings empty;
00089 empty.name = empty.group = it->first;
00090 pconfig2[empty.name] = empty;
00091 }
00092 }
00093
00094 context_manager_.setPlannerConfigurations(pconfig2);
00095 }
00096
00097 ompl_interface::ModelBasedPlanningContextPtr ompl_interface::OMPLInterface::getPlanningContext(const planning_scene::PlanningSceneConstPtr& planning_scene,
00098 const planning_interface::MotionPlanRequest &req) const
00099 {
00100 moveit_msgs::MoveItErrorCodes dummy;
00101 return getPlanningContext(planning_scene, req, dummy);
00102 }
00103
00104 ompl_interface::ModelBasedPlanningContextPtr ompl_interface::OMPLInterface::getPlanningContext(const planning_scene::PlanningSceneConstPtr& planning_scene,
00105 const planning_interface::MotionPlanRequest &req,
00106 moveit_msgs::MoveItErrorCodes &error_code) const
00107 {
00108 ModelBasedPlanningContextPtr ctx = context_manager_.getPlanningContext(planning_scene, req, error_code);
00109 if (ctx)
00110 configureContext(ctx);
00111 return ctx;
00112 }
00113
00114 ompl_interface::ModelBasedPlanningContextPtr ompl_interface::OMPLInterface::getPlanningContext(const std::string &config, const std::string &factory_type) const
00115 {
00116 ModelBasedPlanningContextPtr ctx = context_manager_.getPlanningContext(config, factory_type);
00117 if (ctx)
00118 configureContext(ctx);
00119 return ctx;
00120 }
00121
00122 void ompl_interface::OMPLInterface::configureContext(const ModelBasedPlanningContextPtr &context) const
00123 {
00124 if (use_constraints_approximations_)
00125 context->setConstraintsApproximations(constraints_library_);
00126 else
00127 context->setConstraintsApproximations(ConstraintsLibraryPtr());
00128 context->simplifySolutions(simplify_solutions_);
00129 }
00130
00131 bool ompl_interface::OMPLInterface::solve(const planning_scene::PlanningSceneConstPtr& planning_scene,
00132 const planning_interface::MotionPlanRequest &req, planning_interface::MotionPlanResponse &res) const
00133 {
00134 moveit::Profiler::ScopedStart pslv;
00135 moveit::Profiler::ScopedBlock sblock("OMPLInterface:Solve");
00136
00137 ModelBasedPlanningContextPtr context = getPlanningContext(planning_scene, req);
00138 if (context)
00139 {
00140 context->clear();
00141 return context->solve(res);
00142 }
00143 else
00144 return false;
00145 }
00146
00147 bool ompl_interface::OMPLInterface::solve(const planning_scene::PlanningSceneConstPtr& planning_scene,
00148 const planning_interface::MotionPlanRequest &req, planning_interface::MotionPlanDetailedResponse &res) const
00149 {
00150 moveit::Profiler::ScopedStart pslv;
00151 moveit::Profiler::ScopedBlock sblock("OMPLInterface:Solve");
00152
00153 ModelBasedPlanningContextPtr context = getPlanningContext(planning_scene, req);
00154 if (context)
00155 {
00156 context->clear();
00157 return context->solve(res);
00158 }
00159 else
00160 return false;
00161 }
00162
00163 void ompl_interface::OMPLInterface::loadConstraintApproximations(const std::string &path)
00164 {
00165 constraints_library_->loadConstraintApproximations(path);
00166 std::stringstream ss;
00167 constraints_library_->printConstraintApproximations(ss);
00168 ROS_INFO_STREAM(ss.str());
00169 }
00170
00171 void ompl_interface::OMPLInterface::saveConstraintApproximations(const std::string &path)
00172 {
00173 constraints_library_->saveConstraintApproximations(path);
00174 }
00175
00176 bool ompl_interface::OMPLInterface::saveConstraintApproximations()
00177 {
00178 std::string cpath;
00179 if (nh_.getParam("constraint_approximations_path", cpath))
00180 {
00181 saveConstraintApproximations(cpath);
00182 return true;
00183 }
00184 ROS_WARN("ROS param 'constraint_approximations' not found. Unable to save constraint approximations");
00185 return false;
00186 }
00187
00188 bool ompl_interface::OMPLInterface::loadConstraintApproximations()
00189 {
00190 std::string cpath;
00191 if (nh_.getParam("constraint_approximations_path", cpath))
00192 {
00193 loadConstraintApproximations(cpath);
00194 return true;
00195 }
00196 return false;
00197 }
00198
00199 void ompl_interface::OMPLInterface::loadConstraintSamplers()
00200 {
00201 constraint_sampler_manager_loader_.reset(new constraint_sampler_manager_loader::ConstraintSamplerManagerLoader(constraint_sampler_manager_));
00202 }
00203
00204 void ompl_interface::OMPLInterface::loadPlannerConfigurations()
00205 {
00206 const std::vector<std::string> &group_names = kmodel_->getJointModelGroupNames();
00207 planning_interface::PlannerConfigurationMap pconfig;
00208
00209
00210 pconfig.clear();
00211 for (std::size_t i = 0 ; i < group_names.size() ; ++i)
00212 {
00213
00214 static const std::string KNOWN_GROUP_PARAMS[] = {
00215 "projection_evaluator", "longest_valid_segment_fraction"
00216 };
00217
00218
00219 std::map<std::string, std::string> specific_group_params;
00220 for (std::size_t k = 0 ; k < sizeof(KNOWN_GROUP_PARAMS) / sizeof(std::string) ; ++k)
00221 {
00222 if (nh_.hasParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k]))
00223 {
00224 std::string value;
00225 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value))
00226 {
00227 if (!value.empty())
00228 specific_group_params[KNOWN_GROUP_PARAMS[k]] = value;
00229 }
00230 else
00231 {
00232 double value_d;
00233 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value_d))
00234 specific_group_params[KNOWN_GROUP_PARAMS[k]] = boost::lexical_cast<std::string>(value_d);
00235 else
00236 {
00237 int value_i;
00238 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value_d))
00239 specific_group_params[KNOWN_GROUP_PARAMS[k]] = boost::lexical_cast<std::string>(value_i);
00240 else
00241 {
00242 bool value_b;
00243 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value_b))
00244 specific_group_params[KNOWN_GROUP_PARAMS[k]] = boost::lexical_cast<std::string>(value_b);
00245 }
00246 }
00247 }
00248 }
00249 }
00250
00251
00252 if (!specific_group_params.empty())
00253 {
00254 planning_interface::PlannerConfigurationSettings pc;
00255 pc.name = group_names[i];
00256 pc.group = group_names[i];
00257 pc.config = specific_group_params;
00258 pconfig[pc.name] = pc;
00259 }
00260
00261
00262 XmlRpc::XmlRpcValue config_names;
00263 if (nh_.getParam(group_names[i] + "/planner_configs", config_names))
00264 {
00265 if (config_names.getType() == XmlRpc::XmlRpcValue::TypeArray)
00266 {
00267 for (int32_t j = 0; j < config_names.size() ; ++j)
00268 if (config_names[j].getType() == XmlRpc::XmlRpcValue::TypeString)
00269 {
00270 std::string planner_config = static_cast<std::string>(config_names[j]);
00271 XmlRpc::XmlRpcValue xml_config;
00272 if (nh_.getParam("planner_configs/" + planner_config, xml_config))
00273 {
00274 if (xml_config.getType() == XmlRpc::XmlRpcValue::TypeStruct)
00275 {
00276 planning_interface::PlannerConfigurationSettings pc;
00277 pc.name = group_names[i] + "[" + planner_config + "]";
00278 pc.group = group_names[i];
00279
00280 pc.config = specific_group_params;
00281
00282
00283 for (XmlRpc::XmlRpcValue::iterator it = xml_config.begin() ; it != xml_config.end() ; ++it)
00284 if (it->second.getType() == XmlRpc::XmlRpcValue::TypeString)
00285 pc.config[it->first] = static_cast<std::string>(it->second);
00286 else
00287 if (it->second.getType() == XmlRpc::XmlRpcValue::TypeDouble)
00288 pc.config[it->first] = boost::lexical_cast<std::string>(static_cast<double>(it->second));
00289 else
00290 if (it->second.getType() == XmlRpc::XmlRpcValue::TypeInt)
00291 pc.config[it->first] = boost::lexical_cast<std::string>(static_cast<int>(it->second));
00292 else
00293 if (it->second.getType() == XmlRpc::XmlRpcValue::TypeBoolean)
00294 pc.config[it->first] = boost::lexical_cast<std::string>(static_cast<bool>(it->second));
00295 pconfig[pc.name] = pc;
00296 }
00297 else
00298 ROS_ERROR("A planning configuration should be of type XmlRpc Struct type (for configuration '%s')", planner_config.c_str());
00299 }
00300 else
00301 ROS_ERROR("Could not find the planner configuration '%s' on the param server", planner_config.c_str());
00302 }
00303 else
00304 ROS_ERROR("Planner configuration names must be of type string (for group '%s')", group_names[i].c_str());
00305 }
00306 else
00307 ROS_ERROR("The planner_configs argument of a group configuration should be an array of strings (for group '%s')", group_names[i].c_str());
00308 }
00309 }
00310
00311 for(planning_interface::PlannerConfigurationMap::iterator it = pconfig.begin();
00312 it != pconfig.end(); ++it)
00313 {
00314 ROS_DEBUG_STREAM("Parameters for configuration '"<< it->first << "'");
00315 for (std::map<std::string, std::string>::const_iterator config_it = it->second.config.begin() ;
00316 config_it != it->second.config.end() ; ++config_it)
00317 ROS_DEBUG_STREAM(" - " << config_it->first << " = " << config_it->second);
00318 }
00319 setPlannerConfigurations(pconfig);
00320 }
00321
00322 void ompl_interface::OMPLInterface::printStatus()
00323 {
00324 ROS_INFO("OMPL ROS interface is running.");
00325 }