planning_request_adapter.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2012, 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 #include <moveit/planning_request_adapter/planning_request_adapter.h>
00036 #include <boost/bind.hpp>
00037 #include <algorithm>
00038 
00039 // we could really use some c++11 lambda functions here :)
00040 
00041 namespace planning_request_adapter
00042 {
00043 namespace
00044 {
00045 bool callPlannerInterfaceSolve(const planning_interface::PlannerManager *planner,
00046                                const planning_scene::PlanningSceneConstPtr& planning_scene,
00047                                const planning_interface::MotionPlanRequest &req,
00048                                planning_interface::MotionPlanResponse &res)
00049 {
00050   planning_interface::PlanningContextPtr context = planner->getPlanningContext(planning_scene, req, res.error_code_);
00051   if (context)
00052     return context->solve(res);
00053   else
00054     return false;
00055 }
00056 }
00057 }
00058 
00059 bool planning_request_adapter::PlanningRequestAdapter::adaptAndPlan(const planning_interface::PlannerManagerPtr &planner,
00060                                                                     const planning_scene::PlanningSceneConstPtr& planning_scene,
00061                                                                     const planning_interface::MotionPlanRequest &req,
00062                                                                     planning_interface::MotionPlanResponse &res,
00063                                                                     std::vector<std::size_t> &added_path_index) const
00064 {
00065   return adaptAndPlan(boost::bind(&callPlannerInterfaceSolve, planner.get(), _1, _2, _3), planning_scene, req, res, added_path_index);
00066 }
00067 
00068 bool planning_request_adapter::PlanningRequestAdapter::adaptAndPlan(const planning_interface::PlannerManagerPtr &planner,
00069                                                                     const planning_scene::PlanningSceneConstPtr& planning_scene,
00070                                                                     const planning_interface::MotionPlanRequest &req,
00071                                                                     planning_interface::MotionPlanResponse &res) const
00072 {
00073   std::vector<std::size_t> dummy;
00074   return adaptAndPlan(planner, planning_scene, req, res, dummy);
00075 }
00076 
00077 namespace planning_request_adapter
00078 {
00079 
00080 namespace
00081 {
00082 
00083 // boost bind is not happy with overloading, so we add intermediate function objects
00084 
00085 bool callAdapter1(const PlanningRequestAdapter *adapter,
00086                   const planning_interface::PlannerManagerPtr &planner,
00087                   const planning_scene::PlanningSceneConstPtr& planning_scene,
00088                   const planning_interface::MotionPlanRequest &req,
00089                   planning_interface::MotionPlanResponse &res,
00090                   std::vector<std::size_t> &added_path_index)
00091 {
00092   try
00093   {
00094     return adapter->adaptAndPlan(planner, planning_scene, req, res, added_path_index);
00095   }
00096   catch(std::runtime_error &ex)
00097   {
00098     logError("Exception caught executing adapter '%s': %s", adapter->getDescription().c_str(), ex.what());
00099     added_path_index.clear();
00100     return callPlannerInterfaceSolve(planner.get(), planning_scene, req, res);
00101   }
00102   catch(...)
00103   {
00104     logError("Exception caught executing adapter '%s'", adapter->getDescription().c_str());
00105     added_path_index.clear();
00106     return callPlannerInterfaceSolve(planner.get(), planning_scene, req, res);
00107   }
00108 }
00109 
00110 bool callAdapter2(const PlanningRequestAdapter *adapter,
00111                   const PlanningRequestAdapter::PlannerFn &planner,
00112                   const planning_scene::PlanningSceneConstPtr& planning_scene,
00113                   const planning_interface::MotionPlanRequest &req,
00114                   planning_interface::MotionPlanResponse &res,
00115                   std::vector<std::size_t> &added_path_index)
00116 {
00117   try
00118   {
00119     return adapter->adaptAndPlan(planner, planning_scene, req, res, added_path_index);
00120   }
00121   catch(std::runtime_error &ex)
00122   {
00123     logError("Exception caught executing adapter '%s': %s", adapter->getDescription().c_str(), ex.what());
00124     added_path_index.clear();
00125     return planner(planning_scene, req, res);
00126   }
00127   catch(...)
00128   {
00129     logError("Exception caught executing adapter '%s'", adapter->getDescription().c_str());
00130     added_path_index.clear();
00131     return planner(planning_scene, req, res);
00132   }
00133 }
00134 
00135 }
00136 
00137 }
00138 
00139 bool planning_request_adapter::PlanningRequestAdapterChain::adaptAndPlan(const planning_interface::PlannerManagerPtr &planner,
00140                                                                          const planning_scene::PlanningSceneConstPtr& planning_scene,
00141                                                                          const planning_interface::MotionPlanRequest &req,
00142                                                                          planning_interface::MotionPlanResponse &res) const
00143 {
00144   std::vector<std::size_t> dummy;
00145   return adaptAndPlan(planner, planning_scene, req, res, dummy);
00146 }
00147 
00148 bool planning_request_adapter::PlanningRequestAdapterChain::adaptAndPlan(const planning_interface::PlannerManagerPtr &planner,
00149                                                                          const planning_scene::PlanningSceneConstPtr& planning_scene,
00150                                                                          const planning_interface::MotionPlanRequest &req,
00151                                                                          planning_interface::MotionPlanResponse &res,
00152                                                                          std::vector<std::size_t> &added_path_index) const
00153 {
00154   // if there are no adapters, run the planner directly
00155   if (adapters_.empty())
00156   {
00157     added_path_index.clear();
00158     return callPlannerInterfaceSolve(planner.get(), planning_scene, req, res);
00159   }
00160   else
00161   {
00162     // the index values added by each adapter
00163     std::vector<std::vector<std::size_t> > added_path_index_each(adapters_.size());
00164 
00165     // if there are adapters, construct a function pointer for each, in order,
00166     // so that in the end we have a nested sequence of function pointers that call the adapters in the correct order.
00167     PlanningRequestAdapter::PlannerFn fn = boost::bind(&callAdapter1, adapters_.back().get(), planner, _1, _2, _3, boost::ref(added_path_index_each.back()));
00168     for (int i = adapters_.size() - 2 ; i >= 0 ; --i)
00169       fn = boost::bind(&callAdapter2, adapters_[i].get(), fn, _1, _2, _3, boost::ref(added_path_index_each[i]));
00170     bool result = fn(planning_scene, req, res);
00171     added_path_index.clear();
00172 
00173     // merge the index values from each adapter
00174     for (std::size_t i = 0 ; i < added_path_index_each.size() ; ++i)
00175       for (std::size_t j = 0 ; j < added_path_index_each[i].size() ; ++j)
00176       {
00177         for (std::size_t k = 0 ; k < added_path_index.size() ; ++k)
00178           if (added_path_index_each[i][j] <= added_path_index[k])
00179             added_path_index[k]++;
00180         added_path_index.push_back(added_path_index_each[i][j]);
00181       }
00182     std::sort(added_path_index.begin(), added_path_index.end());
00183     return result;
00184   }
00185 }


moveit_core
Author(s): Ioan Sucan , Sachin Chitta , Acorn Pooley
autogenerated on Mon Oct 6 2014 02:24:47