ompl_interface.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
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   // construct default configurations
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   // read the planning configuration for each group
00210   pconfig.clear();
00211   for (std::size_t i = 0 ; i < group_names.size() ; ++i)
00212   {
00213     // the set of planning parameters that can be specific for the group (inherited by configurations of that group)
00214     static const std::string KNOWN_GROUP_PARAMS[] = {
00215       "projection_evaluator", "longest_valid_segment_fraction"
00216     };
00217 
00218     // get parameters specific for the robot planning group
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     // set the parameters (if any) for the default group configuration;
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     // get parameters specific to each planner type
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         // inherit parameters from the group (which can be overriden)
00280         pc.config = specific_group_params;
00281 
00282         // read parameters specific for this configuration
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 }


ompl
Author(s): Ioan Sucan
autogenerated on Mon Oct 6 2014 11:12:03