43 #include <ompl/config.h>
45 #include <ompl/geometric/planners/AnytimePathShortening.h>
46 #include <ompl/geometric/planners/rrt/RRT.h>
47 #include <ompl/geometric/planners/rrt/pRRT.h>
48 #include <ompl/geometric/planners/rrt/RRTConnect.h>
49 #include <ompl/geometric/planners/rrt/TRRT.h>
50 #include <ompl/geometric/planners/rrt/LazyRRT.h>
51 #include <ompl/geometric/planners/est/EST.h>
52 #include <ompl/geometric/planners/sbl/SBL.h>
53 #include <ompl/geometric/planners/sbl/pSBL.h>
54 #include <ompl/geometric/planners/kpiece/KPIECE1.h>
55 #include <ompl/geometric/planners/kpiece/BKPIECE1.h>
56 #include <ompl/geometric/planners/kpiece/LBKPIECE1.h>
57 #include <ompl/geometric/planners/rrt/RRTstar.h>
58 #include <ompl/geometric/planners/prm/PRM.h>
59 #include <ompl/geometric/planners/prm/PRMstar.h>
60 #include <ompl/geometric/planners/fmt/FMT.h>
61 #include <ompl/geometric/planners/fmt/BFMT.h>
62 #include <ompl/geometric/planners/pdst/PDST.h>
63 #include <ompl/geometric/planners/stride/STRIDE.h>
64 #include <ompl/geometric/planners/rrt/BiTRRT.h>
65 #include <ompl/geometric/planners/rrt/LBTRRT.h>
66 #include <ompl/geometric/planners/est/BiEST.h>
67 #include <ompl/geometric/planners/est/ProjEST.h>
68 #include <ompl/geometric/planners/prm/LazyPRM.h>
69 #include <ompl/geometric/planners/prm/LazyPRMstar.h>
70 #include <ompl/geometric/planners/prm/SPARS.h>
71 #include <ompl/geometric/planners/prm/SPARStwo.h>
72 #include <ompl/geometric/planners/informedtrees/AITstar.h>
73 #include <ompl/geometric/planners/informedtrees/ABITstar.h>
74 #include <ompl/geometric/planners/informedtrees/BITstar.h>
80 using namespace std::placeholders;
84 constexpr
char LOGNAME[] =
"planning_context_manager";
88 std::map<std::pair<std::string, std::string>, std::vector<ModelBasedPlanningContextPtr> >
contexts_;
97 for (
const auto& entry : planner_data_storage_paths_)
100 ob::PlannerData data(planners_[entry.first]->getSpaceInformation());
101 planners_[entry.first]->getPlannerData(data);
102 storage_.store(data, entry.second.c_str());
106 template <
typename T>
112 auto it = cfg.find(
"multi_query_planning_enabled");
113 bool multi_query_planning_enabled =
false;
116 multi_query_planning_enabled = boost::lexical_cast<bool>(it->second);
119 if (multi_query_planning_enabled)
122 auto planner_map_it = planners_.find(new_name);
123 if (planner_map_it != planners_.end())
124 return planner_map_it->second;
131 it = cfg.find(
"load_planner_data");
132 bool load_planner_data =
false;
135 load_planner_data = boost::lexical_cast<bool>(it->second);
138 it = cfg.find(
"store_planner_data");
139 bool store_planner_data =
false;
142 store_planner_data = boost::lexical_cast<bool>(it->second);
145 it = cfg.find(
"planner_data_path");
146 std::string planner_data_path;
149 planner_data_path = it->second;
153 planners_[new_name] =
154 allocatePlannerImpl<T>(si, new_name, spec, load_planner_data, store_planner_data, planner_data_path);
155 return planners_[new_name];
160 return allocatePlannerImpl<T>(si, new_name, spec);
164 template <
typename T>
167 bool load_planner_data,
bool store_planner_data,
const std::string& file_path)
169 ob::PlannerPtr planner;
171 if (load_planner_data)
174 ob::PlannerData data(si);
175 storage_.load(file_path.c_str(), data);
176 planner = std::shared_ptr<ob::Planner>{ allocatePersistentPlanner<T>(data) };
179 "Creating a '%s' planner from persistent data is not supported. Going to create a new instance.",
183 planner = std::make_shared<T>(si);
184 if (!new_name.empty())
185 planner->setName(new_name);
186 planner->params().setParams(spec.
config_,
true);
188 if (store_planner_data)
189 planner_data_storage_paths_[new_name] = file_path;
194 template <
typename T>
195 inline ompl::base::Planner*
204 inline ompl::base::Planner*
205 MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::PRM>(
const ob::PlannerData& data)
207 return new og::PRM(data);
210 inline ompl::base::Planner*
211 MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::PRMstar>(
const ob::PlannerData& data)
213 return new og::PRMstar(data);
216 inline ompl::base::Planner*
217 MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::LazyPRM>(
const ob::PlannerData& data)
219 return new og::LazyPRM(data);
222 inline ompl::base::Planner*
223 MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::LazyPRMstar>(
const ob::PlannerData& data)
225 return new og::LazyPRMstar(data);
230 constraint_samplers::ConstraintSamplerManagerPtr csm)
231 : robot_model_(
std::move(robot_model))
232 , constraint_sampler_manager_(
std::move(csm))
233 , max_goal_samples_(10)
234 , max_state_sampling_attempts_(4)
235 , max_goal_sampling_attempts_(1000)
236 , max_planning_threads_(4)
237 , max_solution_segment_length_(0.0)
238 , minimum_waypoint_count_(2)
250 auto it = known_planners_.find(planner);
251 if (it != known_planners_.end())
260 template <
typename T>
263 registerPlannerAllocator(planner_id, [&](
const ob::SpaceInformationPtr& si,
const std::string& new_name,
265 return planner_allocator_.allocatePlanner<T>(si, new_name, spec);
271 registerPlannerAllocatorHelper<og::AnytimePathShortening>(
"geometric::AnytimePathShortening");
272 registerPlannerAllocatorHelper<og::BFMT>(
"geometric::BFMT");
273 registerPlannerAllocatorHelper<og::BiEST>(
"geometric::BiEST");
274 registerPlannerAllocatorHelper<og::BiTRRT>(
"geometric::BiTRRT");
275 registerPlannerAllocatorHelper<og::BKPIECE1>(
"geometric::BKPIECE");
276 registerPlannerAllocatorHelper<og::EST>(
"geometric::EST");
277 registerPlannerAllocatorHelper<og::FMT>(
"geometric::FMT");
278 registerPlannerAllocatorHelper<og::KPIECE1>(
"geometric::KPIECE");
279 registerPlannerAllocatorHelper<og::LazyPRM>(
"geometric::LazyPRM");
280 registerPlannerAllocatorHelper<og::LazyPRMstar>(
"geometric::LazyPRMstar");
281 registerPlannerAllocatorHelper<og::LazyRRT>(
"geometric::LazyRRT");
282 registerPlannerAllocatorHelper<og::LBKPIECE1>(
"geometric::LBKPIECE");
283 registerPlannerAllocatorHelper<og::LBTRRT>(
"geometric::LBTRRT");
284 registerPlannerAllocatorHelper<og::PDST>(
"geometric::PDST");
285 registerPlannerAllocatorHelper<og::PRM>(
"geometric::PRM");
286 registerPlannerAllocatorHelper<og::PRMstar>(
"geometric::PRMstar");
287 registerPlannerAllocatorHelper<og::ProjEST>(
"geometric::ProjEST");
288 registerPlannerAllocatorHelper<og::RRT>(
"geometric::RRT");
289 registerPlannerAllocatorHelper<og::RRTConnect>(
"geometric::RRTConnect");
290 registerPlannerAllocatorHelper<og::RRTstar>(
"geometric::RRTstar");
291 registerPlannerAllocatorHelper<og::SBL>(
"geometric::SBL");
292 registerPlannerAllocatorHelper<og::SPARS>(
"geometric::SPARS");
293 registerPlannerAllocatorHelper<og::SPARStwo>(
"geometric::SPARStwo");
294 registerPlannerAllocatorHelper<og::STRIDE>(
"geometric::STRIDE");
295 registerPlannerAllocatorHelper<og::TRRT>(
"geometric::TRRT");
296 registerPlannerAllocatorHelper<og::AITstar>(
"geometric::AITstar");
297 registerPlannerAllocatorHelper<og::ABITstar>(
"geometric::ABITstar");
298 registerPlannerAllocatorHelper<og::BITstar>(
"geometric::BITstar");
309 return [
this](
const std::string& planner) {
return plannerSelector(planner); };
315 planner_configs_ = pconfig;
322 ModelBasedPlanningContextPtr context;
325 std::unique_lock<std::mutex> slock(cached_contexts_->lock_);
326 auto cached_contexts = cached_contexts_->contexts_.find(std::make_pair(config.
name, factory->getType()));
327 if (cached_contexts != cached_contexts_->contexts_.end())
329 for (
const ModelBasedPlanningContextPtr& cached_context : cached_contexts->second)
330 if (cached_context.unique())
333 context = cached_context;
347 context_spec.
state_space_ = factory->getNewStateSpace(space_spec);
353 context = std::make_shared<ModelBasedPlanningContext>(config.
name, context_spec);
355 std::unique_lock<std::mutex> slock(cached_contexts_->lock_);
356 cached_contexts_->contexts_[std::make_pair(config.
name, factory->getType())].push_back(context);
360 context->setMaximumPlanningThreads(max_planning_threads_);
361 context->setMaximumGoalSamples(max_goal_samples_);
362 context->setMaximumStateSamplingAttempts(max_state_sampling_attempts_);
363 context->setMaximumGoalSamplingAttempts(max_goal_sampling_attempts_);
364 if (max_solution_segment_length_ > std::numeric_limits<double>::epsilon())
365 context->setMaximumSolutionSegmentLength(max_solution_segment_length_);
366 context->setMinimumWaypointCount(minimum_waypoint_count_);
368 context->setSpecificationConfig(config.
config);
373 const ompl_interface::ModelBasedStateSpaceFactoryPtr&
376 auto f = factory_type.empty() ? state_space_factories_.begin() : state_space_factories_.find(factory_type);
377 if (
f != state_space_factories_.end())
382 static const ModelBasedStateSpaceFactoryPtr EMPTY;
387 const ompl_interface::ModelBasedStateSpaceFactoryPtr&
389 const moveit_msgs::MotionPlanRequest& req)
const
392 auto best = state_space_factories_.end();
393 int prev_priority = 0;
394 for (
auto it = state_space_factories_.begin(); it != state_space_factories_.end(); ++it)
396 int priority = it->second->canRepresentProblem(group, req, robot_model_);
397 if (priority > prev_priority)
400 prev_priority = priority;
404 if (best == state_space_factories_.end())
408 static const ModelBasedStateSpaceFactoryPtr EMPTY;
419 const planning_scene::PlanningSceneConstPtr&
planning_scene,
const moveit_msgs::MotionPlanRequest& req,
420 moveit_msgs::MoveItErrorCodes& error_code,
const ros::NodeHandle& nh,
bool use_constraints_approximation)
const
422 if (req.group_name.empty())
425 error_code.val = moveit_msgs::MoveItErrorCodes::INVALID_GROUP_NAME;
426 return ModelBasedPlanningContextPtr();
429 error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
434 return ModelBasedPlanningContextPtr();
438 auto pc = planner_configs_.end();
439 if (!req.planner_id.empty())
441 pc = planner_configs_.find(req.planner_id.find(req.group_name) == std::string::npos ?
442 req.group_name +
"[" + req.planner_id +
"]" :
444 if (pc == planner_configs_.end())
446 "Cannot find planning configuration for group '%s' using planner '%s'. Will use defaults instead.",
447 req.group_name.c_str(), req.planner_id.c_str());
450 if (pc == planner_configs_.end())
452 pc = planner_configs_.find(req.group_name);
453 if (pc == planner_configs_.end())
456 return ModelBasedPlanningContextPtr();
470 ModelBasedStateSpaceFactoryPtr factory;
471 auto it = pc->second.config.find(
"enforce_joint_model_state_space");
473 auto type_it = pc->second.config.find(
"type");
474 std::string planner_type;
475 if (type_it != pc->second.config.end())
476 planner_type = type_it->second;
478 if (it != pc->second.config.end() && boost::lexical_cast<bool>(it->second))
480 else if (planner_type ==
"geometric::AITstar")
482 else if (planner_type ==
"geometric::ABITstar")
484 else if (planner_type ==
"geometric::BITstar")
487 factory = getStateSpaceFactory(pc->second.group, req);
489 ModelBasedPlanningContextPtr context = getPlanningContext(pc->second, factory);
495 moveit::core::RobotStatePtr start_state =
planning_scene->getCurrentStateUpdated(req.start_state);
499 context->setMotionPlanRequest(req);
500 context->setCompleteInitialState(*start_state);
502 context->setPlanningVolume(req.workspace_parameters);
503 if (!context->setPathConstraints(req.path_constraints, &error_code))
504 return ModelBasedPlanningContextPtr();
506 if (!context->setGoalConstraints(req.goal_constraints, req.path_constraints, &error_code))
507 return ModelBasedPlanningContextPtr();
511 context->configure(nh, use_constraints_approximation);
513 error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
515 catch (ompl::Exception& ex)