LazyPRM.cpp
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2013, Willow Garage
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, Ryan Luna */
36 
37 #include "ompl/geometric/planners/prm/LazyPRM.h"
38 #include "ompl/base/objectives/PathLengthOptimizationObjective.h"
39 #include "ompl/base/goals/GoalSampleableRegion.h"
40 #include "ompl/geometric/planners/prm/ConnectionStrategy.h"
41 #include "ompl/tools/config/SelfConfig.h"
42 #include <boost/graph/astar_search.hpp>
43 #include <boost/graph/incremental_components.hpp>
44 #include <boost/graph/lookup_edge.hpp>
45 #include <boost/foreach.hpp>
46 #include <queue>
47 
48 #include "GoalVisitor.hpp"
49 
50 #define foreach BOOST_FOREACH
51 
52 namespace ompl
53 {
54  namespace magic
55  {
58  static const unsigned int DEFAULT_NEAREST_NEIGHBORS_LAZY = 5;
59 
63  static const unsigned int MIN_ADDED_SEGMENTS_FOR_LAZY_OPTIMIZATION = 5;
64  }
65 }
66 
68  base::Planner(si, "LazyPRM"),
69  starStrategy_(starStrategy),
70  userSetConnectionStrategy_(false),
71  maxDistance_(0.0),
72  indexProperty_(boost::get(boost::vertex_index_t(), g_)),
73  stateProperty_(boost::get(vertex_state_t(), g_)),
74  weightProperty_(boost::get(boost::edge_weight, g_)),
75  vertexComponentProperty_(boost::get(vertex_component_t(), g_)),
76  vertexValidityProperty_(boost::get(vertex_flags_t(), g_)),
77  edgeValidityProperty_(boost::get(edge_flags_t(), g_)),
78  componentCount_(0),
79  bestCost_(std::numeric_limits<double>::quiet_NaN()),
80  iterations_(0)
81 {
84  specs_.optimizingPaths = true;
85 
86  Planner::declareParam<double>("range", this, &LazyPRM::setRange, &LazyPRM::getRange, "0.:1.:10000.");
87  if (!starStrategy_)
88  Planner::declareParam<unsigned int>("max_nearest_neighbors", this, &LazyPRM::setMaxNearestNeighbors, std::string("8:1000"));
89 
90  addPlannerProgressProperty("iterations INTEGER",
91  std::bind(&LazyPRM::getIterationCount, this));
92  addPlannerProgressProperty("best cost REAL",
93  std::bind(&LazyPRM::getBestCost, this));
94  addPlannerProgressProperty("milestone count INTEGER",
95  std::bind(&LazyPRM::getMilestoneCountString, this));
96  addPlannerProgressProperty("edge count INTEGER",
97  std::bind(&LazyPRM::getEdgeCountString, this));
98 }
99 
100 ompl::geometric::LazyPRM::~LazyPRM()
101 {
102 }
103 
105 {
106  Planner::setup();
109 
110  if (!nn_)
111  {
112  nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Vertex>(this));
113  nn_->setDistanceFunction(std::bind(&LazyPRM::distanceFunction, this,
114  std::placeholders::_1, std::placeholders::_2));
115  }
116  if (!connectionStrategy_)
117  {
118  if (starStrategy_)
119  connectionStrategy_ = KStarStrategy<Vertex>(std::bind(&LazyPRM::milestoneCount, this), nn_, si_->getStateDimension());
120  else
122  }
123  if (!connectionFilter_)
124  connectionFilter_ = [] (const Vertex&, const Vertex&) { return true; };
125 
126  // Setup optimization objective
127  //
128  // If no optimization objective was specified, then default to
129  // optimizing path length as computed by the distance() function
130  // in the state space.
131  if (pdef_)
132  {
133  if (pdef_->hasOptimizationObjective())
134  opt_ = pdef_->getOptimizationObjective();
135  else
136  {
138  if (!starStrategy_)
139  opt_->setCostThreshold(opt_->infiniteCost());
140  }
141  }
142  else
143  {
144  OMPL_INFORM("%s: problem definition is not set, deferring setup completion...", getName().c_str());
145  setup_ = false;
146  }
147 
148  sampler_ = si_->allocStateSampler();
149 }
150 
152 {
153  maxDistance_ = distance;
156  if (isSetup())
157  setup();
158 }
159 
161 {
162  if (starStrategy_)
163  throw Exception("Cannot set the maximum nearest neighbors for " + getName());
164  if (!nn_)
165  {
166  nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Vertex>(this));
167  nn_->setDistanceFunction(std::bind(&LazyPRM::distanceFunction, this,
168  std::placeholders::_1, std::placeholders::_2));
169  }
172  if (isSetup())
173  setup();
174 }
175 
177 {
178  Planner::setProblemDefinition(pdef);
179  clearQuery();
180 }
181 
183 {
184  startM_.clear();
185  goalM_.clear();
186  pis_.restart();
187 }
188 
190 {
191  Planner::clear();
192  freeMemory();
193  if (nn_)
194  nn_->clear();
195  clearQuery();
196 
197  componentCount_ = 0;
198  iterations_ = 0;
199  bestCost_ = base::Cost(std::numeric_limits<double>::quiet_NaN());
200 }
201 
203 {
204  foreach (Vertex v, boost::vertices(g_))
205  si_->freeState(stateProperty_[v]);
206  g_.clear();
207 }
208 
210 {
211  Vertex m = boost::add_vertex(g_);
212  stateProperty_[m] = state;
214  unsigned long int newComponent = componentCount_++;
215  vertexComponentProperty_[m] = newComponent;
216  componentSize_[newComponent] = 1;
217 
218  // Which milestones will we attempt to connect to?
219  const std::vector<Vertex> &neighbors = connectionStrategy_(m);
220  foreach (Vertex n, neighbors)
221  if (connectionFilter_(m, n))
222  {
223  const base::Cost weight = opt_->motionCost(stateProperty_[m], stateProperty_[n]);
224  const Graph::edge_property_type properties(weight);
225  const Edge &e = boost::add_edge(m, n, properties, g_).first;
227  uniteComponents(m, n);
228  }
229 
230  nn_->add(m);
231 
232  return m;
233 }
234 
236 {
237  checkValidity();
238  base::GoalSampleableRegion *goal = dynamic_cast<base::GoalSampleableRegion*>(pdef_->getGoal().get());
239 
240  if (!goal)
241  {
242  OMPL_ERROR("%s: Unknown type of goal", getName().c_str());
244  }
245 
246  // Add the valid start states as milestones
247  while (const base::State *st = pis_.nextStart())
248  startM_.push_back(addMilestone(si_->cloneState(st)));
249 
250  if (startM_.size() == 0)
251  {
252  OMPL_ERROR("%s: There are no valid initial states!", getName().c_str());
254  }
255 
256  if (!goal->couldSample())
257  {
258  OMPL_ERROR("%s: Insufficient states in sampleable goal region", getName().c_str());
260  }
261 
262  // Ensure there is at least one valid goal state
263  if (goal->maxSampleCount() > goalM_.size() || goalM_.empty())
264  {
265  const base::State *st = goalM_.empty() ? pis_.nextGoal(ptc) : pis_.nextGoal();
266  if (st)
267  goalM_.push_back(addMilestone(si_->cloneState(st)));
268 
269  if (goalM_.empty())
270  {
271  OMPL_ERROR("%s: Unable to find any valid goal states", getName().c_str());
273  }
274  }
275 
276  unsigned long int nrStartStates = boost::num_vertices(g_);
277  OMPL_INFORM("%s: Starting planning with %lu states already in datastructure", getName().c_str(), nrStartStates);
278 
279  bestCost_ = opt_->infiniteCost();
280  base::State *workState = si_->allocState();
281  std::pair<std::size_t, std::size_t> startGoalPair;
282  base::PathPtr bestSolution;
283  bool fullyOptimized = false;
284  bool someSolutionFound = false;
285  unsigned int optimizingComponentSegments = 0;
286 
287  // Grow roadmap in lazy fashion -- add vertices and edges without checking validity
288  while (ptc == false)
289  {
290  ++iterations_;
291  sampler_->sampleUniform(workState);
292  Vertex addedVertex = addMilestone(si_->cloneState(workState));
293 
294  const long int solComponent = solutionComponent(&startGoalPair);
295  // If the start & goal are connected and we either did not find any solution
296  // so far or the one we found still needs optimizing and we just added an edge
297  // to the connected component that is used for the solution, we attempt to
298  // construct a new solution.
299  if (solComponent != -1 && (!someSolutionFound || (long int)vertexComponentProperty_[addedVertex] == solComponent))
300  {
301  // If we already have a solution, we are optimizing. We check that we added at least
302  // a few segments to the connected component that includes the previously found
303  // solution before attempting to construct a new solution.
304  if (someSolutionFound)
305  {
306  if (++optimizingComponentSegments < magic::MIN_ADDED_SEGMENTS_FOR_LAZY_OPTIMIZATION)
307  continue;
308  optimizingComponentSegments = 0;
309  }
310  Vertex startV = startM_[startGoalPair.first];
311  Vertex goalV = goalM_[startGoalPair.second];
312  base::PathPtr solution;
313  do
314  {
315  solution = constructSolution(startV, goalV);
316  } while (!solution && vertexComponentProperty_[startV] == vertexComponentProperty_[goalV]);
317  if (solution)
318  {
319  someSolutionFound = true;
320  base::Cost c = solution->cost(opt_);
321  if (opt_->isSatisfied(c))
322  {
323  fullyOptimized = true;
324  bestSolution = solution;
325  bestCost_ = c;
326  break;
327  }
328  else
329  {
330  if (opt_->isCostBetterThan(c, bestCost_))
331  {
332  bestSolution = solution;
333  bestCost_ = c;
334  }
335  }
336  }
337  }
338  }
339 
340  si_->freeState(workState);
341 
342  if (bestSolution)
343  {
344  base::PlannerSolution psol(bestSolution);
345  psol.setPlannerName(getName());
346  // if the solution was optimized, we mark it as such
347  psol.setOptimized(opt_, bestCost_, fullyOptimized);
348  pdef_->addSolutionPath(psol);
349  }
350 
351  OMPL_INFORM("%s: Created %u states", getName().c_str(), boost::num_vertices(g_) - nrStartStates);
352 
354 }
355 
356 void ompl::geometric::LazyPRM::uniteComponents(Vertex a, Vertex b)
357 {
358  unsigned long int componentA = vertexComponentProperty_[a];
359  unsigned long int componentB = vertexComponentProperty_[b];
360  if (componentA == componentB) return;
361  if (componentSize_[componentA] > componentSize_[componentB])
362  {
363  std::swap(componentA, componentB);
364  std::swap(a, b);
365  }
366  markComponent(a, componentB);
367 }
368 
369 void ompl::geometric::LazyPRM::markComponent(Vertex v, unsigned long int newComponent)
370 {
371  std::queue<Vertex> q;
372  q.push(v);
373  while (!q.empty())
374  {
375  Vertex n = q.front();
376  q.pop();
377  unsigned long int &component = vertexComponentProperty_[n];
378  if (component == newComponent) continue;
379  if (componentSize_[component] == 1)
380  componentSize_.erase(component);
381  else
382  componentSize_[component]--;
383  component = newComponent;
384  componentSize_[newComponent]++;
385  boost::graph_traits<Graph>::adjacency_iterator nbh, last;
386  for (boost::tie(nbh, last) = boost::adjacent_vertices(n, g_) ; nbh != last ; ++nbh)
387  q.push(*nbh);
388  }
389 }
390 
391 long int ompl::geometric::LazyPRM::solutionComponent(std::pair<std::size_t, std::size_t> *startGoalPair) const
392 {
393  for (std::size_t startIndex = 0; startIndex < startM_.size(); ++startIndex)
394  {
395  long int startComponent = vertexComponentProperty_[startM_[startIndex]];
396  for (std::size_t goalIndex = 0; goalIndex < goalM_.size(); ++goalIndex)
397  {
398  if (startComponent == (long int)vertexComponentProperty_[goalM_[goalIndex]])
399  {
400  startGoalPair->first = startIndex;
401  startGoalPair->second = goalIndex;
402  return startComponent;
403  }
404  }
405  }
406  return -1;
407 }
408 
410 {
411  // Need to update the index map here, becuse nodes may have been removed and
412  // the numbering will not be 0 .. N-1 otherwise.
413  unsigned long int index = 0;
414  boost::graph_traits<Graph>::vertex_iterator vi, vend;
415  for(boost::tie(vi, vend) = boost::vertices(g_); vi != vend; ++vi, ++index)
416  indexProperty_[*vi] = index;
417 
418  boost::property_map<Graph, boost::vertex_predecessor_t>::type prev;
419  try
420  {
421  // Consider using a persistent distance_map if it's slow
422  boost::astar_search(g_, start,
423  std::bind(&LazyPRM::costHeuristic, this, std::placeholders::_1, goal),
424  boost::predecessor_map(prev).
425  distance_compare(std::bind(&base::OptimizationObjective::
426  isCostBetterThan, opt_.get(), std::placeholders::_1, std::placeholders::_2)).
427  distance_combine(std::bind(&base::OptimizationObjective::
428  combineCosts, opt_.get(), std::placeholders::_1, std::placeholders::_2)).
429  distance_inf(opt_->infiniteCost()).
430  distance_zero(opt_->identityCost()).
431  visitor(AStarGoalVisitor<Vertex>(goal)));
432  }
433  catch (AStarFoundGoal&)
434  {
435  }
436  if (prev[goal] == goal)
437  throw Exception(name_, "Could not find solution path");
438 
439  // First, get the solution states without copying them, and check them for validity.
440  // We do all the node validity checks for the vertices, as this may remove a larger
441  // part of the graph (compared to removing an edge).
442  std::vector<const base::State*> states(1, stateProperty_[goal]);
443  std::set<Vertex> milestonesToRemove;
444  for (Vertex pos = prev[goal]; prev[pos] != pos; pos = prev[pos])
445  {
446  const base::State *st = stateProperty_[pos];
447  unsigned int &vd = vertexValidityProperty_[pos];
448  if ((vd & VALIDITY_TRUE) == 0)
449  if (si_->isValid(st))
450  vd |= VALIDITY_TRUE;
451  if ((vd & VALIDITY_TRUE) == 0)
452  milestonesToRemove.insert(pos);
453  if (milestonesToRemove.empty())
454  states.push_back(st);
455  }
456 
457  // We remove *all* invalid vertices. This is not entirely as described in the original LazyPRM
458  // paper, as the paper suggest removing the first vertex only, and then recomputing the
459  // shortest path. Howeve, the paper says the focus is on efficient vertex & edge removal,
460  // rather than collision checking, so this modification is in the spirit of the paper.
461  if (!milestonesToRemove.empty())
462  {
463  unsigned long int comp = vertexComponentProperty_[start];
464  // Remember the current neighbors.
465  std::set<Vertex> neighbors;
466  for (std::set<Vertex>::iterator it = milestonesToRemove.begin() ; it != milestonesToRemove.end() ; ++it)
467  {
468  boost::graph_traits<Graph>::adjacency_iterator nbh, last;
469  for (boost::tie(nbh, last) = boost::adjacent_vertices(*it, g_) ; nbh != last ; ++nbh)
470  if (milestonesToRemove.find(*nbh) == milestonesToRemove.end())
471  neighbors.insert(*nbh);
472  // Remove vertex from nearest neighbors data structure.
473  nn_->remove(*it);
474  // Free vertex state.
475  si_->freeState(stateProperty_[*it]);
476  // Remove all edges.
477  boost::clear_vertex(*it, g_);
478  // Remove the vertex.
479  boost::remove_vertex(*it, g_);
480  }
481  // Update the connected component ID for neighbors.
482  for (std::set<Vertex>::iterator it = neighbors.begin() ; it != neighbors.end() ; ++it)
483  {
484  if (comp == vertexComponentProperty_[*it])
485  {
486  unsigned long int newComponent = componentCount_++;
487  componentSize_[newComponent] = 0;
488  markComponent(*it, newComponent);
489  }
490  }
491  return base::PathPtr();
492  }
493 
494  // start is checked for validity already
495  states.push_back(stateProperty_[start]);
496 
497  // Check the edges too, if the vertices were valid. Remove the first invalid edge only.
498  std::vector<const base::State*>::const_iterator prevState = states.begin(), state = prevState + 1;
499  Vertex prevVertex = goal, pos = prev[goal];
500  do
501  {
502  Edge e = boost::lookup_edge(pos, prevVertex, g_).first;
503  unsigned int &evd = edgeValidityProperty_[e];
504  if ((evd & VALIDITY_TRUE) == 0)
505  {
506  if (si_->checkMotion(*state, *prevState))
507  evd |= VALIDITY_TRUE;
508  }
509  if ((evd & VALIDITY_TRUE) == 0)
510  {
511  boost::remove_edge(e, g_);
512  unsigned long int newComponent = componentCount_++;
513  componentSize_[newComponent] = 0;
514  markComponent(pos, newComponent);
515  return base::PathPtr();
516  }
517  prevState = state;
518  ++state;
519  prevVertex = pos;
520  pos = prev[pos];
521  }
522  while (prevVertex != pos);
523 
524  PathGeometric *p = new PathGeometric(si_);
525  for (std::vector<const base::State*>::const_reverse_iterator st = states.rbegin(); st != states.rend(); ++st)
526  p->append(*st);
527  return base::PathPtr(p);
528 }
529 
531 {
532  return opt_->motionCostHeuristic(stateProperty_[u], stateProperty_[v]);
533 }
534 
536 {
537  Planner::getPlannerData(data);
538 
539  // Explicitly add start and goal states. Tag all states known to be valid as 1.
540  // Unchecked states are tagged as 0.
541  for (size_t i = 0; i < startM_.size(); ++i)
543 
544  for (size_t i = 0; i < goalM_.size(); ++i)
546 
547  // Adding edges and all other vertices simultaneously
548  foreach(const Edge e, boost::edges(g_))
549  {
550  const Vertex v1 = boost::source(e, g_);
551  const Vertex v2 = boost::target(e, g_);
554 
555  // Add the reverse edge, since we're constructing an undirected roadmap
558 
559  // Add tags for the newly added vertices
560  data.tagState(stateProperty_[v1], (vertexValidityProperty_[v1] & VALIDITY_TRUE) == 0 ? 0 : 1);
561  data.tagState(stateProperty_[v2], (vertexValidityProperty_[v2] & VALIDITY_TRUE) == 0 ? 0 : 1);
562  }
563 }
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
void freeMemory()
Free all the memory allocated by the planner.
Definition: LazyPRM.cpp:202
static const unsigned int MIN_ADDED_SEGMENTS_FOR_LAZY_OPTIMIZATION
When optimizing solutions with lazy planners, this is the minimum number of path segments to add befo...
Definition: LazyPRM.cpp:63
bool starStrategy_
Flag indicating whether the default connection strategy is the Star strategy.
Definition: LazyPRM.h:294
Object containing planner generated vertex and edge data. It is assumed that all vertices are unique...
Definition: PlannerData.h:163
boost::property_map< Graph, vertex_state_t >::type stateProperty_
Access to the internal base::state at each Vertex.
Definition: LazyPRM.h:327
LazyPRM(const base::SpaceInformationPtr &si, bool starStrategy=false)
Constructor.
Definition: LazyPRM.cpp:67
A shared pointer wrapper for ompl::base::ProblemDefinition.
base::OptimizationObjectivePtr opt_
Objective cost function for PRM graph edges.
Definition: LazyPRM.h:349
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
boost::property_map< Graph, boost::vertex_index_t >::type indexProperty_
Access to the internal base::state at each Vertex.
Definition: LazyPRM.h:324
const State * nextGoal(const PlannerTerminationCondition &ptc)
Return the next valid goal state or nullptr if no more valid goal states are available. Because sampling of goal states may also produce invalid goals, this function takes an argument that specifies whether a termination condition has been reached. If the termination condition evaluates to true the function terminates even if no valid goal has been found.
Definition: Planner.cpp:271
double maxDistance_
The maximum length of a motion to be added to a tree.
Definition: LazyPRM.h:306
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...
Graph g_
Connectivity graph.
Definition: LazyPRM.h:315
boost::property_map< Graph, vertex_component_t >::type vertexComponentProperty_
Access the connected component of a vertex.
Definition: LazyPRM.h:333
ConnectionStrategy connectionStrategy_
Function that returns the milestones to attempt connections with.
Definition: LazyPRM.h:297
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
STL namespace.
void append(const base::State *state)
Append state to the end of this path. The memory for state is copied.
RoadmapNeighbors nn_
Nearest neighbors data structure.
Definition: LazyPRM.h:312
ProblemDefinitionPtr pdef_
The user set problem definition.
Definition: Planner.h:401
static const unsigned int VALIDITY_UNKNOWN
Flag indicating validity of an edge of a vertex.
Definition: LazyPRM.h:241
ConnectionFilter connectionFilter_
Function that can reject a milestone connection.
Definition: LazyPRM.h:300
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
bool setup_
Flag indicating whether setup() has been called.
Definition: Planner.h:419
Abstract definition of a goal region that can be sampled.
Main namespace. Contains everything in this library.
Definition: Cost.h:42
virtual base::PlannerStatus solve(const base::PlannerTerminationCondition &ptc)
Function that can solve the motion planning problem. This function can be called multiple times on th...
Definition: LazyPRM.cpp:235
virtual unsigned int maxSampleCount() const =0
Return the maximum number of samples that can be asked for before repeating.
Return at most k neighbors, as long as they are also within a specified bound.
boost::property_map< Graph, vertex_flags_t >::type vertexValidityProperty_
Access the validity state of a vertex.
Definition: LazyPRM.h:336
The goal is of a type that a planner does not recognize.
Definition: PlannerStatus.h:60
Vertex addMilestone(base::State *state)
Construct a milestone for a given state (state), store it in the nearest neighbors data structure and...
Definition: LazyPRM.cpp:209
void setMaxNearestNeighbors(unsigned int k)
Convenience function that sets the connection strategy to the default one with k nearest neighbors...
Definition: LazyPRM.cpp:160
#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...
std::vector< Vertex > startM_
Array of start milestones.
Definition: LazyPRM.h:318
virtual void clear()
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
Definition: LazyPRM.cpp:189
double getRange() const
Get the range the planner is using.
Definition: LazyPRM.h:152
The planner found an exact solution.
Definition: PlannerStatus.h:66
boost::adjacency_list_traits< boost::vecS, boost::listS, boost::undirectedS >::vertex_descriptor Vertex
The type for a vertex in the roadmap.
Definition: LazyPRM.h:96
ompl::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: LazyPRM.cpp:409
unsigned long int componentCount_
Number of connected components created so far. This is used as an ID only, does not represent the act...
Definition: LazyPRM.h:343
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...
A shared pointer wrapper for ompl::base::SpaceInformation.
void clearQuery()
Clear the query previously loaded from the ProblemDefinition. Subsequent calls to solve() will reuse ...
Definition: LazyPRM.cpp:182
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
virtual void checkValidity()
Check to see if the planner is in a working state (setup has been called, a goal was set...
Definition: Planner.cpp:100
unsigned long int milestoneCount() const
Return the number of milestones currently in the graph.
Definition: LazyPRM.h:213
PlannerInputStates pis_
Utility class to extract valid input states.
Definition: Planner.h:404
Abstract definition of optimization objectives.
PlannerSpecs specs_
The specifications of the planner (its capabilities)
Definition: Planner.h:410
const State * nextStart()
Return the next valid start state or nullptr if no more valid start states are available.
Definition: Planner.cpp:230
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: LazyPRM.h:284
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
long int solutionComponent(std::pair< std::size_t, std::size_t > *startGoalPair) const
Check if any pair of a start state and goal state are part of the same connected component. If so, return the id of that component. Otherwise, return -1.
Definition: LazyPRM.cpp:391
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: LazyPRM.cpp:530
void setRange(double distance)
Set the maximum length of a motion to be added to the roadmap.
Definition: LazyPRM.cpp:151
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: LazyPRM.cpp:535
std::function< const std::vector< Vertex > &(const Vertex)> ConnectionStrategy
A function returning the milestones that should be attempted to connect to.
Definition: LazyPRM.h:134
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.
std::string name_
The name of this planner.
Definition: Planner.h:407
static const unsigned int VALIDITY_TRUE
Flag indicating validity of an edge of a vertex.
Definition: LazyPRM.h:244
void configurePlannerRange(double &range)
Compute what a good length for motion segments is.
Definition: SelfConfig.cpp:230
This class contains methods that automatically configure various parameters for motion planning...
Definition: SelfConfig.h:60
boost::graph_traits< Graph >::edge_descriptor Edge
The type for an edge in the roadmap.
Definition: LazyPRM.h:127
bool optimizingPaths
Flag indicating whether the planner attempts to optimize the path and reduce its length until the max...
Definition: Planner.h:216
std::vector< Vertex > goalM_
Array of goal milestones.
Definition: LazyPRM.h:321
void restart()
Forget how many states were returned by nextStart() and nextGoal() and return all states again...
Definition: Planner.cpp:170
bool userSetConnectionStrategy_
Flag indicating whether the employed connection strategy was set by the user (or defaults are assumed...
Definition: LazyPRM.h:303
Definition of a geometric path.
Definition: PathGeometric.h:60
boost::property_map< Graph, edge_flags_t >::type edgeValidityProperty_
Access the validity state of an edge.
Definition: LazyPRM.h:339
SpaceInformationPtr si_
The space information for which planning is done.
Definition: Planner.h:398
static const unsigned int DEFAULT_NEAREST_NEIGHBORS_LAZY
The number of nearest neighbors to consider by default in the construction of the PRM roadmap...
Definition: LazyPRM.cpp:58
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
const std::string & getName() const
Get the name of the planner.
Definition: Planner.cpp:55
std::map< unsigned long int, unsigned long int > componentSize_
The number of elements in each component in the LazyPRM roadmap.
Definition: LazyPRM.h:346
virtual void setup()
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition: LazyPRM.cpp:104
bool isSetup() const
Check if setup() was called for this planner.
Definition: Planner.cpp:107
A shared pointer wrapper for ompl::base::Path.
virtual void setProblemDefinition(const base::ProblemDefinitionPtr &pdef)
Set the problem definition for the planner. The problem needs to be set before calling solve()...
Definition: LazyPRM.cpp:176
base::StateSamplerPtr sampler_
Sampler user for generating random in the state space.
Definition: LazyPRM.h:309
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