Go to the documentation of this file.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,
00060 const planning_interface::PlannerConfigurationMap& pconfig,
00061 const ros::NodeHandle& nh)
00062 : nh_(nh)
00063 , kmodel_(kmodel)
00064 , constraint_sampler_manager_(new constraint_samplers::ConstraintSamplerManager())
00065 , context_manager_(kmodel, constraint_sampler_manager_)
00066 , constraints_library_(new ConstraintsLibrary(context_manager_))
00067 , use_constraints_approximations_(true)
00068 , simplify_solutions_(true)
00069 {
00070 ROS_INFO("Initializing OMPL interface using specified configuration");
00071 setPlannerConfigurations(pconfig);
00072 loadConstraintApproximations();
00073 loadConstraintSamplers();
00074 }
00075
00076 ompl_interface::OMPLInterface::~OMPLInterface()
00077 {
00078 }
00079
00080 void ompl_interface::OMPLInterface::setPlannerConfigurations(const planning_interface::PlannerConfigurationMap& pconfig)
00081 {
00082 planning_interface::PlannerConfigurationMap pconfig2 = pconfig;
00083
00084
00085 const std::vector<const robot_model::JointModelGroup*>& groups = kmodel_->getJointModelGroups();
00086 for (std::size_t i = 0; i < groups.size(); ++i)
00087 {
00088 if (pconfig.find(groups[i]->getName()) == pconfig.end())
00089 {
00090 planning_interface::PlannerConfigurationSettings empty;
00091 empty.name = empty.group = groups[i]->getName();
00092 pconfig2[empty.name] = empty;
00093 }
00094 }
00095
00096 context_manager_.setPlannerConfigurations(pconfig2);
00097 }
00098
00099 ompl_interface::ModelBasedPlanningContextPtr ompl_interface::OMPLInterface::getPlanningContext(
00100 const planning_scene::PlanningSceneConstPtr& planning_scene, const planning_interface::MotionPlanRequest& req) const
00101 {
00102 moveit_msgs::MoveItErrorCodes dummy;
00103 return getPlanningContext(planning_scene, req, dummy);
00104 }
00105
00106 ompl_interface::ModelBasedPlanningContextPtr ompl_interface::OMPLInterface::getPlanningContext(
00107 const planning_scene::PlanningSceneConstPtr& planning_scene, const planning_interface::MotionPlanRequest& req,
00108 moveit_msgs::MoveItErrorCodes& error_code) const
00109 {
00110 ModelBasedPlanningContextPtr ctx = context_manager_.getPlanningContext(planning_scene, req, error_code);
00111 if (ctx)
00112 configureContext(ctx);
00113 return ctx;
00114 }
00115
00116 ompl_interface::ModelBasedPlanningContextPtr
00117 ompl_interface::OMPLInterface::getPlanningContext(const std::string& config, const std::string& factory_type) const
00118 {
00119 ModelBasedPlanningContextPtr ctx = context_manager_.getPlanningContext(config, factory_type);
00120 if (ctx)
00121 configureContext(ctx);
00122 return ctx;
00123 }
00124
00125 void ompl_interface::OMPLInterface::configureContext(const ModelBasedPlanningContextPtr& context) const
00126 {
00127 if (use_constraints_approximations_)
00128 context->setConstraintsApproximations(constraints_library_);
00129 else
00130 context->setConstraintsApproximations(ConstraintsLibraryPtr());
00131 context->simplifySolutions(simplify_solutions_);
00132 }
00133
00134 void ompl_interface::OMPLInterface::loadConstraintApproximations(const std::string& path)
00135 {
00136 constraints_library_->loadConstraintApproximations(path);
00137 std::stringstream ss;
00138 constraints_library_->printConstraintApproximations(ss);
00139 ROS_INFO_STREAM(ss.str());
00140 }
00141
00142 void ompl_interface::OMPLInterface::saveConstraintApproximations(const std::string& path)
00143 {
00144 constraints_library_->saveConstraintApproximations(path);
00145 }
00146
00147 bool ompl_interface::OMPLInterface::saveConstraintApproximations()
00148 {
00149 std::string cpath;
00150 if (nh_.getParam("constraint_approximations_path", cpath))
00151 {
00152 saveConstraintApproximations(cpath);
00153 return true;
00154 }
00155 ROS_WARN("ROS param 'constraint_approximations' not found. Unable to save constraint approximations");
00156 return false;
00157 }
00158
00159 bool ompl_interface::OMPLInterface::loadConstraintApproximations()
00160 {
00161 std::string cpath;
00162 if (nh_.getParam("constraint_approximations_path", cpath))
00163 {
00164 loadConstraintApproximations(cpath);
00165 return true;
00166 }
00167 return false;
00168 }
00169
00170 void ompl_interface::OMPLInterface::loadConstraintSamplers()
00171 {
00172 constraint_sampler_manager_loader_.reset(
00173 new constraint_sampler_manager_loader::ConstraintSamplerManagerLoader(constraint_sampler_manager_));
00174 }
00175
00176 void ompl_interface::OMPLInterface::loadPlannerConfigurations()
00177 {
00178 const std::vector<std::string>& group_names = kmodel_->getJointModelGroupNames();
00179 planning_interface::PlannerConfigurationMap pconfig;
00180
00181
00182 pconfig.clear();
00183 for (std::size_t i = 0; i < group_names.size(); ++i)
00184 {
00185
00186 static const std::string KNOWN_GROUP_PARAMS[] = { "projection_evaluator", "longest_valid_segment_fraction",
00187 "enforce_joint_model_state_space" };
00188
00189
00190 std::map<std::string, std::string> specific_group_params;
00191 for (std::size_t k = 0; k < sizeof(KNOWN_GROUP_PARAMS) / sizeof(std::string); ++k)
00192 {
00193 if (nh_.hasParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k]))
00194 {
00195 std::string value;
00196 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value))
00197 {
00198 if (!value.empty())
00199 specific_group_params[KNOWN_GROUP_PARAMS[k]] = value;
00200 }
00201 else
00202 {
00203 double value_d;
00204 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value_d))
00205 specific_group_params[KNOWN_GROUP_PARAMS[k]] = boost::lexical_cast<std::string>(value_d);
00206 else
00207 {
00208 int value_i;
00209 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value_d))
00210 specific_group_params[KNOWN_GROUP_PARAMS[k]] = boost::lexical_cast<std::string>(value_i);
00211 else
00212 {
00213 bool value_b;
00214 if (nh_.getParam(group_names[i] + "/" + KNOWN_GROUP_PARAMS[k], value_b))
00215 specific_group_params[KNOWN_GROUP_PARAMS[k]] = boost::lexical_cast<std::string>(value_b);
00216 }
00217 }
00218 }
00219 }
00220 }
00221
00222
00223 if (!specific_group_params.empty())
00224 {
00225 planning_interface::PlannerConfigurationSettings pc;
00226 pc.name = group_names[i];
00227 pc.group = group_names[i];
00228 pc.config = specific_group_params;
00229 pconfig[pc.name] = pc;
00230 }
00231
00232
00233 XmlRpc::XmlRpcValue config_names;
00234 if (nh_.getParam(group_names[i] + "/planner_configs", config_names))
00235 {
00236 if (config_names.getType() == XmlRpc::XmlRpcValue::TypeArray)
00237 {
00238 for (int32_t j = 0; j < config_names.size(); ++j)
00239 if (config_names[j].getType() == XmlRpc::XmlRpcValue::TypeString)
00240 {
00241 std::string planner_config = static_cast<std::string>(config_names[j]);
00242 XmlRpc::XmlRpcValue xml_config;
00243 if (nh_.getParam("planner_configs/" + planner_config, xml_config))
00244 {
00245 if (xml_config.getType() == XmlRpc::XmlRpcValue::TypeStruct)
00246 {
00247 planning_interface::PlannerConfigurationSettings pc;
00248 pc.name = group_names[i] + "[" + planner_config + "]";
00249 pc.group = group_names[i];
00250
00251 pc.config = specific_group_params;
00252
00253
00254 for (XmlRpc::XmlRpcValue::iterator it = xml_config.begin(); it != xml_config.end(); ++it)
00255 if (it->second.getType() == XmlRpc::XmlRpcValue::TypeString)
00256 pc.config[it->first] = static_cast<std::string>(it->second);
00257 else if (it->second.getType() == XmlRpc::XmlRpcValue::TypeDouble)
00258 pc.config[it->first] = boost::lexical_cast<std::string>(static_cast<double>(it->second));
00259 else if (it->second.getType() == XmlRpc::XmlRpcValue::TypeInt)
00260 pc.config[it->first] = boost::lexical_cast<std::string>(static_cast<int>(it->second));
00261 else if (it->second.getType() == XmlRpc::XmlRpcValue::TypeBoolean)
00262 pc.config[it->first] = boost::lexical_cast<std::string>(static_cast<bool>(it->second));
00263 pconfig[pc.name] = pc;
00264 }
00265 else
00266 ROS_ERROR("A planning configuration should be of type XmlRpc Struct type (for configuration '%s')",
00267 planner_config.c_str());
00268 }
00269 else
00270 ROS_ERROR("Could not find the planner configuration '%s' on the param server", planner_config.c_str());
00271 }
00272 else
00273 ROS_ERROR("Planner configuration names must be of type string (for group '%s')", group_names[i].c_str());
00274 }
00275 else
00276 ROS_ERROR("The planner_configs argument of a group configuration should be an array of strings (for group "
00277 "'%s')",
00278 group_names[i].c_str());
00279 }
00280 }
00281
00282 for (planning_interface::PlannerConfigurationMap::iterator it = pconfig.begin(); it != pconfig.end(); ++it)
00283 {
00284 ROS_DEBUG_STREAM_NAMED("parameters", "Parameters for configuration '" << it->first << "'");
00285 for (std::map<std::string, std::string>::const_iterator config_it = it->second.config.begin();
00286 config_it != it->second.config.end(); ++config_it)
00287 ROS_DEBUG_STREAM_NAMED("parameters", " - " << config_it->first << " = " << config_it->second);
00288 }
00289 setPlannerConfigurations(pconfig);
00290 }
00291
00292 void ompl_interface::OMPLInterface::printStatus()
00293 {
00294 ROS_INFO("OMPL ROS interface is running.");
00295 }