Loading...
Searching...
No Matches
SPARS.cpp
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2013, Rutgers the State University of New Jersey, New Brunswick
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 Rutgers 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: Andrew Dobson */
36
37#include "ompl/geometric/planners/prm/SPARS.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/tools/config/SelfConfig.h"
42#include "ompl/tools/config/MagicConstants.h"
43#include <thread>
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
49#include "GoalVisitor.hpp"
50
51#define foreach BOOST_FOREACH
52#define foreach_reverse BOOST_REVERSE_FOREACH
53
54ompl::geometric::SPARS::SPARS(const base::SpaceInformationPtr &si)
55 : base::Planner(si, "SPARS")
56 , geomPath_(si)
57 , stateProperty_(boost::get(vertex_state_t(), g_))
58 , sparseStateProperty_(boost::get(vertex_state_t(), s_))
59 , sparseColorProperty_(boost::get(vertex_color_t(), s_))
63 , weightProperty_(boost::get(boost::edge_weight, g_))
64 , sparseDJSets_(boost::get(boost::vertex_rank, s_), boost::get(boost::vertex_predecessor, s_))
65{
66 specs_.recognizedGoal = base::GOAL_SAMPLEABLE_REGION;
67 specs_.approximateSolutions = false;
68 specs_.optimizingPaths = true;
69 specs_.multithreaded = true;
70
71 psimp_ = std::make_shared<PathSimplifier>(si_);
72 psimp_->freeStates(false);
73
74 Planner::declareParam<double>("stretch_factor", this, &SPARS::setStretchFactor, &SPARS::getStretchFactor,
75 "1.1:0.1:"
76 "3.0");
77 Planner::declareParam<double>("sparse_delta_fraction", this, &SPARS::setSparseDeltaFraction,
78 &SPARS::getSparseDeltaFraction, "0.0:0.01:1.0");
79 Planner::declareParam<double>("dense_delta_fraction", this, &SPARS::setDenseDeltaFraction,
80 &SPARS::getDenseDeltaFraction, "0.0:0.0001:0.1");
81 Planner::declareParam<unsigned int>("max_failures", this, &SPARS::setMaxFailures, &SPARS::getMaxFailures,
82 "100:10:"
83 "3000");
84
85 addPlannerProgressProperty("iterations INTEGER", [this] { return getIterationCount(); });
86 addPlannerProgressProperty("best cost REAL", [this] { return getBestCost(); });
87}
88
93
95{
96 Planner::setup();
97 if (!nn_)
99 nn_->setDistanceFunction([this](const DenseVertex a, const DenseVertex b) { return distanceFunction(a, b); });
100 if (!snn_)
102 snn_->setDistanceFunction([this](const SparseVertex a, const SparseVertex b)
103 { return sparseDistanceFunction(a, b); });
106 KStarStrategy<DenseVertex>([this] { return milestoneCount(); }, nn_, si_->getStateDimension());
107 double maxExt = si_->getMaximumExtent();
110
111 // Setup optimization objective
112 //
113 // If no optimization objective was specified, then default to
114 // optimizing path length as computed by the distance() function
115 // in the state space.
116 if (pdef_)
117 {
118 if (pdef_->hasOptimizationObjective())
119 {
120 opt_ = pdef_->getOptimizationObjective();
121 if (dynamic_cast<base::PathLengthOptimizationObjective *>(opt_.get()) == nullptr)
122 OMPL_WARN("%s: Asymptotic optimality has only been proven with path length optimizaton; convergence "
123 "for other optimizaton objectives is not guaranteed.",
124 getName().c_str());
125 }
126 else
127 opt_ = std::make_shared<base::PathLengthOptimizationObjective>(si_);
128 }
129 else
130 {
131 OMPL_INFORM("%s: problem definition is not set, deferring setup completion...", getName().c_str());
132 setup_ = false;
133 }
134}
135
136void ompl::geometric::SPARS::setProblemDefinition(const base::ProblemDefinitionPtr &pdef)
137{
138 Planner::setProblemDefinition(pdef);
139 clearQuery();
140}
141
146
148{
149 startM_.clear();
150 goalM_.clear();
151 pis_.restart();
152
153 // Clear past solutions if there are any
154 if (pdef_)
155 pdef_->clearSolutionPaths();
156}
157
159{
160 Planner::clear();
161 sampler_.reset();
162 freeMemory();
163 if (nn_)
164 nn_->clear();
165 if (snn_)
166 snn_->clear();
167 clearQuery();
169 iterations_ = 0;
170 bestCost_ = base::Cost(std::numeric_limits<double>::quiet_NaN());
171}
172
174{
175 foreach (DenseVertex v, boost::vertices(g_))
176 if (stateProperty_[v] != nullptr)
177 {
178 si_->freeState(stateProperty_[v]);
179 stateProperty_[v] = nullptr;
180 }
181 foreach (SparseVertex n, boost::vertices(s_))
182 if (sparseStateProperty_[n] != nullptr)
183 {
184 si_->freeState(sparseStateProperty_[n]);
185 sparseStateProperty_[n] = nullptr;
186 }
187 s_.clear();
188 g_.clear();
189}
190
193{
194 DenseVertex result = boost::graph_traits<DenseGraph>::null_vertex();
195
196 // search for a valid state
197 bool found = false;
198 while (!found && !ptc)
199 {
200 unsigned int attempts = 0;
201 do
202 {
203 found = sampler_->sample(workState);
204 attempts++;
206 }
207
208 if (found)
209 result = addMilestone(si_->cloneState(workState));
210 return result;
211}
212
214{
215 auto *goal = static_cast<base::GoalSampleableRegion *>(pdef_->getGoal().get());
216 while (!ptc && !addedSolution_)
217 {
218 // Check for any new goal states
219 if (goal->maxSampleCount() > goalM_.size())
220 {
221 const base::State *st = pis_.nextGoal();
222 if (st != nullptr)
223 {
224 addMilestone(si_->cloneState(st));
225 goalM_.push_back(addGuard(si_->cloneState(st), GOAL));
226 }
227 }
228
229 // Check for a solution
231 // Sleep for 1ms
232 if (!addedSolution_)
233 std::this_thread::sleep_for(std::chrono::milliseconds(1));
234 }
235}
236
237bool ompl::geometric::SPARS::haveSolution(const std::vector<DenseVertex> &starts, const std::vector<DenseVertex> &goals,
238 base::PathPtr &solution)
239{
240 base::Goal *g = pdef_->getGoal().get();
241 base::Cost sol_cost(opt_->infiniteCost());
242 foreach (DenseVertex start, starts)
243 {
244 foreach (DenseVertex goal, goals)
245 {
246 // we lock because the connected components algorithm is incremental and may change disjointSets_
247 graphMutex_.lock();
248 bool same_component = sameComponent(start, goal);
249 graphMutex_.unlock();
250
251 if (same_component && g->isStartGoalPairValid(sparseStateProperty_[goal], sparseStateProperty_[start]))
252 {
253 base::PathPtr p = constructSolution(start, goal);
254 if (p)
255 {
256 base::Cost pathCost = p->cost(opt_);
257 if (opt_->isCostBetterThan(pathCost, bestCost_))
258 bestCost_ = pathCost;
259 // Check if optimization objective is satisfied
260 if (opt_->isSatisfied(pathCost))
261 {
262 solution = p;
263 return true;
264 }
265 if (opt_->isCostBetterThan(pathCost, sol_cost))
266 {
267 solution = p;
268 sol_cost = pathCost;
269 }
270 }
271 }
272 }
273 }
274
275 return false;
276}
277
282
287
289{
290 std::lock_guard<std::mutex> _(graphMutex_);
291 if (boost::num_vertices(g_) < 1)
292 {
293 sparseQueryVertex_ = boost::add_vertex(s_);
294 queryVertex_ = boost::add_vertex(g_);
296 stateProperty_[queryVertex_] = nullptr;
297 }
298}
299
301{
302 return boost::same_component(m1, m2, sparseDJSets_);
303}
304
306{
309
310 auto *goal = dynamic_cast<base::GoalSampleableRegion *>(pdef_->getGoal().get());
311
312 if (goal == nullptr)
313 {
314 OMPL_ERROR("%s: Unknown type of goal", getName().c_str());
316 }
317
318 // Add the valid start states as milestones
319 while (const base::State *st = pis_.nextStart())
320 {
321 addMilestone(si_->cloneState(st));
322 startM_.push_back(addGuard(si_->cloneState(st), START));
323 }
324 if (startM_.empty())
325 {
326 OMPL_ERROR("%s: There are no valid initial states!", getName().c_str());
328 }
329
330 if (goalM_.empty() && !goal->couldSample())
331 {
332 OMPL_ERROR("%s: Insufficient states in sampleable goal region", getName().c_str());
334 }
335
336 // Add the valid goal states as milestones
337 while (const base::State *st = (goalM_.empty() ? pis_.nextGoal(ptc) : pis_.nextGoal()))
338 {
339 addMilestone(si_->cloneState(st));
340 goalM_.push_back(addGuard(si_->cloneState(st), GOAL));
341 }
342 if (goalM_.empty())
343 {
344 OMPL_ERROR("%s: Unable to find any valid goal states", getName().c_str());
346 }
347
348 unsigned int nrStartStatesDense = boost::num_vertices(g_) - 1; // don't count query vertex
349 unsigned int nrStartStatesSparse = boost::num_vertices(s_) - 1; // don't count query vertex
350 OMPL_INFORM("%s: Starting planning with %u dense states, %u sparse states", getName().c_str(), nrStartStatesDense,
351 nrStartStatesSparse);
352
353 // Reset addedSolution_ member
354 addedSolution_ = false;
356 base::PathPtr sol;
357 base::PlannerTerminationCondition ptcOrFail([this, &ptc] { return ptc || reachedFailureLimit(); });
358 std::thread slnThread([this, &ptcOrFail, &sol] { checkForSolution(ptcOrFail, sol); });
359
360 // Construct planner termination condition which also takes maxFailures_ and addedSolution_ into account
361 base::PlannerTerminationCondition ptcOrStop([this, &ptc] { return ptc || reachedTerminationCriterion(); });
362 constructRoadmap(ptcOrStop);
363
364 // Ensure slnThread is ceased before exiting solve
365 slnThread.join();
366
367 if (sol)
368 pdef_->addSolutionPath(sol, false, -1.0, getName());
369
370 OMPL_INFORM("%s: Created %u dense states, %u sparse states", getName().c_str(),
371 (unsigned int)(boost::num_vertices(g_) - nrStartStatesDense),
372 (unsigned int)(boost::num_vertices(s_) - nrStartStatesSparse));
373
374 // Return true if any solution was found.
375 if (sol)
376 {
378 }
379 else
380 {
382 }
383}
384
386{
387 if (stopOnMaxFail)
388 {
390 base::PlannerTerminationCondition ptcOrFail([this, &ptc] { return ptc || reachedFailureLimit(); });
391 constructRoadmap(ptcOrFail);
392 }
393 else
394 constructRoadmap(ptc);
395}
396
398{
400
401 if (!isSetup())
402 setup();
403 if (!sampler_)
404 sampler_ = si_->allocValidStateSampler();
405
406 base::State *workState = si_->allocState();
407
408 /* The whole neighborhood set which has been most recently computed */
409 std::vector<SparseVertex> graphNeighborhood;
410
411 /* The visible neighborhood set which has been most recently computed */
412 std::vector<SparseVertex> visibleNeighborhood;
413
414 /* Storage for the interface neighborhood, populated by getInterfaceNeighborhood() */
415 std::vector<DenseVertex> interfaceNeighborhood;
416
417 bestCost_ = opt_->infiniteCost();
418 while (!ptc)
419 {
420 iterations_++;
421
422 // Generate a single sample, and attempt to connect it to nearest neighbors.
423 DenseVertex q = addSample(workState, ptc);
424 if (q == boost::graph_traits<DenseGraph>::null_vertex())
425 continue;
426
427 // Now that we've added to D, try adding to S
428 // Start by figuring out who our neighbors are
429 getSparseNeighbors(workState, graphNeighborhood);
430 filterVisibleNeighbors(workState, graphNeighborhood, visibleNeighborhood);
431 // Check for addition for Coverage
432 if (!checkAddCoverage(workState, graphNeighborhood))
433 // If not for Coverage, then Connectivity
434 if (!checkAddConnectivity(workState, graphNeighborhood))
435 // Check for the existence of an interface
436 if (!checkAddInterface(graphNeighborhood, visibleNeighborhood, q))
437 {
438 // Then check to see if it's on an interface
439 getInterfaceNeighborhood(q, interfaceNeighborhood);
440 if (!interfaceNeighborhood.empty())
441 {
442 // Check for addition for spanner prop
443 if (!checkAddPath(q, interfaceNeighborhood))
444 // All of the tests have failed. Report failure for the sample
446 }
447 else
448 // There's no interface here, so drop it
450 }
451 }
452
453 si_->freeState(workState);
454}
455
457{
458 std::lock_guard<std::mutex> _(graphMutex_);
459
460 DenseVertex m = boost::add_vertex(g_);
461 stateProperty_[m] = state;
462
463 // Which milestones will we attempt to connect to?
464 const std::vector<DenseVertex> &neighbors = connectionStrategy_(m);
465
466 foreach (DenseVertex n, neighbors)
467 if (si_->checkMotion(stateProperty_[m], stateProperty_[n]))
468 {
469 const double weight = distanceFunction(m, n);
470 const DenseGraph::edge_property_type properties(weight);
471
472 boost::add_edge(m, n, properties, g_);
473 }
474
475 nn_->add(m);
476
477 // Need to update representative information here...
479
480 std::vector<DenseVertex> interfaceNeighborhood;
481 std::set<SparseVertex> interfaceRepresentatives;
482
483 getInterfaceNeighborRepresentatives(m, interfaceRepresentatives);
484 getInterfaceNeighborhood(m, interfaceNeighborhood);
485 addToRepresentatives(m, representativesProperty_[m], interfaceRepresentatives);
486 foreach (DenseVertex qp, interfaceNeighborhood)
487 {
489 getInterfaceNeighborRepresentatives(qp, interfaceRepresentatives);
490 addToRepresentatives(qp, representativesProperty_[qp], interfaceRepresentatives);
491 }
492
493 return m;
494}
495
497{
498 std::lock_guard<std::mutex> _(graphMutex_);
499
500 SparseVertex v = boost::add_vertex(s_);
501 sparseStateProperty_[v] = state;
502 sparseColorProperty_[v] = type;
503
504 sparseDJSets_.make_set(v);
505
506 snn_->add(v);
508
510 return v;
511}
512
514{
515 const base::Cost weight(costHeuristic(v, vp));
516 const SpannerGraph::edge_property_type properties(weight);
517 std::lock_guard<std::mutex> _(graphMutex_);
518 boost::add_edge(v, vp, properties, s_);
519 sparseDJSets_.union_set(v, vp);
520}
521
523{
524 const double weight = distanceFunction(v, vp);
525 const DenseGraph::edge_property_type properties(weight);
526 std::lock_guard<std::mutex> _(graphMutex_);
527 boost::add_edge(v, vp, properties, g_);
528}
529
530bool ompl::geometric::SPARS::checkAddCoverage(const base::State *lastState, const std::vector<SparseVertex> &neigh)
531{
532 // For each of these neighbors,
533 foreach (SparseVertex n, neigh)
534 // If path between is free
535 if (si_->checkMotion(lastState, sparseStateProperty_[n]))
536 // Abort out and return false
537 return false;
538 // No free paths means we add for coverage
539 addGuard(si_->cloneState(lastState), COVERAGE);
540 return true;
541}
542
543bool ompl::geometric::SPARS::checkAddConnectivity(const base::State *lastState, const std::vector<SparseVertex> &neigh)
544{
545 std::vector<SparseVertex> links;
546 // For each neighbor
547 for (std::size_t i = 0; i < neigh.size(); ++i)
548 // For each other neighbor
549 for (std::size_t j = i + 1; j < neigh.size(); ++j)
550 // If they are in different components
551 if (!sameComponent(neigh[i], neigh[j]))
552 // If the paths between are collision free
553 if (si_->checkMotion(lastState, sparseStateProperty_[neigh[i]]) &&
554 si_->checkMotion(lastState, sparseStateProperty_[neigh[j]]))
555 {
556 links.push_back(neigh[i]);
557 links.push_back(neigh[j]);
558 }
559
560 if (!links.empty())
561 {
562 // Add the node
563 SparseVertex g = addGuard(si_->cloneState(lastState), CONNECTIVITY);
564
565 for (unsigned long link : links)
566 // If there's no edge
567 if (!boost::edge(g, link, s_).second)
568 // And the components haven't been united by previous links
569 if (!sameComponent(link, g))
570 connectSparsePoints(g, link);
571 return true;
572 }
573 return false;
574}
575
576bool ompl::geometric::SPARS::checkAddInterface(const std::vector<SparseVertex> &graphNeighborhood,
577 const std::vector<SparseVertex> &visibleNeighborhood, DenseVertex q)
578{
579 // If we have more than 1 neighbor
580 if (visibleNeighborhood.size() > 1)
581 // If our closest neighbors are also visible
582 if (graphNeighborhood[0] == visibleNeighborhood[0] && graphNeighborhood[1] == visibleNeighborhood[1])
583 // If our two closest neighbors don't share an edge
584 if (!boost::edge(visibleNeighborhood[0], visibleNeighborhood[1], s_).second)
585 {
586 // If they can be directly connected
587 if (si_->checkMotion(sparseStateProperty_[visibleNeighborhood[0]],
588 sparseStateProperty_[visibleNeighborhood[1]]))
589 {
590 // Connect them
591 connectSparsePoints(visibleNeighborhood[0], visibleNeighborhood[1]);
592 // And report that we added to the roadmap
594 // Report success
595 return true;
596 }
597
598 // Add the new node to the graph, to bridge the interface
599 SparseVertex v = addGuard(si_->cloneState(stateProperty_[q]), INTERFACE);
600 connectSparsePoints(v, visibleNeighborhood[0]);
601 connectSparsePoints(v, visibleNeighborhood[1]);
602 // Report success
603 return true;
604 }
605 return false;
606}
607
608bool ompl::geometric::SPARS::checkAddPath(DenseVertex q, const std::vector<DenseVertex> &neigh)
609{
610 bool result = false;
611
612 // Get q's representative => v
614
615 // Extract the representatives of neigh => n_rep
616 std::set<SparseVertex> n_rep;
617 foreach (DenseVertex qp, neigh)
618 n_rep.insert(representativesProperty_[qp]);
619
620 std::vector<SparseVertex> Xs;
621 // for each v' in n_rep
622 for (auto it = n_rep.begin(); it != n_rep.end() && !result; ++it)
623 {
624 SparseVertex vp = *it;
625 // Identify appropriate v" candidates => vpps
626 std::vector<SparseVertex> VPPs;
627 computeVPP(v, vp, VPPs);
628
629 foreach (SparseVertex vpp, VPPs)
630 {
631 double s_max = 0;
632 // Find the X nodes to test
633 computeX(v, vp, vpp, Xs);
634
635 // For each x in xs
636 foreach (SparseVertex x, Xs)
637 {
638 // Compute/Retain MAXimum distance path thorugh S
639 double dist = (si_->distance(sparseStateProperty_[x], sparseStateProperty_[v]) +
640 si_->distance(sparseStateProperty_[v], sparseStateProperty_[vp])) /
641 2.0;
642 if (dist > s_max)
643 s_max = dist;
644 }
645
646 DensePath bestDPath;
647 DenseVertex best_qpp = boost::graph_traits<DenseGraph>::null_vertex();
648 double d_min = std::numeric_limits<double>::infinity(); // Insanely big number
649 // For each vpp in vpps
650 for (std::size_t j = 0; j < VPPs.size() && !result; ++j)
651 {
652 SparseVertex vpp = VPPs[j];
653 // For each q", which are stored interface nodes on v for i(vpp,v)
654 foreach (DenseVertex qpp, interfaceListsProperty_[v][vpp])
655 {
656 // check that representatives are consistent
657 assert(representativesProperty_[qpp] == v);
658
659 // If they happen to be the one and same node
660 if (q == qpp)
661 {
662 bestDPath.push_front(stateProperty_[q]);
663 best_qpp = qpp;
664 d_min = 0;
665 }
666 else
667 {
668 // Compute/Retain MINimum distance path on D through q, q"
669 DensePath dPath;
670 computeDensePath(q, qpp, dPath);
671 if (!dPath.empty())
672 {
673 // compute path length
674 double length = 0.0;
675 DensePath::const_iterator jt = dPath.begin();
676 for (auto it = jt + 1; it != dPath.end(); ++it)
677 {
678 length += si_->distance(*jt, *it);
679 jt = it;
680 }
681
682 if (length < d_min)
683 {
684 d_min = length;
685 bestDPath.swap(dPath);
686 best_qpp = qpp;
687 }
688 }
689 }
690 }
691
692 // If the spanner property is violated for these paths
693 if (s_max > stretchFactor_ * d_min)
694 {
695 // Need to augment this path with the appropriate neighbor information
697 DenseVertex nb = getInterfaceNeighbor(best_qpp, vpp);
698
699 bestDPath.push_front(stateProperty_[na]);
700 bestDPath.push_back(stateProperty_[nb]);
701
702 // check consistency of representatives
703 assert(representativesProperty_[na] == vp && representativesProperty_[nb] == vpp);
704
705 // Add the dense path to the spanner
706 addPathToSpanner(bestDPath, vpp, vp);
707
708 // Report success
709 result = true;
710 }
711 }
712 }
713 }
714 return result;
715}
716
718{
719 double degree = 0.0;
720 foreach (DenseVertex v, boost::vertices(s_))
721 degree += (double)boost::out_degree(v, s_);
722 degree /= (double)boost::num_vertices(s_);
723 return degree;
724}
725
726void ompl::geometric::SPARS::printDebug(std::ostream &out) const
727{
728 out << "SPARS Debug Output: " << std::endl;
729 out << " Settings: " << std::endl;
730 out << " Max Failures: " << getMaxFailures() << std::endl;
731 out << " Dense Delta Fraction: " << getDenseDeltaFraction() << std::endl;
732 out << " Sparse Delta Fraction: " << getSparseDeltaFraction() << std::endl;
733 out << " Stretch Factor: " << getStretchFactor() << std::endl;
734 out << " Status: " << std::endl;
735 out << " Milestone Count: " << milestoneCount() << std::endl;
736 out << " Guard Count: " << guardCount() << std::endl;
737 out << " Iterations: " << getIterationCount() << std::endl;
738 out << " Average Valence: " << averageValence() << std::endl;
739 out << " Consecutive Failures: " << consecutiveFailures_ << std::endl;
740}
741
742void ompl::geometric::SPARS::getSparseNeighbors(base::State *inState, std::vector<SparseVertex> &graphNeighborhood)
743{
745
746 graphNeighborhood.clear();
747 snn_->nearestR(sparseQueryVertex_, sparseDelta_, graphNeighborhood);
748
750}
751
753 const std::vector<SparseVertex> &graphNeighborhood,
754 std::vector<SparseVertex> &visibleNeighborhood) const
755{
756 visibleNeighborhood.clear();
757 // Now that we got the neighbors from the NN, we must remove any we can't see
758 for (unsigned long i : graphNeighborhood)
759 if (si_->checkMotion(inState, sparseStateProperty_[i]))
760 visibleNeighborhood.push_back(i);
761}
762
764{
765 foreach (DenseVertex vp, boost::adjacent_vertices(q, g_))
766 if (representativesProperty_[vp] == rep)
767 if (distanceFunction(q, vp) <= denseDelta_)
768 return vp;
769 throw Exception(name_, "Vertex has no interface neighbor with given representative");
770}
771
773{
774 // First, check to see that the path has length
775 if (dense_path.size() <= 1)
776 {
777 // The path is 0 length, so simply link the representatives
778 connectSparsePoints(vp, vpp);
780 }
781 else
782 {
783 // We will need to construct a PathGeometric to do this.
784 geomPath_.getStates().resize(dense_path.size());
785 std::copy(dense_path.begin(), dense_path.end(), geomPath_.getStates().begin());
786
787 // Attempt to simplify the path
788 psimp_->reduceVertices(geomPath_, geomPath_.getStateCount() * 2);
789
790 // we are sure there are at least 2 points left on geomPath_
791
792 std::vector<SparseVertex> added_nodes;
793 added_nodes.reserve(geomPath_.getStateCount());
794 for (std::size_t i = 0; i < geomPath_.getStateCount(); ++i)
795 {
796 // Add each guard
797 SparseVertex ng = addGuard(si_->cloneState(geomPath_.getState(i)), QUALITY);
798 added_nodes.push_back(ng);
799 }
800 // Link them up
801 for (std::size_t i = 1; i < added_nodes.size(); ++i)
802 {
803 connectSparsePoints(added_nodes[i - 1], added_nodes[i]);
804 }
805 // Don't forget to link them to their representatives
806 connectSparsePoints(added_nodes[0], vp);
807 connectSparsePoints(added_nodes[added_nodes.size() - 1], vpp);
808 }
809 geomPath_.getStates().clear();
810 return true;
811}
812
814{
815 // Get all of the dense samples which may be affected by adding this node
816 std::vector<DenseVertex> dense_points;
817
819
820 nn_->nearestR(queryVertex_, sparseDelta_ + denseDelta_, dense_points);
821
822 stateProperty_[queryVertex_] = nullptr;
823
824 // For each of those points
825 for (unsigned long dense_point : dense_points)
826 {
827 // Remove that point from the old representative's list(s)
828 removeFromRepresentatives(dense_point, representativesProperty_[dense_point]);
829 // Update that point's representative
830 calculateRepresentative(dense_point);
831 }
832
833 std::set<SparseVertex> interfaceRepresentatives;
834 // For each of the points
835 for (unsigned long dense_point : dense_points)
836 {
837 // Get it's representative
838 SparseVertex rep = representativesProperty_[dense_point];
839 // Extract the representatives of any interface-sharing neighbors
840 getInterfaceNeighborRepresentatives(dense_point, interfaceRepresentatives);
841 // For sanity's sake, make sure we clear ourselves out of what this new rep might think of us
842 removeFromRepresentatives(dense_point, rep);
843 // Add this vertex to it's representative's list for the other representatives
844 addToRepresentatives(dense_point, rep, interfaceRepresentatives);
845 }
846}
847
849{
850 // Get the nearest neighbors within sparseDelta_
851 std::vector<SparseVertex> graphNeighborhood;
852 getSparseNeighbors(stateProperty_[q], graphNeighborhood);
853
854 // For each neighbor
855 for (unsigned long i : graphNeighborhood)
856 if (si_->checkMotion(stateProperty_[q], sparseStateProperty_[i]))
857 {
858 // update the representative
860 // abort
861 break;
862 }
863}
864
865void ompl::geometric::SPARS::addToRepresentatives(DenseVertex q, SparseVertex rep, const std::set<SparseVertex> &oreps)
866{
867 // If this node supports no interfaces
868 if (oreps.empty())
869 {
870 // Add it to the pool of non-interface nodes
871 bool new_insert = nonInterfaceListsProperty_[rep].insert(q).second;
872
873 // we expect this was not previously tracked
874 if (!new_insert)
875 assert(false);
876 }
877 else
878 {
879 // otherwise, for every neighbor representative
880 foreach (SparseVertex v, oreps)
881 {
882 assert(rep == representativesProperty_[q]);
883 bool new_insert = interfaceListsProperty_[rep][v].insert(q).second;
884 if (!new_insert)
885 assert(false);
886 }
887 }
888}
889
891{
892 // Remove the node from the non-interface points (if there)
893 nonInterfaceListsProperty_[rep].erase(q);
894
895 // From each of the interfaces
896 foreach (SparseVertex vpp, interfaceListsProperty_[rep] | boost::adaptors::map_keys)
897 {
898 // Remove this node from that list
899 interfaceListsProperty_[rep][vpp].erase(q);
900 }
901}
902
903void ompl::geometric::SPARS::computeVPP(SparseVertex v, SparseVertex vp, std::vector<SparseVertex> &VPPs)
904{
905 foreach (SparseVertex cvpp, boost::adjacent_vertices(v, s_))
906 if (cvpp != vp)
907 if (!boost::edge(cvpp, vp, s_).second)
908 VPPs.push_back(cvpp);
909}
910
911void ompl::geometric::SPARS::computeX(SparseVertex v, SparseVertex vp, SparseVertex vpp, std::vector<SparseVertex> &Xs)
912{
913 Xs.clear();
914 foreach (SparseVertex cx, boost::adjacent_vertices(vpp, s_))
915 if (boost::edge(cx, v, s_).second && !boost::edge(cx, vp, s_).second)
916 if (!interfaceListsProperty_[vpp][cx].empty())
917 Xs.push_back(cx);
918 Xs.push_back(vpp);
919}
920
922 std::set<SparseVertex> &interfaceRepresentatives)
923{
924 interfaceRepresentatives.clear();
925
926 // Get our representative
928 // For each neighbor we are connected to
929 foreach (DenseVertex n, boost::adjacent_vertices(q, g_))
930 {
931 // Get his representative
933 // If that representative is not our own
934 if (orep != rep)
935 // If he is within denseDelta_
936 if (distanceFunction(q, n) < denseDelta_)
937 // Include his rep in the set
938 interfaceRepresentatives.insert(orep);
939 }
940}
941
942void ompl::geometric::SPARS::getInterfaceNeighborhood(DenseVertex q, std::vector<DenseVertex> &interfaceNeighborhood)
943{
944 interfaceNeighborhood.clear();
945
946 // Get our representative
948
949 // For each neighbor we are connected to
950 foreach (DenseVertex n, boost::adjacent_vertices(q, g_))
951 // If neighbor representative is not our own
952 if (representativesProperty_[n] != rep)
953 // If he is within denseDelta_
954 if (distanceFunction(q, n) < denseDelta_)
955 // Append him to the list
956 interfaceNeighborhood.push_back(n);
957}
958
959ompl::base::PathPtr ompl::geometric::SPARS::constructSolution(const SparseVertex start, const SparseVertex goal) const
960{
961 std::lock_guard<std::mutex> _(graphMutex_);
962
963 boost::vector_property_map<SparseVertex> prev(boost::num_vertices(s_));
964
965 try
966 {
967 // Consider using a persistent distance_map if it's slow
968 boost::astar_search(
969 s_, start, [this, goal](SparseVertex v) { return costHeuristic(v, goal); },
970 boost::predecessor_map(prev)
971 .distance_compare([this](base::Cost c1, base::Cost c2) { return opt_->isCostBetterThan(c1, c2); })
972 .distance_combine([this](base::Cost c1, base::Cost c2) { return opt_->combineCosts(c1, c2); })
973 .distance_inf(opt_->infiniteCost())
974 .distance_zero(opt_->identityCost())
975 .visitor(AStarGoalVisitor<SparseVertex>(goal)));
976 }
977 catch (AStarFoundGoal &)
978 {
979 }
980
981 if (prev[goal] == goal)
982 throw Exception(name_, "Could not find solution path");
983 else
984 {
985 auto p(std::make_shared<PathGeometric>(si_));
986
987 for (SparseVertex pos = goal; prev[pos] != pos; pos = prev[pos])
988 p->append(sparseStateProperty_[pos]);
989 p->append(sparseStateProperty_[start]);
990 p->reverse();
991
992 return p;
993 }
994}
995
997{
998 path.clear();
999
1000 boost::vector_property_map<DenseVertex> prev(boost::num_vertices(g_));
1001
1002 try
1003 {
1004 boost::astar_search(
1005 g_, start, [this, goal](const DenseVertex a) { return distanceFunction(a, goal); },
1006 boost::predecessor_map(prev).visitor(AStarGoalVisitor<DenseVertex>(goal)));
1007 }
1008 catch (AStarFoundGoal &)
1009 {
1010 }
1011
1012 if (prev[goal] == goal)
1013 OMPL_WARN("%s: No dense path was found?", getName().c_str());
1014 else
1015 {
1016 for (DenseVertex pos = goal; prev[pos] != pos; pos = prev[pos])
1017 path.push_front(stateProperty_[pos]);
1018 path.push_front(stateProperty_[start]);
1019 }
1020}
1021
1023{
1024 Planner::getPlannerData(data);
1025
1026 // Explicitly add start and goal states:
1027 for (unsigned long i : startM_)
1029
1030 for (unsigned long i : goalM_)
1032
1033 // Adding edges and all other vertices simultaneously
1034 foreach (const SparseEdge e, boost::edges(s_))
1035 {
1036 const SparseVertex v1 = boost::source(e, s_);
1037 const SparseVertex v2 = boost::target(e, s_);
1040
1041 // Add the reverse edge, since we're constructing an undirected roadmap
1044 }
1045
1046 // Make sure to add edge-less nodes as well
1047 foreach (const SparseVertex n, boost::vertices(s_))
1048 if (boost::out_degree(n, s_) == 0)
1050}
1051
The exception type for ompl.
Definition Exception.h:47
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
Definition Cost.h:48
Abstract definition of a goal region that can be sampled.
Abstract definition of goals.
Definition Goal.h:63
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:136
An optimization objective which corresponds to optimizing path length.
Base class for a vertex in the PlannerData structure. All derived classes must implement the clone an...
Definition PlannerData.h:59
Object containing planner generated vertex and edge data. It is assumed that all vertices are unique,...
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...
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...
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...
unsigned int addVertex(const PlannerDataVertex &st)
Adds the given vertex to the graph data. The vertex index is returned. Duplicates are not added....
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
bool isSetup() const
Check if setup() was called for this planner.
Definition Planner.cpp:113
PlannerInputStates pis_
Utility class to extract valid input states.
Definition Planner.h:407
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:394
PlannerSpecs specs_
The specifications of the planner (its capabilities).
Definition Planner.h:413
ProblemDefinitionPtr pdef_
The user set problem definition.
Definition Planner.h:404
std::string name_
The name of this planner.
Definition Planner.h:410
const std::string & getName() const
Get the name of the planner.
Definition Planner.cpp:56
SpaceInformationPtr si_
The space information for which planning is done.
Definition Planner.h:401
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:106
bool setup_
Flag indicating whether setup() has been called.
Definition Planner.h:424
Definition of an abstract state.
Definition State.h:50
Make the minimal number of connections required to ensure asymptotic optimality.
void setup() override
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition SPARS.cpp:94
double denseDelta_
SPARS parameter for dense graph connection distance.
Definition SPARS.h:563
long unsigned int iterations_
A counter for the number of iterations of the algorithm.
Definition SPARS.h:584
bool checkAddPath(DenseVertex q, const std::vector< DenseVertex > &neigh)
Checks for adding an entire dense path to the Sparse Roadmap.
Definition SPARS.cpp:608
bool reachedFailureLimit() const
Returns true if we have reached the iteration failures limit, maxFailures_.
Definition SPARS.cpp:283
void getInterfaceNeighborRepresentatives(DenseVertex q, std::set< SparseVertex > &interfaceRepresentatives)
Gets the representatives of all interfaces that q supports.
Definition SPARS.cpp:921
boost::property_map< SpannerGraph, vertex_state_t >::type sparseStateProperty_
Access to the internal base::State for each SparseVertex of S.
Definition SPARS.h:516
void getSparseNeighbors(base::State *inState, std::vector< SparseVertex > &graphNeighborhood)
Get all nodes in the sparse graph which are within sparseDelta_ of the given state.
Definition SPARS.cpp:742
double sparseDelta_
SPARS parameter for Sparse Roadmap connection distance.
Definition SPARS.h:566
std::vector< SparseVertex > goalM_
Array of goal guards.
Definition SPARS.h:501
void computeX(DenseVertex v, DenseVertex vp, DenseVertex vpp, std::vector< SparseVertex > &Xs)
Computes all nodes which qualify as a candidate x for v, v', and v".
Definition SPARS.cpp:911
boost::graph_traits< DenseGraph >::vertex_descriptor DenseVertex
A vertex in DenseGraph.
Definition SPARS.h:184
~SPARS() override
Destructor.
Definition SPARS.cpp:89
DenseVertex addMilestone(base::State *state)
Construct a milestone for a given state (state) and store it in the nearest neighbors data structure.
Definition SPARS.cpp:456
void setStretchFactor(double t)
Set the roadmap spanner stretch factor. This value represents a multiplicative upper bound on path qu...
Definition SPARS.h:292
double stretchFactor_
The stretch factor in terms of graph spanners for SPARS to check against.
Definition SPARS.h:548
void checkQueryStateInitialization()
Check that the query vertex is initialized (used for internal nearest neighbor searches).
Definition SPARS.cpp:288
void getPlannerData(base::PlannerData &data) const override
Get information about the current run of the motion planner. Repeated calls to this function will upd...
Definition SPARS.cpp:1022
void connectDensePoints(DenseVertex v, DenseVertex vp)
Connects points in the dense graph.
Definition SPARS.cpp:522
void clear() override
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
Definition SPARS.cpp:158
unsigned int consecutiveFailures_
A counter for the number of consecutive failed iterations of the algorithm.
Definition SPARS.h:545
base::Cost costHeuristic(SparseVertex u, SparseVertex v) const
Given two vertices, returns a heuristic on the cost of the path connecting them. This method wraps Op...
Definition SPARS.cpp:1052
bool reachedTerminationCriterion() const
Returns true if we have reached the iteration failures limit, maxFailures_ or if a solution was added...
Definition SPARS.cpp:278
base::PathPtr constructSolution(SparseVertex start, SparseVertex goal) const
Given two milestones from the same connected component, construct a path connecting them and set it a...
Definition SPARS.cpp:959
std::function< const std::vector< DenseVertex > &(const DenseVertex)> connectionStrategy_
Function that returns the milestones to attempt connections with.
Definition SPARS.h:542
void setDenseDeltaFraction(double d)
Set the delta fraction for interface detection. If two nodes in the dense graph are more than a delta...
Definition SPARS.h:269
DenseNeighbors nn_
Nearest neighbors data structure.
Definition SPARS.h:486
void updateRepresentatives(SparseVertex v)
Automatically updates the representatives of all dense samplse within sparseDelta_ of v.
Definition SPARS.cpp:813
base::OptimizationObjectivePtr opt_
Objective cost function for PRM graph edges.
Definition SPARS.h:575
double getDenseDeltaFraction() const
Retrieve the dense graph interface support delta fraction.
Definition SPARS.h:304
bool checkAddInterface(const std::vector< DenseVertex > &graphNeighborhood, const std::vector< DenseVertex > &visibleNeighborhood, DenseVertex q)
Checks the latest dense sample for bridging an edge-less interface.
Definition SPARS.cpp:576
PathGeometric geomPath_
Geometric Path variable used for smoothing out paths.
Definition SPARS.h:510
DenseVertex queryVertex_
Vertex for performing nearest neighbor queries on the DENSE graph.
Definition SPARS.h:507
SparseVertex addGuard(base::State *state, GuardType type)
Construct a node with the given state (state) for the spanner and store it in the nn structure.
Definition SPARS.cpp:496
std::deque< base::State * > DensePath
Internal representation of a dense path.
Definition SPARS.h:123
void computeDensePath(DenseVertex start, DenseVertex goal, DensePath &path) const
Constructs the dense path between the start and goal vertices (if connected).
Definition SPARS.cpp:996
unsigned int guardCount() const
Returns the number of guards added to S.
Definition SPARS.h:344
boost::graph_traits< SpannerGraph >::edge_descriptor SparseEdge
An edge in the sparse roadmap that is constructed.
Definition SPARS.h:154
boost::graph_traits< SpannerGraph >::vertex_descriptor SparseVertex
A vertex in the sparse roadmap that is constructed.
Definition SPARS.h:151
double averageValence() const
Returns the average valence of the spanner graph.
Definition SPARS.cpp:717
bool checkAddConnectivity(const base::State *lastState, const std::vector< SparseVertex > &neigh)
Checks the latest dense sample for connectivity, and adds appropriately.
Definition SPARS.cpp:543
std::vector< SparseVertex > startM_
Array of start guards.
Definition SPARS.h:498
boost::property_map< SpannerGraph, vertex_interface_list_t >::type interfaceListsProperty_
Access to the interface-supporting vertice hashes of the sparse nodes.
Definition SPARS.h:528
bool addedSolution_
A flag indicating that a solution has been added during solve().
Definition SPARS.h:554
DenseVertex getInterfaceNeighbor(DenseVertex q, SparseVertex rep)
Get the first neighbor of q who has representative rep and is within denseDelta_.
Definition SPARS.cpp:763
boost::property_map< DenseGraph, vertex_state_t >::type stateProperty_
Access to the internal base::state at each DenseVertex.
Definition SPARS.h:513
void clearQuery() override
Clear the query previously loaded from the ProblemDefinition. Subsequent calls to solve() will reuse ...
Definition SPARS.cpp:147
boost::property_map< DenseGraph, vertex_representative_t >::type representativesProperty_
Access to the representatives of the Dense vertices.
Definition SPARS.h:522
unsigned getMaxFailures() const
Retrieve the maximum consecutive failure limit.
Definition SPARS.h:298
void calculateRepresentative(DenseVertex q)
Calculates the representative for a dense sample.
Definition SPARS.cpp:848
DenseVertex sparseQueryVertex_
DenseVertex for performing nearest neighbor queries on the SPARSE roadmap.
Definition SPARS.h:504
void setSparseDeltaFraction(double d)
Set the delta fraction for connection distance on the sparse spanner. This value represents the visib...
Definition SPARS.h:280
void printDebug(std::ostream &out=std::cout) const
Print debug information about planner.
Definition SPARS.cpp:726
std::mutex graphMutex_
Mutex to guard access to the graphs.
Definition SPARS.h:572
boost::property_map< SpannerGraph, vertex_color_t >::type sparseColorProperty_
Access to draw colors for the SparseVertexs of S, to indicate addition type.
Definition SPARS.h:519
void constructRoadmap(const base::PlannerTerminationCondition &ptc)
While the termination condition permits, construct the spanner graph.
Definition SPARS.cpp:397
base::Cost bestCost_
Best cost found so far by algorithm.
Definition SPARS.h:586
PathSimplifierPtr psimp_
A path simplifier used to simplify dense paths added to S.
Definition SPARS.h:531
double sparseDistanceFunction(const SparseVertex a, const SparseVertex b) const
Compute distance between two nodes in the sparse roadmap spanner.
Definition SPARS.h:477
base::PlannerStatus solve(const base::PlannerTerminationCondition &ptc) override
Function that can solve the motion planning problem. This function can be called multiple times on th...
Definition SPARS.cpp:305
bool haveSolution(const std::vector< DenseVertex > &starts, const std::vector< DenseVertex > &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 SPARS.cpp:237
GuardType
Enumeration which specifies the reason a guard is added to the spanner.
Definition SPARS.h:82
double denseDeltaFraction_
SPARS parameter for dense graph connection distance as a fraction of max. extent.
Definition SPARS.h:557
void connectSparsePoints(SparseVertex v, SparseVertex vp)
Convenience function for creating an edge in the Spanner Roadmap.
Definition SPARS.cpp:513
SpannerGraph s_
The sparse roadmap, S.
Definition SPARS.h:495
void freeMemory()
Free all the memory allocated by the planner.
Definition SPARS.cpp:173
boost::disjoint_sets< boost::property_map< SpannerGraph, boost::vertex_rank_t >::type, boost::property_map< SpannerGraph, boost::vertex_predecessor_t >::type > sparseDJSets_
Data structure that maintains the connected components of S.
Definition SPARS.h:539
boost::property_map< SpannerGraph, vertex_list_t >::type nonInterfaceListsProperty_
Access to all non-interface supporting vertices of the sparse nodes.
Definition SPARS.h:525
base::ValidStateSamplerPtr sampler_
Sampler user for generating valid samples in the state space.
Definition SPARS.h:483
bool addPathToSpanner(const DensePath &dense_path, SparseVertex vp, SparseVertex vpp)
Method for actually adding a dense path to the Roadmap Spanner, S.
Definition SPARS.cpp:772
boost::property_map< DenseGraph, boost::edge_weight_t >::type weightProperty_
Access to the weights of each DenseEdge.
Definition SPARS.h:534
double sparseDeltaFraction_
SPARS parameter for Sparse Roadmap connection distance as a fraction of max. extent.
Definition SPARS.h:560
void addToRepresentatives(DenseVertex q, SparseVertex rep, const std::set< SparseVertex > &oreps)
Adds a dense sample to the appropriate lists of its representative.
Definition SPARS.cpp:865
bool checkAddCoverage(const base::State *lastState, const std::vector< SparseVertex > &neigh)
Checks the latest dense sample for the coverage property, and adds appropriately.
Definition SPARS.cpp:530
SparseNeighbors snn_
Nearest Neighbors structure for the sparse roadmap.
Definition SPARS.h:489
DenseGraph g_
The dense graph, D.
Definition SPARS.h:492
unsigned int maxFailures_
The maximum number of failures before terminating the algorithm.
Definition SPARS.h:551
void resetFailures()
A reset function for resetting the failures count.
Definition SPARS.cpp:142
void setMaxFailures(unsigned int m)
Set the maximum consecutive failures to augment the spanner before termination. In general,...
Definition SPARS.h:261
double distanceFunction(const DenseVertex a, const DenseVertex b) const
Compute distance between two milestones (this is simply distance between the states of the milestones...
Definition SPARS.h:471
double getStretchFactor() const
Retrieve the spanner's set stretch factor.
Definition SPARS.h:316
void computeVPP(DenseVertex v, DenseVertex vp, std::vector< SparseVertex > &VPPs)
Computes all nodes which qualify as a candidate v" for v and vp.
Definition SPARS.cpp:903
DenseVertex addSample(base::State *workState, const base::PlannerTerminationCondition &ptc)
Attempt to add a single sample to the roadmap.
Definition SPARS.cpp:191
unsigned int milestoneCount() const
Returns the number of milestones added to D.
Definition SPARS.h:338
double getSparseDeltaFraction() const
Retrieve the sparse graph visibility range delta fraction.
Definition SPARS.h:310
void getInterfaceNeighborhood(DenseVertex q, std::vector< DenseVertex > &interfaceNeighborhood)
Gets the neighbors of q who help it support an interface.
Definition SPARS.cpp:942
void filterVisibleNeighbors(base::State *inState, const std::vector< SparseVertex > &graphNeighborhood, std::vector< SparseVertex > &visibleNeighborhood) const
Get the visible neighbors.
Definition SPARS.cpp:752
void removeFromRepresentatives(DenseVertex q, SparseVertex rep)
Removes the node from its representative's lists.
Definition SPARS.cpp:890
bool sameComponent(SparseVertex m1, SparseVertex m2)
Check that two vertices are in the same connected component.
Definition SPARS.cpp:300
void checkForSolution(const base::PlannerTerminationCondition &ptc, base::PathPtr &solution)
Definition SPARS.cpp:213
SPARS(const base::SpaceInformationPtr &si)
Constructor.
Definition SPARS.cpp:54
static NearestNeighbors< _T > * getDefaultNearestNeighbors(const base::Planner *planner)
Select a default nearest neighbor datastructure for the given space.
Definition SelfConfig.h:105
#define OMPL_INFORM(fmt,...)
Log a formatted information string.
Definition Console.h:68
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
Definition Console.h:64
#define OMPL_WARN(fmt,...)
Log a formatted warning string.
Definition Console.h:66
This namespace contains sampling based planning routines shared by both planning under geometric cons...
@ GOAL_SAMPLEABLE_REGION
This bit is set if casting to sampleable goal regions (ompl::base::GoalSampleableRegion) is possible.
Definition GoalTypes.h:56
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 ...
A class to store the exit status of Planner::solve().
@ INVALID_START
Invalid start state or no start state specified.
@ EXACT_SOLUTION
The planner found an exact solution.
@ INVALID_GOAL
Invalid goal state.
@ UNRECOGNIZED_GOAL_TYPE
The goal is of a type that a planner does not recognize.
@ TIMEOUT
The planner failed to find a solution.
@ INFEASIBLE
The planner decided that problem is infeasible.