PRM.cpp
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2011, Rice University
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 Rice University 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, James D. Marble, Ryan Luna */
36 
37 #include "ompl/geometric/planners/prm/PRM.h"
38 #include "ompl/geometric/planners/prm/ConnectionStrategy.h"
39 #include "ompl/base/goals/GoalSampleableRegion.h"
40 #include "ompl/base/objectives/PathLengthOptimizationObjective.h"
41 #include "ompl/datastructures/PDF.h"
42 #include "ompl/tools/config/SelfConfig.h"
43 #include "ompl/tools/config/MagicConstants.h"
44 #include <boost/graph/astar_search.hpp>
45 #include <boost/graph/incremental_components.hpp>
46 #include <boost/property_map/vector_property_map.hpp>
47 #include <boost/foreach.hpp>
48 #include <thread>
49 
50 #include "GoalVisitor.hpp"
51 
52 #define foreach BOOST_FOREACH
53 
54 namespace ompl
55 {
56  namespace magic
57  {
58 
61  static const unsigned int MAX_RANDOM_BOUNCE_STEPS = 5;
62 
64  static const double ROADMAP_BUILD_TIME = 0.2;
65 
68  static const unsigned int DEFAULT_NEAREST_NEIGHBORS = 10;
69  }
70 }
71 
73  base::Planner(si, "PRM"),
74  starStrategy_(starStrategy),
75  stateProperty_(boost::get(vertex_state_t(), g_)),
76  totalConnectionAttemptsProperty_(boost::get(vertex_total_connection_attempts_t(), g_)),
77  successfulConnectionAttemptsProperty_(boost::get(vertex_successful_connection_attempts_t(), g_)),
78  weightProperty_(boost::get(boost::edge_weight, g_)),
79  disjointSets_(boost::get(boost::vertex_rank, g_),
80  boost::get(boost::vertex_predecessor, g_)),
81  userSetConnectionStrategy_(false),
82  addedNewSolution_(false),
83  iterations_(0),
84  bestCost_(std::numeric_limits<double>::quiet_NaN())
85 {
88  specs_.optimizingPaths = true;
89  specs_.multithreaded = true;
90 
91  if (!starStrategy_)
92  Planner::declareParam<unsigned int>("max_nearest_neighbors", this, &PRM::setMaxNearestNeighbors, std::string("8:1000"));
93 
94  addPlannerProgressProperty("iterations INTEGER",
95  std::bind(&PRM::getIterationCount, this));
96  addPlannerProgressProperty("best cost REAL",
97  std::bind(&PRM::getBestCost, this));
98  addPlannerProgressProperty("milestone count INTEGER",
99  std::bind(&PRM::getMilestoneCountString, this));
100  addPlannerProgressProperty("edge count INTEGER",
101  std::bind(&PRM::getEdgeCountString, this));
102 }
103 
104 ompl::geometric::PRM::~PRM()
105 {
106  freeMemory();
107 }
108 
110 {
111  Planner::setup();
112  if (!nn_)
113  {
114  specs_.multithreaded = false; // temporarily set to false since nn_ is used only in single thread
115  nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Vertex>(this));
116  specs_.multithreaded = true;
117  nn_->setDistanceFunction(std::bind(&PRM::distanceFunction, this, std::placeholders::_1, std::placeholders::_2));
118  }
119  if (!connectionStrategy_)
120  {
121  if (starStrategy_)
122  connectionStrategy_ = KStarStrategy<Vertex>(std::bind(&PRM::milestoneCount, this), nn_, si_->getStateDimension());
123  else
124  connectionStrategy_ = KStrategy<Vertex>(magic::DEFAULT_NEAREST_NEIGHBORS, nn_);
125  }
126  if (!connectionFilter_)
127  connectionFilter_ = [] (const Vertex&, const Vertex&) { return true; };
128 
129  // Setup optimization objective
130  //
131  // If no optimization objective was specified, then default to
132  // optimizing path length as computed by the distance() function
133  // in the state space.
134  if (pdef_)
135  {
136  if (pdef_->hasOptimizationObjective())
137  opt_ = pdef_->getOptimizationObjective();
138  else
139  {
140  opt_.reset(new base::PathLengthOptimizationObjective(si_));
141  if (!starStrategy_)
142  opt_->setCostThreshold(opt_->infiniteCost());
143  }
144  }
145  else
146  {
147  OMPL_INFORM("%s: problem definition is not set, deferring setup completion...", getName().c_str());
148  setup_ = false;
149  }
150 }
151 
153 {
154  if (starStrategy_)
155  throw Exception("Cannot set the maximum nearest neighbors for " + getName());
156  if (!nn_)
157  {
158  specs_.multithreaded = false; // temporarily set to false since nn_ is used only in single thread
159  nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Vertex>(this));
160  specs_.multithreaded = true;
161  nn_->setDistanceFunction(std::bind(&PRM::distanceFunction, this, std::placeholders::_1, std::placeholders::_2));
162  }
163  if (!userSetConnectionStrategy_)
164  connectionStrategy_ = ConnectionStrategy();
165  if (isSetup())
166  setup();
167 }
168 
170 {
171  Planner::setProblemDefinition(pdef);
172  clearQuery();
173 }
174 
176 {
177  startM_.clear();
178  goalM_.clear();
179  pis_.restart();
180 }
181 
183 {
184  Planner::clear();
185  sampler_.reset();
186  simpleSampler_.reset();
187  freeMemory();
188  if (nn_)
189  nn_->clear();
190  clearQuery();
191 
192  iterations_ = 0;
193  bestCost_ = base::Cost(std::numeric_limits<double>::quiet_NaN());
194 }
195 
197 {
198  foreach (Vertex v, boost::vertices(g_))
199  si_->freeState(stateProperty_[v]);
200  g_.clear();
201 }
202 
203 void ompl::geometric::PRM::expandRoadmap(double expandTime)
204 {
205  expandRoadmap(base::timedPlannerTerminationCondition(expandTime));
206 }
207 
209 {
210  if (!simpleSampler_)
211  simpleSampler_ = si_->allocStateSampler();
212 
213  std::vector<base::State*> states(magic::MAX_RANDOM_BOUNCE_STEPS);
214  si_->allocStates(states);
215  expandRoadmap(ptc, states);
216  si_->freeStates(states);
217 }
218 
220  std::vector<base::State*> &workStates)
221 {
222  // construct a probability distribution over the vertices in the roadmap
223  // as indicated in
224  // "Probabilistic Roadmaps for Path Planning in High-Dimensional Configuration Spaces"
225  // Lydia E. Kavraki, Petr Svestka, Jean-Claude Latombe, and Mark H. Overmars
226 
227  PDF<Vertex> pdf;
228  foreach (Vertex v, boost::vertices(g_))
229  {
230  const unsigned long int t = totalConnectionAttemptsProperty_[v];
231  pdf.add(v, (double)(t - successfulConnectionAttemptsProperty_[v]) / (double)t);
232  }
233 
234  if (pdf.empty())
235  return;
236 
237  while (ptc == false)
238  {
239  iterations_++;
240  Vertex v = pdf.sample(rng_.uniform01());
241  unsigned int s = si_->randomBounceMotion(simpleSampler_, stateProperty_[v], workStates.size(), workStates, false);
242  if (s > 0)
243  {
244  s--;
245  Vertex last = addMilestone(si_->cloneState(workStates[s]));
246 
247  graphMutex_.lock();
248  for (unsigned int i = 0 ; i < s ; ++i)
249  {
250  // add the vertex along the bouncing motion
251  Vertex m = boost::add_vertex(g_);
252  stateProperty_[m] = si_->cloneState(workStates[i]);
253  totalConnectionAttemptsProperty_[m] = 1;
254  successfulConnectionAttemptsProperty_[m] = 0;
255  disjointSets_.make_set(m);
256 
257  // add the edge to the parent vertex
258  const base::Cost weight = opt_->motionCost(stateProperty_[v], stateProperty_[m]);
259  const Graph::edge_property_type properties(weight);
260  boost::add_edge(v, m, properties, g_);
261  uniteComponents(v, m);
262 
263  // add the vertex to the nearest neighbors data structure
264  nn_->add(m);
265  v = m;
266  }
267 
268  // if there are intermediary states or the milestone has not been connected to the initially sampled vertex,
269  // we add an edge
270  if (s > 0 || !sameComponent(v, last))
271  {
272  // add the edge to the parent vertex
273  const base::Cost weight = opt_->motionCost(stateProperty_[v], stateProperty_[last]);
274  const Graph::edge_property_type properties(weight);
275  boost::add_edge(v, last, properties, g_);
276  uniteComponents(v, last);
277  }
278  graphMutex_.unlock();
279  }
280  }
281 }
282 
284 {
285  growRoadmap(base::timedPlannerTerminationCondition(growTime));
286 }
287 
289 {
290  if (!isSetup())
291  setup();
292  if (!sampler_)
293  sampler_ = si_->allocValidStateSampler();
294 
295  base::State *workState = si_->allocState();
296  growRoadmap (ptc, workState);
297  si_->freeState(workState);
298 }
299 
301  base::State *workState)
302 {
303  /* grow roadmap in the regular fashion -- sample valid states, add them to the roadmap, add valid connections */
304  while (ptc == false)
305  {
306  iterations_++;
307  // search for a valid state
308  bool found = false;
309  while (!found && ptc == false)
310  {
311  unsigned int attempts = 0;
312  do
313  {
314  found = sampler_->sample(workState);
315  attempts++;
316  } while (attempts < magic::FIND_VALID_STATE_ATTEMPTS_WITHOUT_TERMINATION_CHECK && !found);
317  }
318  // add it as a milestone
319  if (found)
320  addMilestone(si_->cloneState(workState));
321  }
322 }
323 
325  base::PathPtr &solution)
326 {
327  base::GoalSampleableRegion *goal = static_cast<base::GoalSampleableRegion*>(pdef_->getGoal().get());
328  while (!ptc && !addedNewSolution_)
329  {
330  // Check for any new goal states
331  if (goal->maxSampleCount() > goalM_.size())
332  {
333  const base::State *st = pis_.nextGoal();
334  if (st)
335  goalM_.push_back(addMilestone(si_->cloneState(st)));
336  }
337 
338  // Check for a solution
339  addedNewSolution_ = maybeConstructSolution(startM_, goalM_, solution);
340  // Sleep for 1ms
341  if (!addedNewSolution_)
342  std::this_thread::sleep_for(std::chrono::milliseconds(1));
343  }
344 }
345 
346 bool ompl::geometric::PRM::maybeConstructSolution(const std::vector<Vertex> &starts, const std::vector<Vertex> &goals, base::PathPtr &solution)
347 {
348  base::Goal *g = pdef_->getGoal().get();
349  base::Cost sol_cost(opt_->infiniteCost());
350  foreach (Vertex start, starts)
351  {
352  foreach (Vertex goal, goals)
353  {
354  // we lock because the connected components algorithm is incremental and may change disjointSets_
355  graphMutex_.lock();
356  bool same_component = sameComponent(start, goal);
357  graphMutex_.unlock();
358 
359  if (same_component && g->isStartGoalPairValid(stateProperty_[goal], stateProperty_[start]))
360  {
361  base::PathPtr p = constructSolution(start, goal);
362  if (p)
363  {
364  base::Cost pathCost = p->cost(opt_);
365  if (opt_->isCostBetterThan(pathCost, bestCost_))
366  bestCost_ = pathCost;
367  // Check if optimization objective is satisfied
368  if (opt_->isSatisfied(pathCost))
369  {
370  solution = p;
371  return true;
372  }
373  else if (opt_->isCostBetterThan(pathCost, sol_cost))
374  {
375  solution = p;
376  sol_cost = pathCost;
377  }
378  }
379  }
380  }
381  }
382 
383  return false;
384 }
385 
387 {
388  return addedNewSolution_;
389 }
390 
392 {
393  checkValidity();
394  base::GoalSampleableRegion *goal = dynamic_cast<base::GoalSampleableRegion*>(pdef_->getGoal().get());
395 
396  if (!goal)
397  {
398  OMPL_ERROR("%s: Unknown type of goal", getName().c_str());
400  }
401 
402  // Add the valid start states as milestones
403  while (const base::State *st = pis_.nextStart())
404  startM_.push_back(addMilestone(si_->cloneState(st)));
405 
406  if (startM_.size() == 0)
407  {
408  OMPL_ERROR("%s: There are no valid initial states!", getName().c_str());
410  }
411 
412  if (!goal->couldSample())
413  {
414  OMPL_ERROR("%s: Insufficient states in sampleable goal region", getName().c_str());
416  }
417 
418  // Ensure there is at least one valid goal state
419  if (goal->maxSampleCount() > goalM_.size() || goalM_.empty())
420  {
421  const base::State *st = goalM_.empty() ? pis_.nextGoal(ptc) : pis_.nextGoal();
422  if (st)
423  goalM_.push_back(addMilestone(si_->cloneState(st)));
424 
425  if (goalM_.empty())
426  {
427  OMPL_ERROR("%s: Unable to find any valid goal states", getName().c_str());
429  }
430  }
431 
432  unsigned long int nrStartStates = boost::num_vertices(g_);
433  OMPL_INFORM("%s: Starting planning with %lu states already in datastructure", getName().c_str(), nrStartStates);
434 
435  // Reset addedNewSolution_ member and create solution checking thread
436  addedNewSolution_ = false;
437  base::PathPtr sol;
438  std::thread slnThread(std::bind(&PRM::checkForSolution, this, ptc, boost::ref(sol)));
439 
440  // construct new planner termination condition that fires when the given ptc is true, or a solution is found
441  base::PlannerTerminationCondition ptcOrSolutionFound =
443 
444  constructRoadmap(ptcOrSolutionFound);
445 
446  // Ensure slnThread is ceased before exiting solve
447  slnThread.join();
448 
449  OMPL_INFORM("%s: Created %u states", getName().c_str(), boost::num_vertices(g_) - nrStartStates);
450 
451  if (sol)
452  {
453  base::PlannerSolution psol(sol);
454  psol.setPlannerName(getName());
455  // if the solution was optimized, we mark it as such
456  psol.setOptimized(opt_, bestCost_, addedNewSolution());
457  pdef_->addSolutionPath(psol);
458  }
459 
461 }
462 
464 {
465  if (!isSetup())
466  setup();
467  if (!sampler_)
468  sampler_ = si_->allocValidStateSampler();
469  if (!simpleSampler_)
470  simpleSampler_ = si_->allocStateSampler();
471 
472  std::vector<base::State*> xstates(magic::MAX_RANDOM_BOUNCE_STEPS);
473  si_->allocStates(xstates);
474  bool grow = true;
475 
476  bestCost_ = opt_->infiniteCost();
477  while (ptc() == false)
478  {
479  // maintain a 2:1 ratio for growing/expansion of roadmap
480  // call growRoadmap() twice as long for every call of expandRoadmap()
481  if (grow)
483  else
485  grow = !grow;
486  }
487 
488  si_->freeStates(xstates);
489 }
490 
492 {
493  std::lock_guard<std::mutex> _(graphMutex_);
494 
495  Vertex m = boost::add_vertex(g_);
496  stateProperty_[m] = state;
497  totalConnectionAttemptsProperty_[m] = 1;
498  successfulConnectionAttemptsProperty_[m] = 0;
499 
500  // Initialize to its own (dis)connected component.
501  disjointSets_.make_set(m);
502 
503  // Which milestones will we attempt to connect to?
504  const std::vector<Vertex>& neighbors = connectionStrategy_(m);
505 
506  foreach (Vertex n, neighbors)
507  if (connectionFilter_(n, m))
508  {
509  totalConnectionAttemptsProperty_[m]++;
510  totalConnectionAttemptsProperty_[n]++;
511  if (si_->checkMotion(stateProperty_[n], stateProperty_[m]))
512  {
513  successfulConnectionAttemptsProperty_[m]++;
514  successfulConnectionAttemptsProperty_[n]++;
515  const base::Cost weight = opt_->motionCost(stateProperty_[n], stateProperty_[m]);
516  const Graph::edge_property_type properties(weight);
517  boost::add_edge(n, m, properties, g_);
518  uniteComponents(n, m);
519  }
520  }
521 
522  nn_->add(m);
523 
524  return m;
525 }
526 
528 {
529  disjointSets_.union_set(m1, m2);
530 }
531 
533 {
534  return boost::same_component(m1, m2, disjointSets_);
535 }
536 
538 {
539  std::lock_guard<std::mutex> _(graphMutex_);
540  boost::vector_property_map<Vertex> prev(boost::num_vertices(g_));
541 
542  try
543  {
544  // Consider using a persistent distance_map if it's slow
545  boost::astar_search(g_, start,
546  std::bind(&PRM::costHeuristic, this, std::placeholders::_1, goal),
547  boost::predecessor_map(prev).
548  distance_compare(std::bind(&base::OptimizationObjective::
549  isCostBetterThan, opt_.get(), std::placeholders::_1, std::placeholders::_2)).
550  distance_combine(std::bind(&base::OptimizationObjective::
551  combineCosts, opt_.get(), std::placeholders::_1, std::placeholders::_2)).
552  distance_inf(opt_->infiniteCost()).
553  distance_zero(opt_->identityCost()).
554  visitor(AStarGoalVisitor<Vertex>(goal)));
555  }
556  catch (AStarFoundGoal&)
557  {
558  }
559 
560  if (prev[goal] == goal)
561  throw Exception(name_, "Could not find solution path");
562 
563  PathGeometric *p = new PathGeometric(si_);
564  for (Vertex pos = goal; prev[pos] != pos; pos = prev[pos])
565  p->append(stateProperty_[pos]);
566  p->append(stateProperty_[start]);
567  p->reverse();
568 
569  return base::PathPtr(p);
570 }
571 
573 {
574  Planner::getPlannerData(data);
575 
576  // Explicitly add start and goal states:
577  for (size_t i = 0; i < startM_.size(); ++i)
578  data.addStartVertex(base::PlannerDataVertex(stateProperty_[startM_[i]], const_cast<PRM*>(this)->disjointSets_.find_set(startM_[i])));
579 
580  for (size_t i = 0; i < goalM_.size(); ++i)
581  data.addGoalVertex(base::PlannerDataVertex(stateProperty_[goalM_[i]], const_cast<PRM*>(this)->disjointSets_.find_set(goalM_[i])));
582 
583  // Adding edges and all other vertices simultaneously
584  foreach(const Edge e, boost::edges(g_))
585  {
586  const Vertex v1 = boost::source(e, g_);
587  const Vertex v2 = boost::target(e, g_);
588  data.addEdge(base::PlannerDataVertex(stateProperty_[v1]),
589  base::PlannerDataVertex(stateProperty_[v2]));
590 
591  // Add the reverse edge, since we're constructing an undirected roadmap
592  data.addEdge(base::PlannerDataVertex(stateProperty_[v2]),
593  base::PlannerDataVertex(stateProperty_[v1]));
594 
595  // Add tags for the newly added vertices
596  data.tagState(stateProperty_[v1], const_cast<PRM*>(this)->disjointSets_.find_set(v1));
597  data.tagState(stateProperty_[v2], const_cast<PRM*>(this)->disjointSets_.find_set(v2));
598  }
599 }
600 
602 {
603  return opt_->motionCostHeuristic(stateProperty_[u], stateProperty_[v]);
604 }
PRM(const base::SpaceInformationPtr &si, bool starStrategy=false)
Constructor.
Definition: PRM.cpp:72
bool approximateSolutions
Flag indicating whether the planner is able to compute approximate solutions.
Definition: Planner.h:212
void addPlannerProgressProperty(const std::string &progressPropertyName, const PlannerProgressProperty &prop)
Add a planner progress property called progressPropertyName with a property querying function prop to...
Definition: Planner.h:392
Object containing planner generated vertex and edge data. It is assumed that all vertices are unique...
Definition: PlannerData.h:163
PlannerTerminationCondition plannerOrTerminationCondition(const PlannerTerminationCondition &c1, const PlannerTerminationCondition &c2)
Combine two termination conditions into one. If either termination condition returns true...
void clearQuery()
Clear the query previously loaded from the ProblemDefinition. Subsequent calls to solve() will reuse ...
Definition: PRM.cpp:175
void checkForSolution(const base::PlannerTerminationCondition &ptc, base::PathPtr &solution)
Definition: PRM.cpp:324
A shared pointer wrapper for ompl::base::ProblemDefinition.
The planner failed to find a solution.
Definition: PlannerStatus.h:62
Representation of a solution to a planning problem.
GoalType recognizedGoal
The type of goal specification the planner can use.
Definition: Planner.h:206
double distanceFunction(const Vertex a, const Vertex b) const
Compute distance between two milestones (this is simply distance between the states of the milestones...
Definition: PRM.h:317
void expandRoadmap(double expandTime)
Attempt to connect disjoint components in the roadmap using random bouncing motions (the PRM expansio...
Definition: PRM.cpp:203
bool sameComponent(Vertex m1, Vertex m2)
Check if two milestones (m1 and m2) are part of the same connected component. This is not a const fun...
Definition: PRM.cpp:532
unsigned int addGoalVertex(const PlannerDataVertex &v)
Adds the given vertex to the graph data, and marks it as a start vertex. The vertex index is returned...
Abstract definition of goals.
Definition: Goal.h:62
static const double ROADMAP_BUILD_TIME
The time in seconds for a single roadmap building operation (dt)
Definition: PRM.cpp:64
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
void growRoadmap(double growTime)
If the user desires, the roadmap can be improved for the given time (seconds). The solve() method wil...
Definition: PRM.cpp:283
void append(const base::State *state)
Append state to the end of this path. The memory for state is copied.
bool multithreaded
Flag indicating whether multiple threads are used in the computation of the planner.
Definition: Planner.h:209
void expandRoadmap(const base::PlannerTerminationCondition &ptc)
Attempt to connect disjoint components in the roadmap using random bouncing motions (the PRM expansio...
Definition: PRM.cpp:208
virtual void clear()
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
Definition: PRM.cpp:182
virtual base::PlannerStatus solve(const base::PlannerTerminationCondition &ptc)
Function that can solve the motion planning problem. Grows a roadmap using constructRoadmap(). This function can be called multiple times on the same problem, without calling clear() in between. This allows the planner to continue work for more time on an unsolved problem, for example. Start and goal states from the currently specified ProblemDefinition are cached. This means that between calls to solve(), input states are only added, not removed. When using PRM as a multi-query planner, the input states should be however cleared, without clearing the roadmap itself. This can be done using the clearQuery() function.
Definition: PRM.cpp:391
A container that supports probabilistic sampling over weighted data.
Definition: PDF.h:48
Base class for a vertex in the PlannerData structure. All derived classes must implement the clone an...
Definition: PlannerData.h:59
Invalid start state or no start state specified.
Definition: PlannerStatus.h:56
PlannerTerminationCondition timedPlannerTerminationCondition(double duration)
Return a termination condition that will become true duration seconds in the future (wall-time) ...
boost::graph_traits< Graph >::edge_descriptor Edge
The type for an edge in the roadmap.
Definition: PRM.h:127
Abstract definition of a goal region that can be sampled.
static const unsigned int DEFAULT_NEAREST_NEIGHBORS
The number of nearest neighbors to consider by default in the construction of the PRM roadmap...
Definition: PRM.cpp:68
virtual unsigned int maxSampleCount() const =0
Return the maximum number of samples that can be asked for before repeating.
The goal is of a type that a planner does not recognize.
Definition: PlannerStatus.h:60
void freeMemory()
Free all the memory allocated by the planner.
Definition: PRM.cpp:196
bool starStrategy_
Flag indicating whether the default connection strategy is the Star strategy.
Definition: PRM.h:342
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
Definition: Console.h:64
bool tagState(const State *st, int tag)
Set the integer tag associated with the given state. If the given state does not exist in a vertex...
Vertex addMilestone(base::State *state)
Construct a milestone for a given state (state), store it in the nearest neighbors data structure and...
Definition: PRM.cpp:491
base::PathPtr constructSolution(const Vertex &start, const Vertex &goal)
Given two milestones from the same connected component, construct a path connecting them and set it a...
Definition: PRM.cpp:537
The planner found an exact solution.
Definition: PlannerStatus.h:66
void reverse()
Reverse the path.
A class to store the exit status of Planner::solve()
Definition: PlannerStatus.h:48
virtual bool addEdge(unsigned int v1, unsigned int v2, const PlannerDataEdge &edge=PlannerDataEdge(), Cost weight=Cost(1.0))
Adds a directed edge between the given vertex indexes. An optional edge structure and weight can be s...
virtual bool isStartGoalPairValid(const State *, const State *) const
Since there can be multiple starting states (and multiple goal states) it is possible certain pairs a...
Definition: Goal.h:138
A shared pointer wrapper for ompl::base::SpaceInformation.
An optimization objective which corresponds to optimizing path length.
unsigned int addStartVertex(const PlannerDataVertex &v)
Adds the given vertex to the graph data, and marks it as a start vertex. The vertex index is returned...
Definition of an abstract state.
Definition: State.h:50
static const unsigned int FIND_VALID_STATE_ATTEMPTS_WITHOUT_TERMINATION_CHECK
Maximum number of sampling attempts to find a valid state, without checking whether the allowed time ...
Abstract definition of optimization objectives.
PlannerSpecs specs_
The specifications of the planner (its capabilities)
Definition: Planner.h:410
void setOptimized(const OptimizationObjectivePtr &opt, Cost cost, bool meetsObjective)
Set the optimization objective used to optimize this solution, the cost of the solution and whether i...
The exception type for ompl.
Definition: Exception.h:47
Element * add(const _T &d, const double w)
Adds a piece of data with a given weight to the PDF. Returns a corresponding Element, which can be used to subsequently update or remove the data from the PDF.
Definition: PDF.h:97
virtual bool couldSample() const
Return true if samples could be generated by this sampler at some point in the future. By default this is equivalent to canSample(), but for GoalLazySamples, this call also reflects the fact that a sampling thread is active and although no samples are produced yet, some may become available at some point in the future.
Make the minimal number of connections required to ensure asymptotic optimality.
void uniteComponents(Vertex m1, Vertex m2)
Make two milestones (m1 and m2) be part of the same connected component. The component with fewer ele...
Definition: PRM.cpp:527
void setMaxNearestNeighbors(unsigned int k)
Convenience function that sets the connection strategy to the default one with k nearest neighbors...
Definition: PRM.cpp:152
virtual void setup()
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition: PRM.cpp:109
virtual void setProblemDefinition(const base::ProblemDefinitionPtr &pdef)
Set the problem definition for the planner. The problem needs to be set before calling solve()...
Definition: PRM.cpp:169
bool optimizingPaths
Flag indicating whether the planner attempts to optimize the path and reduce its length until the max...
Definition: Planner.h:216
static const unsigned int MAX_RANDOM_BOUNCE_STEPS
The number of steps to take for a random bounce motion generated as part of the expansion step of PRM...
Definition: PRM.cpp:61
bool maybeConstructSolution(const std::vector< Vertex > &starts, const std::vector< Vertex > &goals, base::PathPtr &solution)
Check if there exists a solution, i.e., there exists a pair of milestones such that the first is in s...
Definition: PRM.cpp:346
unsigned long int milestoneCount() const
Return the number of milestones currently in the graph.
Definition: PRM.h:259
Definition of a geometric path.
Definition: PathGeometric.h:60
bool empty() const
Returns whether the PDF contains no data.
Definition: PDF.h:262
boost::graph_traits< Graph >::vertex_descriptor Vertex
The type for a vertex in the roadmap.
Definition: PRM.h:125
_T & sample(double r) const
Returns a piece of data from the PDF according to the input sampling value, which must be between 0 a...
Definition: PDF.h:132
void constructRoadmap(const base::PlannerTerminationCondition &ptc)
While the termination condition allows, this function will construct the roadmap (using growRoadmap()...
Definition: PRM.cpp:463
void setPlannerName(const std::string &name)
Set the name of the planner used to compute this solution.
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
Definition: Cost.h:47
A shared pointer wrapper for ompl::base::Path.
virtual void getPlannerData(base::PlannerData &data) const
Get information about the current run of the motion planner. Repeated calls to this function will upd...
Definition: PRM.cpp:572
bool addedNewSolution() const
Returns the value of the addedNewSolution_ member.
Definition: PRM.cpp:386
std::function< const std::vector< Vertex > &(const Vertex)> ConnectionStrategy
A function returning the milestones that should be attempted to connect to.
Definition: PRM.h:134
base::Cost costHeuristic(Vertex u, Vertex v) const
Given two vertices, returns a heuristic on the cost of the path connecting them. This method wraps Op...
Definition: PRM.cpp:601
This bit is set if casting to sampleable goal regions (ompl::base::GoalSampleableRegion) is possible...
Definition: GoalTypes.h:55
#define OMPL_INFORM(fmt,...)
Log a formatted information string.
Definition: Console.h:68