moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
planning_context_manager.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2012, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Ioan Sucan */
36
40
41#include <utility>
42
43#include <ompl/geometric/planners/AnytimePathShortening.h>
44#include <ompl/geometric/planners/rrt/RRT.h>
45#include <ompl/geometric/planners/rrt/pRRT.h>
46#include <ompl/geometric/planners/rrt/RRTConnect.h>
47#include <ompl/geometric/planners/rrt/TRRT.h>
48#include <ompl/geometric/planners/rrt/LazyRRT.h>
49#include <ompl/geometric/planners/est/EST.h>
50#include <ompl/geometric/planners/sbl/SBL.h>
51#include <ompl/geometric/planners/sbl/pSBL.h>
52#include <ompl/geometric/planners/kpiece/KPIECE1.h>
53#include <ompl/geometric/planners/kpiece/BKPIECE1.h>
54#include <ompl/geometric/planners/kpiece/LBKPIECE1.h>
55#include <ompl/geometric/planners/rrt/RRTstar.h>
56#include <ompl/geometric/planners/prm/PRM.h>
57#include <ompl/geometric/planners/prm/PRMstar.h>
58#include <ompl/geometric/planners/fmt/FMT.h>
59#include <ompl/geometric/planners/fmt/BFMT.h>
60#include <ompl/geometric/planners/pdst/PDST.h>
61#include <ompl/geometric/planners/stride/STRIDE.h>
62#include <ompl/geometric/planners/rrt/BiTRRT.h>
63#include <ompl/geometric/planners/rrt/LBTRRT.h>
64#include <ompl/geometric/planners/est/BiEST.h>
65#include <ompl/geometric/planners/est/ProjEST.h>
66#include <ompl/geometric/planners/prm/LazyPRM.h>
67#include <ompl/geometric/planners/prm/LazyPRMstar.h>
68#include <ompl/geometric/planners/prm/SPARS.h>
69#include <ompl/geometric/planners/prm/SPARStwo.h>
70
71#include <ompl/base/ConstrainedSpaceInformation.h>
72#include <ompl/base/spaces/constraint/ProjectedStateSpace.h>
73
80
81using namespace std::placeholders;
82
83namespace ompl_interface
84{
85namespace
86{
87rclcpp::Logger getLogger()
88{
89 return moveit::getLogger("moveit.planners.ompl.planning_context_manager");
90}
91} // namespace
92
94{
95 std::map<std::pair<std::string, std::string>, std::vector<ModelBasedPlanningContextPtr> > contexts_;
96 std::mutex lock_;
97};
98
100{
101 // Store all planner data
102 for (const auto& entry : planner_data_storage_paths_)
103 {
104 ob::PlannerData data(planners_[entry.first]->getSpaceInformation());
105 planners_[entry.first]->getPlannerData(data);
106 RCLCPP_INFO_STREAM(getLogger(), "Storing planner data. NumEdges: " << data.numEdges()
107 << ", NumVertices: " << data.numVertices());
108 storage_.store(data, entry.second.c_str());
109 }
110}
111
112template <typename T>
113ompl::base::PlannerPtr MultiQueryPlannerAllocator::allocatePlanner(const ob::SpaceInformationPtr& si,
114 const std::string& new_name,
116{
117 // Store planner instance if multi-query planning is enabled
118 auto cfg = spec.config_;
119 auto it = cfg.find("multi_query_planning_enabled");
120 bool multi_query_planning_enabled = false;
121 if (it != cfg.end())
122 {
123 multi_query_planning_enabled = boost::lexical_cast<bool>(it->second);
124 cfg.erase(it);
125 }
126 if (multi_query_planning_enabled)
127 {
128 // If we already have an instance, reuse it's planning data
129 // FIXME: make reusing PlannerPtr not crash, so that we don't have to reconstruct a PlannerPtr instance
130 auto planner_map_it = planners_.find(new_name);
131 if (planner_map_it != planners_.end())
132 {
133 ob::PlannerData data(si);
134 planner_map_it->second->getPlannerData(data);
135 RCLCPP_INFO_STREAM(getLogger(), "Reusing planner data. NumEdges: " << data.numEdges()
136 << ", NumVertices: " << data.numVertices());
137 planners_[planner_map_it->first] = std::shared_ptr<ob::Planner>{ allocatePersistentPlanner<T>(data) };
138 return planners_[planner_map_it->first];
139 }
140
141 // Certain multi-query planners allow loading and storing the generated planner data. This feature can be
142 // selectively enabled for loading and storing using the bool parameters 'load_planner_data' and
143 // 'store_planner_data'. The storage file path is set using the parameter 'planner_data_path'.
144 // File read and write access are handled by the PlannerDataStorage class. If the file path is invalid
145 // an error message is printed and the planner is constructed/destructed with default values.
146 it = cfg.find("load_planner_data");
147 bool load_planner_data = false;
148 if (it != cfg.end())
149 {
150 load_planner_data = boost::lexical_cast<bool>(it->second);
151 cfg.erase(it);
152 }
153 it = cfg.find("store_planner_data");
154 bool store_planner_data = false;
155 if (it != cfg.end())
156 {
157 store_planner_data = boost::lexical_cast<bool>(it->second);
158 cfg.erase(it);
159 }
160 it = cfg.find("planner_data_path");
161 std::string planner_data_path;
162 if (it != cfg.end())
163 {
164 planner_data_path = it->second;
165 cfg.erase(it);
166 }
167 // Store planner instance for multi-query use
168 planners_[new_name] =
169 allocatePlannerImpl<T>(si, new_name, spec, load_planner_data, store_planner_data, planner_data_path);
170 return planners_[new_name];
171 }
172 else
173 {
174 // Return single-shot planner instance
175 return allocatePlannerImpl<T>(si, new_name, spec);
176 }
177}
178
179template <typename T>
180ompl::base::PlannerPtr
181MultiQueryPlannerAllocator::allocatePlannerImpl(const ob::SpaceInformationPtr& si, const std::string& new_name,
183 bool load_planner_data, bool store_planner_data,
184 const std::string& file_path)
185{
186 ob::PlannerPtr planner;
187 // Try to initialize planner with loaded planner data
188 if (load_planner_data)
189 {
190 ob::PlannerData data(si);
191 storage_.load(file_path.c_str(), data);
192 RCLCPP_INFO_STREAM(getLogger(), "Loading planner data. NumEdges: " << data.numEdges()
193 << ", NumVertices: " << data.numVertices());
194 planner = std::shared_ptr<ob::Planner>{ allocatePersistentPlanner<T>(data) };
195 if (!planner)
196 {
197 RCLCPP_ERROR(getLogger(),
198 "Creating a '%s' planner from persistent data is not supported. Going to create a new instance.",
199 new_name.c_str());
200 }
201 }
202
203 if (!planner)
204 {
205 planner = std::make_shared<T>(si);
206 }
207
208 if (!new_name.empty())
209 {
210 planner->setName(new_name);
211 }
212
213 planner->params().setParams(spec.config_, true);
214 // Remember which planner instances to store when the destructor is called
215 if (store_planner_data)
216 {
217 planner_data_storage_paths_[new_name] = file_path;
218 }
219
220 return planner;
221}
222
223// default implementation
224template <typename T>
225inline ompl::base::Planner* MultiQueryPlannerAllocator::allocatePersistentPlanner(const ob::PlannerData& /*data*/)
226{
227 return nullptr;
228};
229template <>
230inline ompl::base::Planner*
231MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::PRM>(const ob::PlannerData& data)
232{
233 return new og::PRM(data);
234};
235template <>
236inline ompl::base::Planner*
237MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::PRMstar>(const ob::PlannerData& data)
238{
239 return new og::PRMstar(data);
240};
241template <>
242inline ompl::base::Planner*
243MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::LazyPRM>(const ob::PlannerData& data)
244{
245 return new og::LazyPRM(data);
246};
247template <>
248inline ompl::base::Planner*
249MultiQueryPlannerAllocator::allocatePersistentPlanner<ompl::geometric::LazyPRMstar>(const ob::PlannerData& data)
250{
251 return new og::LazyPRMstar(data);
252};
253
254PlanningContextManager::PlanningContextManager(moveit::core::RobotModelConstPtr robot_model,
255 constraint_samplers::ConstraintSamplerManagerPtr csm)
256 : robot_model_(std::move(robot_model))
257 , constraint_sampler_manager_(std::move(csm))
258 , max_goal_samples_(10)
259 , max_state_sampling_attempts_(4)
260 , max_goal_sampling_attempts_(1000)
261 , max_planning_threads_(4)
262 , max_solution_segment_length_(0.0)
263 , minimum_waypoint_count_(2)
264{
265 cached_contexts_ = std::make_shared<CachedContexts>();
268}
269
271
273{
274 auto it = known_planners_.find(planner);
275 if (it != known_planners_.end())
276 {
277 return it->second;
278 }
279 else
280 {
281 RCLCPP_ERROR(getLogger(), "Unknown planner: '%s'", planner.c_str());
283 }
284}
285
286template <typename T>
288{
289 registerPlannerAllocator(planner_id, [&](const ob::SpaceInformationPtr& si, const std::string& new_name,
291 return planner_allocator_.allocatePlanner<T>(si, new_name, spec);
292 });
293}
294
296{
297 registerPlannerAllocatorHelper<og::AnytimePathShortening>("geometric::AnytimePathShortening");
298 registerPlannerAllocatorHelper<og::BFMT>("geometric::BFMT");
299 registerPlannerAllocatorHelper<og::BiEST>("geometric::BiEST");
300 registerPlannerAllocatorHelper<og::BiTRRT>("geometric::BiTRRT");
301 registerPlannerAllocatorHelper<og::BKPIECE1>("geometric::BKPIECE");
302 registerPlannerAllocatorHelper<og::EST>("geometric::EST");
303 registerPlannerAllocatorHelper<og::FMT>("geometric::FMT");
304 registerPlannerAllocatorHelper<og::KPIECE1>("geometric::KPIECE");
305 registerPlannerAllocatorHelper<og::LazyPRM>("geometric::LazyPRM");
306 registerPlannerAllocatorHelper<og::LazyPRMstar>("geometric::LazyPRMstar");
307 registerPlannerAllocatorHelper<og::LazyRRT>("geometric::LazyRRT");
308 registerPlannerAllocatorHelper<og::LBKPIECE1>("geometric::LBKPIECE");
309 registerPlannerAllocatorHelper<og::LBTRRT>("geometric::LBTRRT");
310 registerPlannerAllocatorHelper<og::PDST>("geometric::PDST");
311 registerPlannerAllocatorHelper<og::PRM>("geometric::PRM");
312 registerPlannerAllocatorHelper<og::PRMstar>("geometric::PRMstar");
313 registerPlannerAllocatorHelper<og::ProjEST>("geometric::ProjEST");
314 registerPlannerAllocatorHelper<og::RRT>("geometric::RRT");
315 registerPlannerAllocatorHelper<og::RRTConnect>("geometric::RRTConnect");
316 registerPlannerAllocatorHelper<og::RRTstar>("geometric::RRTstar");
317 registerPlannerAllocatorHelper<og::SBL>("geometric::SBL");
318 registerPlannerAllocatorHelper<og::SPARS>("geometric::SPARS");
319 registerPlannerAllocatorHelper<og::SPARStwo>("geometric::SPARStwo");
320 registerPlannerAllocatorHelper<og::STRIDE>("geometric::STRIDE");
321 registerPlannerAllocatorHelper<og::TRRT>("geometric::TRRT");
322}
323
325{
326 registerStateSpaceFactory(std::make_shared<JointModelStateSpaceFactory>());
327 registerStateSpaceFactory(std::make_shared<PoseModelStateSpaceFactory>());
328 registerStateSpaceFactory(std::make_shared<ConstrainedPlanningStateSpaceFactory>());
329}
330
332{
333 return [this](const std::string& planner) { return plannerSelector(planner); };
334}
335
340
341ModelBasedPlanningContextPtr
343 const ModelBasedStateSpaceFactoryPtr& factory,
344 const moveit_msgs::msg::MotionPlanRequest& req) const
345{
346 // Check for a cached planning context
347 ModelBasedPlanningContextPtr context;
348
349 {
350 std::unique_lock<std::mutex> slock(cached_contexts_->lock_);
351 auto cached_contexts = cached_contexts_->contexts_.find(std::make_pair(config.name, factory->getType()));
352 if (cached_contexts != cached_contexts_->contexts_.end())
353 {
354 for (const ModelBasedPlanningContextPtr& cached_context : cached_contexts->second)
355 {
356 if (cached_context.unique())
357 {
358 RCLCPP_DEBUG(getLogger(), "Reusing cached planning context");
359 context = cached_context;
360 break;
361 }
362 }
363 }
364 }
365
366 // Create a new planning context
367 if (!context)
368 {
371 context_spec.config_ = config.config;
372 context_spec.planner_selector_ = getPlannerSelector();
374 context_spec.state_space_ = factory->getNewStateSpace(space_spec);
375
377 {
378 RCLCPP_DEBUG_STREAM(getLogger(), "planning_context_manager: Using OMPL's constrained state space for planning.");
379
380 // Select the correct type of constraints based on the path constraints in the planning request.
381 ompl::base::ConstraintPtr ompl_constraint =
382 createOMPLConstraints(robot_model_, config.group, req.path_constraints);
383
384 // Fail if ompl constraints could not be parsed successfully
385 if (!ompl_constraint)
386 {
387 return ModelBasedPlanningContextPtr();
388 }
389
390 // Create a constrained state space of type "projected state space".
391 // Other types are available, so we probably should add another setting to ompl_planning.yaml
392 // to choose between them.
393 context_spec.constrained_state_space_ =
394 std::make_shared<ob::ProjectedStateSpace>(context_spec.state_space_, ompl_constraint);
395
396 // Pass the constrained state space to ompl simple setup through the creation of a
397 // ConstrainedSpaceInformation object. This makes sure the state space is properly initialized.
398 context_spec.ompl_simple_setup_ = std::make_shared<ompl::geometric::SimpleSetup>(
399 std::make_shared<ob::ConstrainedSpaceInformation>(context_spec.constrained_state_space_));
400 }
401 else
402 {
403 // Choose the correct simple setup type to load
404 context_spec.ompl_simple_setup_ = std::make_shared<ompl::geometric::SimpleSetup>(context_spec.state_space_);
405 }
406
407 RCLCPP_DEBUG(getLogger(), "Creating new planning context");
408 context = std::make_shared<ModelBasedPlanningContext>(config.name, context_spec);
409
410 // Do not cache a constrained planning context, as the constraints could be changed
411 // and need to be parsed again.
413 {
414 {
415 std::lock_guard<std::mutex> slock(cached_contexts_->lock_);
416 cached_contexts_->contexts_[std::make_pair(config.name, factory->getType())].push_back(context);
417 }
418 }
419 }
420
421 context->setMaximumPlanningThreads(max_planning_threads_);
422 context->setMaximumGoalSamples(max_goal_samples_);
423 context->setMaximumStateSamplingAttempts(max_state_sampling_attempts_);
424 context->setMaximumGoalSamplingAttempts(max_goal_sampling_attempts_);
425
426 if (max_solution_segment_length_ > std::numeric_limits<double>::epsilon())
427 {
428 context->setMaximumSolutionSegmentLength(max_solution_segment_length_);
429 }
430
431 context->setMinimumWaypointCount(minimum_waypoint_count_);
432 context->setSpecificationConfig(config.config);
433
434 return context;
435}
436
437const ModelBasedStateSpaceFactoryPtr& PlanningContextManager::getStateSpaceFactory(const std::string& factory_type) const
438{
439 auto f = factory_type.empty() ? state_space_factories_.begin() : state_space_factories_.find(factory_type);
440 if (f != state_space_factories_.end())
441 {
442 RCLCPP_DEBUG(getLogger(), "Using '%s' parameterization for solving problem", factory_type.c_str());
443 return f->second;
444 }
445 else
446 {
447 RCLCPP_ERROR(getLogger(), "Factory of type '%s' was not found", factory_type.c_str());
448 static const ModelBasedStateSpaceFactoryPtr EMPTY;
449 return EMPTY;
450 }
451}
452
453const ModelBasedStateSpaceFactoryPtr&
455 const moveit_msgs::msg::MotionPlanRequest& req) const
456{
457 // find the problem representation to use
458 auto best = state_space_factories_.end();
459 int prev_priority = 0;
460 for (auto it = state_space_factories_.begin(); it != state_space_factories_.end(); ++it)
461 {
462 int priority = it->second->canRepresentProblem(group, req, robot_model_);
463 if (priority > prev_priority)
464 {
465 best = it;
466 prev_priority = priority;
467 }
468 }
469
470 if (best == state_space_factories_.end())
471 {
472 RCLCPP_ERROR(getLogger(), "There are no known state spaces that can represent the given planning "
473 "problem");
474 static const ModelBasedStateSpaceFactoryPtr EMPTY;
475 return EMPTY;
476 }
477 else
478 {
479 RCLCPP_DEBUG(getLogger(), "Using '%s' parameterization for solving problem", best->first.c_str());
480 return best->second;
481 }
482}
483
485 const planning_scene::PlanningSceneConstPtr& planning_scene, const moveit_msgs::msg::MotionPlanRequest& req,
486 moveit_msgs::msg::MoveItErrorCodes& error_code, const rclcpp::Node::SharedPtr& node,
487 bool use_constraints_approximation) const
488{
489 if (req.group_name.empty())
490 {
491 RCLCPP_ERROR(getLogger(), "No group specified to plan for");
492 error_code.val = moveit_msgs::msg::MoveItErrorCodes::INVALID_GROUP_NAME;
493 return ModelBasedPlanningContextPtr();
494 }
495
496 error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
497
498 if (!planning_scene)
499 {
500 RCLCPP_ERROR(getLogger(), "No planning scene supplied as input");
501 return ModelBasedPlanningContextPtr();
502 }
503
504 // identify the correct planning configuration
505 auto pc = planner_configs_.end();
506 if (!req.planner_id.empty())
507 {
508 pc = planner_configs_.find(req.planner_id.find(req.group_name) == std::string::npos ?
509 req.group_name + "[" + req.planner_id + "]" :
510 req.planner_id);
511 if (pc == planner_configs_.end())
512 {
513 RCLCPP_WARN(getLogger(),
514 "Cannot find planning configuration for group '%s' using planner '%s'. Will use defaults instead.",
515 req.group_name.c_str(), req.planner_id.c_str());
516 }
517 }
518
519 if (pc == planner_configs_.end())
520 {
521 pc = planner_configs_.find(req.group_name);
522 if (pc == planner_configs_.end())
523 {
524 RCLCPP_ERROR(getLogger(), "Cannot find planning configuration for group '%s'", req.group_name.c_str());
525 return ModelBasedPlanningContextPtr();
526 }
527 }
528
529 // State space selection process
530 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
531 // There are 3 options for the factory_selector
532 // 1) enforce_constrained_state_space = true AND there are path constraints in the planning request
533 // Overrides all other settings and selects a ConstrainedPlanningStateSpace factory
534 // 2) enforce_joint_model_state_space = true
535 // If 1) is false, then this one overrides the remaining settings and returns a JointModelStateSpace factory
536 // 3) Not 1) or 2), then the factory is selected based on the priority that each one returns.
537 // See PoseModelStateSpaceFactory::canRepresentProblem for details on the selection process.
538 // In short, it returns a PoseModelStateSpace if there is an IK solver and a path constraint.
539 //
540 // enforce_constrained_state_space
541 // ****************************************
542 // Check if the user wants to use an OMPL ConstrainedStateSpace for planning.
543 // This is done by setting 'enforce_constrained_state_space' to 'true' for the desired group in ompl_planing.yaml.
544 // If there are no path constraints in the planning request, this option is ignored, as the constrained state space is
545 // only useful for paths constraints. (And at the moment only a single position constraint is supported, hence:
546 // req.path_constraints.position_constraints.size() == 1
547 // is used in the selection process below.)
548 //
549 // enforce_joint_model_state_space
550 // *******************************
551 // Check if sampling in JointModelStateSpace is enforced for this group by user.
552 // This is done by setting 'enforce_joint_model_state_space' to 'true' for the desired group in ompl_planning.yaml.
553 //
554 // Some planning problems like orientation path constraints are represented in PoseModelStateSpace and sampled via IK.
555 // However consecutive IK solutions are not checked for proximity at the moment and sometimes happen to be flipped,
556 // leading to invalid trajectories. This workaround lets the user prevent this problem by forcing rejection sampling
557 // in JointModelStateSpace.
558 ModelBasedStateSpaceFactoryPtr factory;
559 auto constrained_planning_iterator = pc->second.config.find("enforce_constrained_state_space");
560 auto joint_space_planning_iterator = pc->second.config.find("enforce_joint_model_state_space");
561
562 // Use ConstrainedPlanningStateSpace if there is exactly one position constraint and/or one orientation constraint
563 if (constrained_planning_iterator != pc->second.config.end() &&
564 boost::lexical_cast<bool>(constrained_planning_iterator->second) &&
565 ((req.path_constraints.position_constraints.size() == 1) ||
566 (req.path_constraints.orientation_constraints.size() == 1)))
567 {
569 }
570 else if (joint_space_planning_iterator != pc->second.config.end() &&
571 boost::lexical_cast<bool>(joint_space_planning_iterator->second))
572 {
574 }
575 else
576 {
577 factory = getStateSpaceFactory(pc->second.group, req);
578 }
579
580 ModelBasedPlanningContextPtr context = getPlanningContext(pc->second, factory, req);
581
582 if (context)
583 {
584 context->clear();
585
586 moveit::core::RobotStatePtr start_state = planning_scene->getCurrentStateUpdated(req.start_state);
587
588 // Setup the context
589 context->setPlanningScene(planning_scene);
590 context->setMotionPlanRequest(req);
591 context->setCompleteInitialState(*start_state);
592
593 context->setPlanningVolume(req.workspace_parameters);
594 if (!context->setPathConstraints(req.path_constraints, &error_code))
595 {
596 return ModelBasedPlanningContextPtr();
597 }
598
599 if (!context->setGoalConstraints(req.goal_constraints, req.path_constraints, &error_code))
600 {
601 return ModelBasedPlanningContextPtr();
602 }
603
604 try
605 {
606 context->configure(node, use_constraints_approximation);
607 RCLCPP_DEBUG(getLogger(), "%s: New planning context is set.", context->getName().c_str());
608 error_code.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
609 }
610 catch (ompl::Exception& ex)
611 {
612 RCLCPP_ERROR(getLogger(), "OMPL encountered an error: %s", ex.what());
613 context.reset();
614 }
615 }
616
617 return context;
618}
619} // namespace ompl_interface
ob::PlannerPtr allocatePlanner(const ob::SpaceInformationPtr &si, const std::string &new_name, const ModelBasedPlanningContextSpecification &spec)
planning_interface::PlannerConfigurationMap planner_configs_
All the existing planning configurations. The name of the configuration is the key of the map....
const ModelBasedStateSpaceFactoryPtr & getStateSpaceFactory(const std::string &factory_type) const
unsigned int max_goal_sampling_attempts_
maximum number of attempts to be made at sampling goals
PlanningContextManager(moveit::core::RobotModelConstPtr robot_model, constraint_samplers::ConstraintSamplerManagerPtr csm)
std::map< std::string, ConfiguredPlannerAllocator > known_planners_
void registerPlannerAllocator(const std::string &planner_id, const ConfiguredPlannerAllocator &pa)
ModelBasedPlanningContextPtr getPlanningContext(const planning_scene::PlanningSceneConstPtr &planning_scene, const planning_interface::MotionPlanRequest &req, moveit_msgs::msg::MoveItErrorCodes &error_code, const rclcpp::Node::SharedPtr &node, bool use_constraints_approximations) const
Returns a planning context to OMPLInterface, which in turn passes it to OMPLPlannerManager.
constraint_samplers::ConstraintSamplerManagerPtr constraint_sampler_manager_
unsigned int max_planning_threads_
when planning in parallel, this is the maximum number of threads to use at one time
unsigned int max_goal_samples_
maximum number of states to sample in the goal region for any planning request (when such sampling is...
moveit::core::RobotModelConstPtr robot_model_
The kinematic model for which motion plans are computed.
ConfiguredPlannerSelector getPlannerSelector() const
std::map< std::string, ModelBasedStateSpaceFactoryPtr > state_space_factories_
void setPlannerConfigurations(const planning_interface::PlannerConfigurationMap &pconfig)
Specify configurations for the planners.
ConfiguredPlannerAllocator plannerSelector(const std::string &planner) const
void registerPlannerAllocatorHelper(const std::string &planner_id)
MultiQueryPlannerAllocator planner_allocator_
Multi-query planner allocator.
void registerStateSpaceFactory(const ModelBasedStateSpaceFactoryPtr &factory)
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition logger.cpp:79
The MoveIt interface to OMPL.
std::function< ob::PlannerPtr(const ompl::base::SpaceInformationPtr &si, const std::string &name, const ModelBasedPlanningContextSpecification &spec)> ConfiguredPlannerAllocator
ompl::base::ConstraintPtr createOMPLConstraints(const moveit::core::RobotModelConstPtr &robot_model, const std::string &group, const moveit_msgs::msg::Constraints &constraints)
Factory to create constraints based on what is in the MoveIt constraint message.
std::function< ConfiguredPlannerAllocator(const std::string &planner_type)> ConfiguredPlannerSelector
std::map< std::string, PlannerConfigurationSettings > PlannerConfigurationMap
Map from PlannerConfigurationSettings.name to PlannerConfigurationSettings.
This namespace includes the central class for representing planning contexts.
constraint_samplers::ConstraintSamplerManagerPtr constraint_sampler_manager_
ob::ConstrainedStateSpacePtr constrained_state_space_
OMPL constrained state space to handle path constraints.
std::map< std::pair< std::string, std::string >, std::vector< ModelBasedPlanningContextPtr > > contexts_
Specify the settings for a particular planning algorithm, for a particular group. The Planner plugin ...
std::map< std::string, std::string > config
Key-value pairs of settings that get passed to the planning algorithm.
std::string group
The group (as defined in the SRDF) this configuration is meant for.