Loading...
Searching...
No Matches
BundleSpaceGraph.cpp
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2019, University of Stuttgart
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 the University of Stuttgart nor the names
18 * of its contributors may be used to endorse or promote products
19 * derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *********************************************************************/
35
36/* Author: Andreas Orthey */
37
38#include <ompl/multilevel/datastructures/PlannerDataVertexAnnotated.h>
39#include <ompl/multilevel/datastructures/BundleSpaceGraph.h>
40#include <ompl/multilevel/datastructures/src/BundleSpaceGraphGoalVisitor.hpp>
41#include <ompl/multilevel/datastructures/Projection.h>
42
43#include <ompl/multilevel/datastructures/graphsampler/RandomVertex.h>
44#include <ompl/multilevel/datastructures/graphsampler/RandomDegreeVertex.h>
45#include <ompl/multilevel/datastructures/graphsampler/RandomEdge.h>
46#include <ompl/multilevel/datastructures/importance/Greedy.h>
47#include <ompl/multilevel/datastructures/importance/Exponential.h>
48#include <ompl/multilevel/datastructures/importance/Uniform.h>
49#include <ompl/multilevel/datastructures/metrics/Geodesic.h>
50#include <ompl/multilevel/datastructures/propagators/Geometric.h>
51#include <ompl/multilevel/datastructures/pathrestriction/PathRestriction.h>
52
53#include <ompl/geometric/PathSimplifier.h>
54#include <ompl/base/goals/GoalSampleableRegion.h>
55#include <ompl/base/objectives/PathLengthOptimizationObjective.h>
56#include <ompl/base/objectives/MaximizeMinClearanceObjective.h>
57#include <ompl/datastructures/PDF.h>
58#include <ompl/tools/config/SelfConfig.h>
59#include <ompl/tools/config/MagicConstants.h>
60#include <ompl/util/Exception.h>
61#include <ompl/control/SpaceInformation.h>
62
63#include <ompl/datastructures/NearestNeighborsSqrtApprox.h>
64
65#include <boost/graph/astar_search.hpp>
66#include <boost/graph/incremental_components.hpp>
67#include <boost/graph/graphviz.hpp>
68#include <boost/property_map/vector_property_map.hpp>
69#include <boost/property_map/transform_value_property_map.hpp>
70
71#include <boost/foreach.hpp>
72
73#define foreach BOOST_FOREACH
74
76
77using namespace ompl::multilevel;
78
79BundleSpaceGraph::BundleSpaceGraph(const ompl::base::SpaceInformationPtr &si, BundleSpace *parent_) : BaseT(si, parent_)
80{
81 setName("BundleSpaceGraph");
82
83 // Functional primitives
84 setMetric("geodesic");
85 setGraphSampler("randomvertex");
86 setImportance("uniform");
87 setFindSectionStrategy(FindSectionType::SIDE_STEP);
88
89 if (isDynamic())
90 {
91 setPropagator("dynamic");
92 }
93 else
94 {
95 setPropagator("geometric");
96 }
97
98 specs_.recognizedGoal = base::GOAL_SAMPLEABLE_REGION;
99 specs_.approximateSolutions = false;
100 specs_.optimizingPaths = false;
101
102 Planner::declareParam<double>("range", this, &BundleSpaceGraph::setRange, &BundleSpaceGraph::getRange,
103 "0.:1.:"
104 "10000.");
105
106 Planner::declareParam<double>("goal_bias", this, &BundleSpaceGraph::setGoalBias, &BundleSpaceGraph::getGoalBias,
107 "0.:.1:1.");
108
109 xRandom_ = new Configuration(getBundle());
110}
111
112BundleSpaceGraph::~BundleSpaceGraph()
113{
114 deleteConfiguration(xRandom_);
115}
116
118{
119 BaseT::setup();
120
123
124 OMPL_DEBUG("Range distance graph sampling: %f (max extent %f)", maxDistance_, getBundle()->getMaximumExtent());
125
127 {
128 if (!isDynamic())
129 {
131 }
132 else
133 {
134 // for dynamical systems, we use a quasimetric
135 //(non-symmetric metric), so we cannot use NN structures like GNAT
137 }
138 nearestDatastructure_->setDistanceFunction([this](const Configuration *a, const Configuration *b)
139 { return distance(a, b); });
140 }
141
142 if (hasBaseSpace() && getProjection()->isFibered())
143 {
144 pathRestriction_ = std::make_shared<PathRestriction>(this);
145 }
146
147 if (pdef_)
148 {
149 setup_ = true;
150
151 optimizer_ = std::make_shared<ompl::geometric::PathSimplifier>(getBundle(), pdef_->getGoal(),
152 getOptimizationObjectivePtr());
153 optimizer_->freeStates(false);
154 }
155 else
156 {
157 setup_ = false;
158 }
159}
160
161void BundleSpaceGraph::setFindSectionStrategy(FindSectionType type)
162{
163 if (pathRestriction_ != nullptr)
164 {
165 pathRestriction_->setFindSectionStrategy(type);
166 }
167}
168
170{
171 if (hasBaseSpace() && getProjection()->isFibered())
172 {
173 base::PathPtr basePath = static_cast<BundleSpaceGraph *>(getChild())->getSolutionPathByReference();
174 pathRestriction_->setBasePath(basePath);
175
176 if (pathRestriction_->hasFeasibleSection(qStart_, qGoal_))
177 {
178 if (sameComponent(vStart_, qGoal_->index))
179 {
180 hasSolution_ = true;
181 return true;
182 }
183 }
184 }
185 return false;
186}
187
189{
190 BaseT::clear();
191
192 clearVertices();
193 pis_.restart();
194
195 graphLength_ = 0;
196 bestCost_ = base::Cost(base::dInf);
197 setup_ = false;
198 vStart_ = 0;
199 shortestVertexPath_.clear();
200
201 startConfigurations_.clear();
202 goalConfigurations_.clear();
203
204 if (!isDynamic())
205 {
206 if (solutionPath_ != nullptr)
207 {
208 std::static_pointer_cast<geometric::PathGeometric>(solutionPath_)->clear();
209 }
210 }
211
212 numVerticesWhenComputingSolutionPath_ = 0;
213
214 importanceCalculator_->clear();
215 graphSampler_->clear();
216 if (pathRestriction_ != nullptr)
217 {
218 pathRestriction_->clear();
219 }
220}
221
222void BundleSpaceGraph::clearVertices()
223{
225 {
226 std::vector<Configuration *> configs;
227 nearestDatastructure_->list(configs);
228 for (auto &config : configs)
229 {
230 deleteConfiguration(config);
231 }
232 nearestDatastructure_->clear();
233 }
234 graph_.clear();
235}
236
237void BundleSpaceGraph::setGoalBias(double goalBias)
238{
239 goalBias_ = goalBias;
240}
241
242double BundleSpaceGraph::getGoalBias() const
243{
244 return goalBias_;
245}
246
247void BundleSpaceGraph::setRange(double maxDistance)
248{
249 maxDistance_ = maxDistance;
250}
251
252double BundleSpaceGraph::getRange() const
253{
254 return maxDistance_;
255}
256
257BundleSpaceGraph::Configuration::Configuration(const ompl::base::SpaceInformationPtr &si) : state(si->allocState())
258{
259}
260BundleSpaceGraph::Configuration::Configuration(const ompl::base::SpaceInformationPtr &si,
261 const ompl::base::State *state_)
262 : state(si->cloneState(state_))
263{
264}
265
266void BundleSpaceGraph::deleteConfiguration(Configuration *q)
267{
268 if (q != nullptr)
269 {
270 if (q->state != nullptr)
271 {
272 getBundle()->freeState(q->state);
273 }
274 for (unsigned int k = 0; k < q->reachableSet.size(); k++)
275 {
276 Configuration *qk = q->reachableSet.at(k);
277 if (qk->state != nullptr)
278 {
279 getBundle()->freeState(qk->state);
280 }
281 }
282 if (isDynamic())
283 {
284 const ompl::control::SpaceInformationPtr siC =
285 std::static_pointer_cast<ompl::control::SpaceInformation>(getBundle());
286 siC->freeControl(q->control);
287 }
288 q->reachableSet.clear();
289
290 delete q;
291 q = nullptr;
292 }
293}
294
296{
297 return importanceCalculator_->eval();
298}
299
301{
302 if (const base::State *state = pis_.nextStart())
303 {
304 qStart_ = new Configuration(getBundle(), state);
305 vStart_ = addConfiguration(qStart_);
306 qStart_->isStart = true;
307 }
308
309 if (qStart_ == nullptr)
310 {
311 OMPL_ERROR("%s: There are no valid initial states!", getName().c_str());
312 throw ompl::Exception("Invalid initial states.");
313 }
314
315 if (const base::State *state = pis_.nextGoal())
316 {
317 qGoal_ = new Configuration(getBundle(), state);
318 qGoal_->isGoal = true;
319 }
320
321 if (qGoal_ == nullptr && getGoalPtr()->canSample())
322 {
323 OMPL_ERROR("%s: There are no valid goal states!", getName().c_str());
324 throw ompl::Exception("Invalid goal states.");
325 }
326}
327
328void BundleSpaceGraph::uniteComponents(Vertex m1, Vertex m2)
329{
330 disjointSets_.union_set(m1, m2);
331}
332
333bool BundleSpaceGraph::sameComponent(Vertex m1, Vertex m2)
334{
335 return boost::same_component(m1, m2, disjointSets_);
336}
337
338const BundleSpaceGraph::Configuration *BundleSpaceGraph::nearest(const Configuration *q) const
339{
340 return nearestDatastructure_->nearest(const_cast<Configuration *>(q));
341}
342
349
351{
352 addEdge(a->index, b->index);
353}
354
356{
357 Vertex m = boost::add_vertex(q, graph_);
358 graph_[m]->total_connection_attempts = 1;
359 graph_[m]->successful_connection_attempts = 0;
360 disjointSets_.make_set(m);
361
362 nearestDatastructure_->add(q);
363 q->index = m;
364
365 return m;
366}
367
368unsigned int BundleSpaceGraph::getNumberOfVertices() const
369{
370 return num_vertices(graph_);
371}
372
373unsigned int BundleSpaceGraph::getNumberOfEdges() const
374{
375 return num_edges(graph_);
376}
377
379{
380 return graph_;
381}
382
387
388const BundleSpaceGraph::RoadmapNeighborsPtr &BundleSpaceGraph::getRoadmapNeighborsPtr() const
389{
391}
392
393ompl::base::Cost BundleSpaceGraph::costHeuristic(Vertex u, Vertex v) const
394{
395 return getOptimizationObjectivePtr()->motionCostHeuristic(graph_[u]->state, graph_[v]->state);
396}
397
398template <template <typename T> class NN>
399void BundleSpaceGraph::setNearestNeighbors()
400{
402 OMPL_WARN("Calling setNearestNeighbors will clear all states.");
403 clear();
404 nearestDatastructure_ = std::make_shared<NN<base::State *>>();
405 if (!isSetup())
406 {
407 setup();
408 }
409}
410
412{
413 return metric_->distanceBundle(a, b);
414}
415
417{
418 return getBundle()->checkMotion(a->state, b->state);
419}
420
422{
423 metric_->interpolateBundle(a, b, dest);
424}
425
427{
428 Configuration *next = new Configuration(getBundle(), to->state);
429
430 if (!propagator_->steer(from, to, next))
431 {
432 deleteConfiguration(next);
433 return nullptr;
434 }
435 return next;
436}
437
439{
440 double d = distance(from, to);
441 if (d > maxDistance_)
442 {
443 metric_->interpolateBundle(from, to, maxDistance_ / d, to);
444 }
445
446 if (!propagator_->steer(from, to, to))
447 {
448 return nullptr;
449 }
450 Configuration *next = new Configuration(getBundle(), to->state);
451 return next;
452}
453
455{
456 if (!isDynamic())
457 {
458 double d = distance(from, to);
459 if (d > maxDistance_)
460 {
461 metric_->interpolateBundle(from, to, maxDistance_ / d, to);
462 }
463 }
464
465 if (!propagator_->steer(from, to, to))
466 {
467 return nullptr;
468 }
469
470 Configuration *next = new Configuration(getBundle(), to->state);
471 addConfiguration(next);
472 addBundleEdge(from, next);
473 return next;
474}
475
477{
478 if (!propagator_->steer(from, to, xRandom_))
479 {
480 return false;
481 }
482
483 addBundleEdge(from, to);
484 return true;
485}
486
487void BundleSpaceGraph::setPropagator(const std::string &sPropagator)
488{
489 if (sPropagator == "geometric")
490 {
491 OMPL_DEBUG("Geometric Propagator Selected");
492 propagator_ = std::make_shared<BundleSpacePropagatorGeometric>(this);
493 }
494 else
495 {
496 OMPL_ERROR("Propagator unknown: %s", sPropagator.c_str());
497 throw ompl::Exception("Unknown Propagator");
498 }
499}
500
501void BundleSpaceGraph::setMetric(const std::string &sMetric)
502{
503 if (sMetric == "geodesic")
504 {
505 OMPL_DEBUG("Geodesic Metric Selected");
506 metric_ = std::make_shared<BundleSpaceMetricGeodesic>(this);
507 }
508 else
509 {
510 OMPL_ERROR("Metric unknown: %s", sMetric.c_str());
511 throw ompl::Exception("Unknown Metric");
512 }
513}
514
515void BundleSpaceGraph::setImportance(const std::string &sImportance)
516{
517 if (sImportance == "uniform")
518 {
519 OMPL_DEBUG("Uniform Importance Selected");
520 importanceCalculator_ = std::make_shared<BundleSpaceImportanceUniform>(this);
521 }
522 else if (sImportance == "greedy")
523 {
524 OMPL_DEBUG("Greedy Importance Selected");
525 importanceCalculator_ = std::make_shared<BundleSpaceImportanceGreedy>(this);
526 }
527 else if (sImportance == "exponential")
528 {
529 OMPL_DEBUG("Greedy Importance Selected");
530 importanceCalculator_ = std::make_shared<BundleSpaceImportanceExponential>(this);
531 }
532 else
533 {
534 OMPL_ERROR("Importance calculator unknown: %s", sImportance.c_str());
535 throw ompl::Exception("Unknown Importance");
536 }
537}
538
539void BundleSpaceGraph::setGraphSampler(const std::string &sGraphSampler)
540{
541 if (sGraphSampler == "randomvertex")
542 {
543 OMPL_DEBUG("Random Vertex Sampler Selected");
544 graphSampler_ = std::make_shared<BundleSpaceGraphSamplerRandomVertex>(this);
545 }
546 else if (sGraphSampler == "randomedge")
547 {
548 OMPL_DEBUG("Random Edge Sampler Selected");
549 graphSampler_ = std::make_shared<BundleSpaceGraphSamplerRandomEdge>(this);
550 }
551 else if (sGraphSampler == "randomdegreevertex")
552 {
553 OMPL_DEBUG("Random Degree Vertex Sampler Selected");
554 graphSampler_ = std::make_shared<BundleSpaceGraphSamplerRandomDegreeVertex>(this);
555 }
556 else
557 {
558 OMPL_ERROR("Sampler unknown: %s", sGraphSampler.c_str());
559 throw ompl::Exception("Unknown Graph Sampler");
560 }
561}
562
563BundleSpaceGraphSamplerPtr BundleSpaceGraph::getGraphSampler()
564{
565 return graphSampler_;
566}
567
568const std::pair<BundleSpaceGraph::Edge, bool> BundleSpaceGraph::addEdge(const Vertex a, const Vertex b)
569{
570 base::Cost weight = getOptimizationObjectivePtr()->motionCost(graph_[a]->state, graph_[b]->state);
571 EdgeInternalState properties(weight);
572 const std::pair<Edge, bool> e = boost::add_edge(a, b, properties, graph_);
573 uniteComponents(a, b);
574 return e;
575}
576
577BundleSpaceGraph::Vertex BundleSpaceGraph::getStartIndex() const
578{
579 return vStart_;
580}
581
583{
584 goalConfigurations_.push_back(x);
585 if (getOptimizationObjectivePtr()->isCostBetterThan(x->cost, bestCost_))
586 {
587 bestCost_ = x->cost;
588 }
589}
590
591BundleSpaceGraph::Vertex BundleSpaceGraph::getGoalIndex() const
592{
593 if (goalConfigurations_.size() > 0)
594 {
595 return goalConfigurations_.front()->index;
596 }
597 else
598 {
599 OMPL_DEVMSG1("Returned NullVertex");
600 return nullVertex();
601 }
602}
603
604BundleSpaceGraph::Vertex BundleSpaceGraph::nullVertex() const
605{
606 return BGT::null_vertex();
607}
608
610{
611 vStart_ = idx;
612}
613
614ompl::base::PathPtr &BundleSpaceGraph::getSolutionPathByReference()
615{
616 return solutionPath_;
617}
618
619bool BundleSpaceGraph::getSolution(ompl::base::PathPtr &solution)
620{
621 if (hasSolution_)
622 {
623 if ((solutionPath_ != nullptr) && (getNumberOfVertices() == numVerticesWhenComputingSolutionPath_))
624 {
625 }
626 else
627 {
628 Vertex goalVertex;
629 for (unsigned int k = 0; k < goalConfigurations_.size(); k++)
630 {
632 if (sameComponent(vStart_, qk->index))
633 {
634 solutionPath_ = getPath(vStart_, qk->index);
635 goalVertex = qk->index;
636 break;
637 }
638 }
639 if (solutionPath_ == nullptr)
640 {
641 throw "hasSolution_ is set, but no solution exists.";
642 }
643 numVerticesWhenComputingSolutionPath_ = getNumberOfVertices();
644
645 if (!isDynamic() && solutionPath_ != solution && hasParent())
646 {
647 // @NOTE: optimization seems to improve feasibility of sections
648 // in low-dim problems (up to 20 dof roughly), but will take too
649 // much time for high-dim problems. Reducing vertices seems to
650 // be the only optimization not significantly slowing everything
651 // down.
652
653 bool valid = false;
654 for (unsigned int k = 0; k < 3; k++)
655 {
656 geometric::PathGeometric &gpath = static_cast<geometric::PathGeometric &>(*solutionPath_);
657
658 valid = optimizer_->reduceVertices(gpath, 0, 0, 0.1);
659
660 if (!valid)
661 {
662 // reset solutionPath
663 solutionPath_ = getPath(vStart_, goalVertex);
664 }
665 else
666 {
667 break;
668 }
669 }
670 }
671 }
672 solution = solutionPath_;
673 return true;
674 }
675 else
676 {
677 return false;
678 }
679}
680
681ompl::base::PathPtr BundleSpaceGraph::getPath(const Vertex &start, const Vertex &goal)
682{
683 return getPath(start, goal, graph_);
684}
685
686ompl::base::PathPtr BundleSpaceGraph::getPath(const Vertex &start, const Vertex &goal, Graph &graph)
687{
688 std::vector<Vertex> prev(boost::num_vertices(graph));
689 auto weight = boost::make_transform_value_property_map(std::mem_fn(&EdgeInternalState::getCost),
690 get(boost::edge_bundle, graph));
691
692 try
693 {
694 boost::astar_search(
695 graph, start, [this, goal](const Vertex v) { return costHeuristic(v, goal); },
696 boost::predecessor_map(&prev[0])
697 .weight_map(weight)
698 .distance_compare(
699 [this](EdgeInternalState c1, EdgeInternalState c2)
700 { return getOptimizationObjectivePtr()->isCostBetterThan(c1.getCost(), c2.getCost()); })
701 .distance_combine([this](EdgeInternalState c1, EdgeInternalState c2)
702 { return getOptimizationObjectivePtr()->combineCosts(c1.getCost(), c2.getCost()); })
703 .distance_inf(getOptimizationObjectivePtr()->infiniteCost())
704 .distance_zero(getOptimizationObjectivePtr()->identityCost())
705 .visitor(BundleSpaceGraphGoalVisitor<Vertex>(goal)));
706 }
707 catch (BundleSpaceGraphFoundGoal &)
708 {
709 }
710
711 auto p(std::make_shared<geometric::PathGeometric>(getBundle()));
712 if (prev[goal] == goal)
713 {
714 return nullptr;
715 }
716
717 std::vector<Vertex> vpath;
718 for (Vertex pos = goal; prev[pos] != pos; pos = prev[pos])
719 {
720 graph[pos]->on_shortest_path = true;
721 vpath.push_back(pos);
722 p->append(graph[pos]->state);
723 }
724 graph[start]->on_shortest_path = true;
725 vpath.push_back(start);
726 p->append(graph[start]->state);
727
728 shortestVertexPath_.clear();
729 shortestVertexPath_.insert(shortestVertexPath_.begin(), vpath.rbegin(), vpath.rend());
730 p->reverse();
731
732 return p;
733}
734
735void BundleSpaceGraph::sampleBundleGoalBias(ompl::base::State *xRandom)
736{
737 if (hasSolution_)
738 {
739 // No Goal Biasing if we already found a solution on this bundle space
740 sampleBundle(xRandom);
741 }
742 else
743 {
744 double s = rng_.uniform01();
745 if (s < goalBias_ && getGoalPtr()->canSample())
746 {
747 getGoalPtr()->sampleGoal(xRandom);
748 }
749 else
750 {
751 sampleBundle(xRandom);
752 }
753 }
754}
755
756void BundleSpaceGraph::sampleFromDatastructure(ompl::base::State *xRandom)
757{
758 graphSampler_->sample(xRandom);
759}
760
761void BundleSpaceGraph::writeToGraphviz(std::string filename) const
762{
763 std::ofstream f(filename.c_str());
764 std::vector<std::string> annotationVec;
765 foreach (const Vertex v, boost::vertices(graph_))
766 {
767 Configuration *qv = graph_[v];
768 const base::State *s = qv->state;
769 std::ostringstream out;
770 getBundle()->printState(s, out);
771 annotationVec.push_back(out.str());
772 }
773 write_graphviz(f, graph_, boost::make_label_writer(&annotationVec[0]));
774}
775
776void BundleSpaceGraph::print(std::ostream &out) const
777{
778 BaseT::print(out);
779 out << std::endl
780 << " --[BundleSpaceGraph has " << getNumberOfVertices() << " vertices and " << getNumberOfEdges() << " edges.]"
781 << std::endl;
782}
783
785{
786 getBundle()->printState(q->state);
787}
788
789void BundleSpaceGraph::getPlannerDataGraph(ompl::base::PlannerData &data, const Graph &graph, const Vertex vStart) const
790{
791 if (boost::num_vertices(graph) <= 0)
792 return;
793
794 multilevel::PlannerDataVertexAnnotated pstart(graph[vStart]->state);
795 pstart.setLevel(getLevel());
796 data.addStartVertex(pstart);
797
798 for (unsigned int k = 0; k < goalConfigurations_.size(); k++)
799 {
800 Configuration *qgoal = goalConfigurations_.at(k);
801 multilevel::PlannerDataVertexAnnotated pgoal(qgoal->state);
802 pgoal.setLevel(getLevel());
803 data.addGoalVertex(pgoal);
804 }
805 if (hasSolution_)
806 {
807 if (solutionPath_ != nullptr)
808 {
809 geometric::PathGeometric &gpath = static_cast<geometric::PathGeometric &>(*solutionPath_);
810
811 std::vector<base::State *> gstates = gpath.getStates();
812
814
815 for (unsigned int k = 1; k < gstates.size(); k++)
816 {
818 p.setLevel(getLevel());
819 data.addVertex(p);
820 data.addEdge(*pLast, p);
821 pLast = &p;
822 }
823 }
824 }
825
826 foreach (const Edge e, boost::edges(graph))
827 {
828 const Vertex v1 = boost::source(e, graph);
829 const Vertex v2 = boost::target(e, graph);
830
831 multilevel::PlannerDataVertexAnnotated p1(graph[v1]->state);
832 multilevel::PlannerDataVertexAnnotated p2(graph[v2]->state);
833 p1.setLevel(getLevel());
834 p2.setLevel(getLevel());
835 data.addEdge(p1, p2);
836 }
837 foreach (const Vertex v, boost::vertices(graph))
838 {
839 multilevel::PlannerDataVertexAnnotated p(graph[v]->state);
840 p.setLevel(getLevel());
841 data.addVertex(p);
842 }
843}
844
846{
847 OMPL_DEBUG("Graph (level %d) has %d/%d vertices/edges", getLevel(), boost::num_vertices(graph_),
848 boost::num_edges(graph_));
849
850 if (bestCost_.value() < ompl::base::dInf)
851 {
852 OMPL_DEBUG("Best Cost: %.2f", bestCost_.value());
853 }
854 getPlannerDataGraph(data, graph_, vStart_);
855}
The exception type for ompl.
Definition Exception.h:47
A nearest neighbors datastructure that uses linear search. The linear search is done over sqrt(n) ele...
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
Definition Cost.h:48
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....
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
ProblemDefinitionPtr pdef_
The user set problem definition.
Definition Planner.h:404
const std::string & getName() const
Get the name of the planner.
Definition Planner.cpp:56
bool setup_
Flag indicating whether setup() has been called.
Definition Planner.h:424
Definition of an abstract state.
Definition State.h:50
Definition of a geometric path.
std::vector< base::State * > & getStates()
Get the states that make up the path (as a reference, so it can be modified, hence the function is no...
normalized_index_type index
Index of configuration in boost::graph. Usually in the interval [0,num_vertices(graph)],...
bool connect(const Configuration *from, const Configuration *to)
Try to connect configuration a to configuration b using the current metric.
BundleSpaceGraphSamplerPtr graphSampler_
Pointer to strategy to sample from graph.
bool getSolution(ompl::base::PathPtr &solution) override
Return best solution.
BundleSpaceImportancePtr importanceCalculator_
Pointer to strategy to compute importance of this bundle space (which is used to decide which bundle ...
PathRestrictionPtr pathRestriction_
Pointer to current path restriction (the set of points which project onto the best cost path on the b...
Configuration * extendGraphTowards_Range(const Configuration *from, Configuration *to)
Steer system at Configuration *from to Configuration *to while system is valid, stopping if maxDistan...
void clear() override
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
double maxDistance_
Maximum expansion step.
virtual Vertex addConfiguration(Configuration *q)
Add configuration to graph. Return its vertex in boost graph.
RoadmapNeighborsPtr nearestDatastructure_
Nearest neighbor structure for Bundle space configurations.
Configuration * qGoal_
The (best) goal configuration.
void writeToGraphviz(std::string filename) const
Write class to graphviz.
Configuration * xRandom_
Temporary random configuration.
double getImportance() const override
Importance of Bundle-space depending on number of vertices in Bundle-graph.
Configuration * steerTowards_Range(const Configuration *from, Configuration *to)
Steer system at Configuration *from to Configuration *to, stopping if maxdistance is reached.
virtual const std::pair< Edge, bool > addEdge(const Vertex a, const Vertex b)
Add edge between Vertex a and Vertex b to graph.
ompl::base::PathPtr getPath(const Vertex &start, const Vertex &goal)
Shortest path on Bundle-graph.
virtual void setStartIndex(Vertex)
Set vertex representing the start.
Configuration * steerTowards(const Configuration *from, const Configuration *to)
Steer system at Configuration *from to Configuration *to.
std::vector< Configuration * > goalConfigurations_
List of configurations that satisfy the goal condition.
base::Cost bestCost_
Best cost found so far by algorithm.
virtual void init()
Initialization methods for the first iteration (adding start configuration and doing sanity checks).
std::vector< Configuration * > startConfigurations_
List of configurations that satisfy the start condition.
virtual Vertex getStartIndex() const
Get vertex representing the start.
virtual void interpolate(const Configuration *a, const Configuration *b, Configuration *dest) const
Interpolate from configuration a to configuration b and store results in dest.
virtual Configuration * addBundleConfiguration(base::State *)
Add ompl::base::State to graph. Return its configuration.
virtual void printConfiguration(const Configuration *) const
Print configuration to std::cout.
virtual Graph & getGraphNonConst()
Get underlying boost graph representation (non const).
virtual void addBundleEdge(const Configuration *a, const Configuration *b)
Add edge between configuration a and configuration b to graph.
virtual double distance(const Configuration *a, const Configuration *b) const
Distance between two configurations using the current metric.
virtual bool checkMotion(const Configuration *a, const Configuration *b) const
Check if we can move from configuration a to configuration b using the current metric.
virtual const Graph & getGraph() const
Get underlying boost graph representation.
void addGoalConfiguration(Configuration *x)
Add configuration to graph as goal vertex.
void print(std::ostream &out) const override
Print class to ostream.
ompl::geometric::PathSimplifierPtr optimizer_
A path optimizer.
bool findSection() override
Call algorithm to solve the find section problem.
Configuration * qStart_
Start configuration.
void getPlannerData(ompl::base::PlannerData &data) const override
Return plannerdata structure, whereby each vertex is marked depending to which component it belongs (...
void setup() override
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
double graphLength_
Length of graph (useful for determing importance of Bundle-space.
boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, Configuration *, EdgeInternalState, GraphMetaData > Graph
A Bundle-graph structure using boost::adjacency_list bundles.
virtual Vertex getGoalIndex() const
Get vertex representing the goal.
A single Bundle-space.
Definition BundleSpace.h:64
virtual void clear() override
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
ProjectionPtr getProjection() const
Get ProjectionPtr from Bundle to Base.
bool hasParent() const
Return if has parent space pointer.
BundleSpacePropagatorPtr propagator_
Propagator (steering or interpolation) on bundle space. Note: currently just a stub for base::StatePr...
virtual void setup() override
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
bool hasSolution_
If there exists a solution.
BundleSpaceMetricPtr metric_
Metric on bundle space.
BundleSpace * getChild() const
Return k-1 th bundle space (locally the base space).
const ompl::base::SpaceInformationPtr & getBundle() const
Get SpaceInformationPtr for Bundle.
bool hasBaseSpace() const
Return if has base space pointer.
virtual void print(std::ostream &out) const
Internal function implementing actual printing to stream.
unsigned int getLevel() const
Level in hierarchy of Bundle-spaces.
An annotated vertex, adding information about its level in the multilevel hierarchy....
This class contains methods that automatically configure various parameters for motion planning....
Definition SelfConfig.h:59
static NearestNeighbors< _T > * getDefaultNearestNeighbors(const base::Planner *planner)
Select a default nearest neighbor datastructure for the given space.
Definition SelfConfig.h:105
void configurePlannerRange(double &range)
Compute what a good length for motion segments is.
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
Definition Console.h:64
#define OMPL_DEBUG(fmt,...)
Log a formatted debugging string.
Definition Console.h:70
#define OMPL_WARN(fmt,...)
Log a formatted warning string.
Definition Console.h:66
@ GOAL_SAMPLEABLE_REGION
This bit is set if casting to sampleable goal regions (ompl::base::GoalSampleableRegion) is possible.
Definition GoalTypes.h:56
This namespace contains datastructures and planners to exploit multilevel abstractions,...