Loading...
Searching...
No Matches
Syclop.h
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2011, Rice University
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Rice University nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Matt Maly */
36
37#ifndef OMPL_CONTROL_PLANNERS_SYCLOP_SYCLOP_
38#define OMPL_CONTROL_PLANNERS_SYCLOP_SYCLOP_
39
40#include <boost/graph/astar_search.hpp>
41#include <boost/graph/graph_traits.hpp>
42#include <boost/graph/adjacency_list.hpp>
43#include <unordered_map>
44#include "ompl/control/planners/PlannerIncludes.h"
45#include "ompl/control/planners/syclop/Decomposition.h"
46#include "ompl/control/planners/syclop/GridDecomposition.h"
47#include "ompl/datastructures/PDF.h"
48#include "ompl/util/Hash.h"
49#include <functional>
50#include <map>
51#include <utility>
52#include <vector>
53
54namespace ompl
55{
56 namespace control
57 {
71
73 class Syclop : public base::Planner
74 {
75 public:
96 using EdgeCostFactorFn = std::function<double(int, int)>;
97
100 using LeadComputeFn = std::function<void(int, int, std::vector<int> &)>;
101
103 Syclop(const SpaceInformationPtr &si, DecompositionPtr d, const std::string &plannerName)
104 : ompl::base::Planner(si, plannerName)
105 , siC_(si.get())
106 , decomp_(std::move(d))
107 , covGrid_(Defaults::COVGRID_LENGTH, decomp_)
108 {
109 specs_.approximateSolutions = true;
110
111 Planner::declareParam<int>("free_volume_samples", this, &Syclop::setNumFreeVolumeSamples,
112 &Syclop::getNumFreeVolumeSamples, "10000:10000:500000");
113 Planner::declareParam<int>("num_region_expansions", this, &Syclop::setNumRegionExpansions,
114 &Syclop::getNumRegionExpansions, "10:10:500");
115 Planner::declareParam<int>("num_tree_expansions", this, &Syclop::setNumTreeExpansions,
116 &Syclop::getNumTreeExpansions, "0:1:100");
117 Planner::declareParam<double>("prob_abandon_lead_early", this, &Syclop::setProbAbandonLeadEarly,
118 &Syclop::getProbAbandonLeadEarly, "0.:.05:1.");
119 Planner::declareParam<double>("prob_add_available_regions", this,
122 Planner::declareParam<double>("prob_shortest_path_lead", this, &Syclop::setProbShortestPathLead,
123 &Syclop::getProbShortestPathLead, "0.:.05:1.");
124 }
125
126 ~Syclop() override = default;
127
130
131 void setup() override;
132
133 void clear() override;
134
139
142
144 void setLeadComputeFn(const LeadComputeFn &compute);
145
147 void addEdgeCostFactor(const EdgeCostFactorFn &factor);
148
151
154 {
155 return numFreeVolSamples_;
156 }
157
160 void setNumFreeVolumeSamples(int numSamples)
161 {
162 numFreeVolSamples_ = numSamples;
163 }
164
168 {
169 return probShortestPath_;
170 }
171
174 void setProbShortestPathLead(double probability)
175 {
176 probShortestPath_ = probability;
177 }
178
182 {
184 }
185
188 void setProbAddingToAvailableRegions(double probability)
189 {
190 probKeepAddingToAvail_ = probability;
191 }
192
196 {
198 }
199
202 void setNumRegionExpansions(int regionExpansions)
203 {
204 numRegionExpansions_ = regionExpansions;
205 }
206
210 {
211 return numTreeSelections_;
212 }
213
216 void setNumTreeExpansions(int treeExpansions)
217 {
218 numTreeSelections_ = treeExpansions;
219 }
220
224 {
226 }
227
230 void setProbAbandonLeadEarly(double probability)
231 {
232 probAbandonLeadEarly_ = probability;
233 }
234
235
237 struct Defaults
238 {
239 static const int NUM_FREEVOL_SAMPLES = 100000;
240 static const int COVGRID_LENGTH = 128;
241 static const int NUM_REGION_EXPANSIONS = 100;
242 static const int NUM_TREE_SELECTIONS = 1;
243 // C++ standard prohibits non-integral static const member initialization
244 // These constants are set in Syclop.cpp. C++11 standard changes this
245 // with the constexpr keyword, but for compatibility this is not done.
246 static const double PROB_ABANDON_LEAD_EARLY /*= 0.25*/;
247 static const double PROB_KEEP_ADDING_TO_AVAIL /*= 0.50*/;
248 static const double PROB_SHORTEST_PATH /*= 0.95*/;
249 };
250
251 protected:
256 class Motion
257 {
258 public:
259 Motion() = default;
260
262 Motion(const SpaceInformation *si) : state(si->allocState()), control(si->allocControl())
263 {
264 }
265 virtual ~Motion() = default;
269 Control *control{nullptr};
271 const Motion *parent{nullptr};
273 unsigned int steps{0};
274 };
275
277 class Region
278 {
279 public:
280 Region() = default;
281 virtual ~Region() = default;
282
283 Region(const Region &) = default;
284 Region &operator=(const Region &) = default;
285 Region(Region &&) = default;
286 Region &operator=(Region &&) = default;
287
289 void clear()
290 {
291 motions.clear();
292 covGridCells.clear();
293 pdfElem = nullptr;
294 }
295
297 std::set<int> covGridCells;
299 std::vector<Motion *> motions;
301 double volume;
307 double weight;
309 double alpha;
311 int index;
313 unsigned int numSelections;
316 };
317
320 class Adjacency
321 {
322 public:
323 Adjacency() = default;
324 virtual ~Adjacency() = default;
326 void clear()
327 {
328 covGridCells.clear();
329 }
330
332 std::set<int> covGridCells = {};
334 const Region *source = {nullptr};
336 const Region *target = {nullptr};
338 double cost = {0.};
343 int numSelections = {0};
346 bool empty = {false};
347 };
348
350 virtual Motion *addRoot(const base::State *s) = 0;
351
354 virtual void selectAndExtend(Region &region, std::vector<Motion *> &newMotions) = 0;
355
357 inline const Region &getRegionFromIndex(const int rid) const
358 {
359 return graph_[boost::vertex(rid, graph_)];
360 }
361
363 int numFreeVolSamples_{Defaults::NUM_FREEVOL_SAMPLES};
364
366 double probShortestPath_{Defaults::PROB_SHORTEST_PATH};
367
369 double probKeepAddingToAvail_{Defaults::PROB_KEEP_ADDING_TO_AVAIL};
370
372 int numRegionExpansions_{Defaults::NUM_REGION_EXPANSIONS};
373
376 int numTreeSelections_{Defaults::NUM_TREE_SELECTIONS};
377
380 double probAbandonLeadEarly_{Defaults::PROB_ABANDON_LEAD_EARLY};
381
384
387
390
391 private:
393
394 struct HashRegionPair
395 {
396 size_t operator()(const std::pair<int, int> &p) const
397 {
398 std::size_t hash = std::hash<int>()(p.first);
399 hash_combine(hash, p.second);
400 return hash;
401 }
402 };
404
407 class CoverageGrid : public GridDecomposition
408 {
409 public:
410 CoverageGrid(const int len, const DecompositionPtr &d)
411 : GridDecomposition(len, d->getDimension(), d->getBounds()), decomp(d)
412 {
413 }
414
415 ~CoverageGrid() override = default;
416
419 void project(const base::State *s, std::vector<double> &coord) const override
420 {
421 decomp->project(s, coord);
422 }
423
425 void sampleFullState(const base::StateSamplerPtr & /*sampler*/, const std::vector<double> & /*coord*/,
426 base::State * /*s*/) const override
427 {
428 }
429
430 protected:
431 const DecompositionPtr &decomp;
432 };
433
434 using RegionGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Region, Adjacency>;
435 using Vertex = boost::graph_traits<RegionGraph>::vertex_descriptor;
436 using VertexIter = boost::graph_traits<RegionGraph>::vertex_iterator;
437 using VertexIndexMap = boost::property_map<RegionGraph, boost::vertex_index_t>::type;
438 using EdgeIter = boost::graph_traits<RegionGraph>::edge_iterator;
439
441 friend class DecompositionHeuristic;
442
443 class DecompositionHeuristic : public boost::astar_heuristic<RegionGraph, double>
444 {
445 public:
446 DecompositionHeuristic(const Syclop *s, const Region &goal) : syclop(s), goalRegion(goal)
447 {
448 }
449
450 double operator()(Vertex v)
451 {
452 const Region &region = syclop->getRegionFromIndex(v);
453 return region.alpha * goalRegion.alpha;
454 }
455
456 private:
457 const Syclop *syclop;
458 const Region &goalRegion;
459 };
460
461 struct found_goal
462 {
463 };
464
465 class GoalVisitor : public boost::default_astar_visitor
466 {
467 public:
468 GoalVisitor(const int goal) : goalRegion(goal)
469 {
470 }
471 void examine_vertex(Vertex v, const RegionGraph & /*g*/)
472 {
473 if (static_cast<int>(v) == goalRegion)
474 throw found_goal();
475 }
476
477 private:
478 const int goalRegion;
479 };
481
483 class RegionSet
484 {
485 public:
486 int sampleUniform()
487 {
488 if (empty())
489 return -1;
490 return regions.sample(rng.uniform01());
491 }
492 void insert(const int r)
493 {
494 if (regToElem.count(r) == 0)
495 regToElem[r] = regions.add(r, 1);
496 else
497 {
498 PDF<int>::Element *elem = regToElem[r];
499 regions.update(elem, regions.getWeight(elem) + 1);
500 }
501 }
502 void clear()
503 {
504 regions.clear();
505 regToElem.clear();
506 }
507 std::size_t size() const
508 {
509 return regions.size();
510 }
511 bool empty() const
512 {
513 return regions.empty();
514 }
515
516 private:
517 RNG rng;
518 PDF<int> regions;
519 std::unordered_map<int, PDF<int>::Element *> regToElem;
520 };
522
524 void initRegion(Region &r);
525
527 void setupRegionEstimates();
528
530 void updateRegion(Region &r);
531
533 void initEdge(Adjacency &adj, const Region *source, const Region *target);
534
536 void setupEdgeEstimates();
537
539 void updateEdge(Adjacency &a);
540
543 bool updateCoverageEstimate(Region &r, const base::State *s);
544
547 bool updateConnectionEstimate(const Region &c, const Region &d, const base::State *s);
548
551 void buildGraph();
552
554 void clearGraphDetails();
555
557 int selectRegion();
558
560 void computeAvailableRegions();
561
564 void defaultComputeLead(int startRegion, int goalRegion, std::vector<int> &lead);
565
567 double defaultEdgeCost(int r, int s);
568
570 LeadComputeFn leadComputeFn;
572 std::vector<int> lead_;
574 PDF<int> availDist_;
576 std::vector<EdgeCostFactorFn> edgeCostFactors_;
578 CoverageGrid covGrid_;
581 RegionGraph graph_;
583 bool graphReady_{false};
585 std::unordered_map<std::pair<int, int>, Adjacency *, HashRegionPair> regionsToEdge_;
587 unsigned int numMotions_{0};
589 RegionSet startRegions_;
591 RegionSet goalRegions_;
592 };
593 } // namespace control
594} // namespace ompl
595
596#endif
A class that will hold data contained in the PDF.
Definition PDF.h:53
Random number generation. An instance of this class cannot be used by multiple threads at once (membe...
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
Base class for a planner.
Definition Planner.h:216
PlannerSpecs specs_
The specifications of the planner (its capabilities).
Definition Planner.h:413
A shared pointer wrapper for ompl::base::SpaceInformation.
Definition of an abstract state.
Definition State.h:50
Definition of an abstract control.
Definition Control.h:48
A shared pointer wrapper for ompl::control::Decomposition.
virtual int getDimension() const
Returns the dimension of this Decomposition.
virtual const base::RealVectorBounds & getBounds() const
Returns the bounds of this Decomposition.
A GridDecomposition is a Decomposition implemented using a grid.
Space information containing necessary information for planning with controls. setup() needs to be ca...
Representation of an adjacency (a directed edge) between two regions in the Decomposition assigned to...
Definition Syclop.h:321
std::set< int > covGridCells
The cells of the underlying coverage grid that contain tree motions originating from direct connectio...
Definition Syclop.h:332
const Region * target
The target region of this adjacency edge.
Definition Syclop.h:336
bool empty
This value is true if and only if this adjacency's source and target regions both contain zero tree m...
Definition Syclop.h:346
int numLeadInclusions
The number of times this adjacency has been included in a lead.
Definition Syclop.h:340
double cost
The cost of this adjacency edge, used in lead computations.
Definition Syclop.h:338
const Region * source
The source region of this adjacency edge.
Definition Syclop.h:334
int numSelections
The number of times the low-level tree planner has selected motions from the source region when attem...
Definition Syclop.h:343
void clear()
Clears coverage information from this adjacency.
Definition Syclop.h:326
Representation of a motion.
Definition Syclop.h:257
unsigned int steps
The number of steps for which the control is applied.
Definition Syclop.h:273
Motion(const SpaceInformation *si)
Constructor that allocates memory for the state and the control.
Definition Syclop.h:262
const Motion * parent
The parent motion in the tree.
Definition Syclop.h:271
base::State * state
The state contained by the motion.
Definition Syclop.h:267
Representation of a region in the Decomposition assigned to Syclop.
Definition Syclop.h:278
double volume
The volume of this region.
Definition Syclop.h:301
double percentValidCells
The percent of free volume of this region.
Definition Syclop.h:305
void clear()
Clears motions and coverage information from this region.
Definition Syclop.h:289
std::vector< Motion * > motions
The tree motions contained in this region.
Definition Syclop.h:299
std::set< int > covGridCells
The cells of the underlying coverage grid that contain tree motions from this region.
Definition Syclop.h:297
PDF< int >::Element * pdfElem
The Element corresponding to this region in the PDF of available regions.
Definition Syclop.h:315
double alpha
The coefficient contributed by this region to edge weights in lead computations.
Definition Syclop.h:309
double weight
The probabilistic weight of this region, used when sampling from PDF.
Definition Syclop.h:307
unsigned int numSelections
The number of times this region has been selected for expansion.
Definition Syclop.h:313
double freeVolume
The free volume of this region.
Definition Syclop.h:303
int index
The index of the graph node corresponding to this region.
Definition Syclop.h:311
Synergistic Combination of Layers of Planning.
Definition Syclop.h:74
const Region & getRegionFromIndex(const int rid) const
Returns a reference to the Region object with the given index. Assumes the index is valid.
Definition Syclop.h:357
void setup() override
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition Syclop.cpp:48
double getProbAbandonLeadEarly() const
Get the probability [0,1] that a lead will be abandoned early, before a new region is chosen for expa...
Definition Syclop.h:223
void setNumTreeExpansions(int treeExpansions)
Set the number of calls to selectAndExtend() in the low-level tree planner for a given lead and regio...
Definition Syclop.h:216
void setNumFreeVolumeSamples(int numSamples)
Set the number of states to sample when estimating free volume in the Decomposition.
Definition Syclop.h:160
const SpaceInformation * siC_
Handle to the control::SpaceInformation object.
Definition Syclop.h:383
void setProbShortestPathLead(double probability)
Set the probability [0,1] that a lead will be computed as a shortest-path instead of a random-DFS.
Definition Syclop.h:174
std::function< double(int, int)> EdgeCostFactorFn
Each edge weight between two adjacent regions in the Decomposition is defined as a product of edge co...
Definition Syclop.h:96
void clear() override
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
Definition Syclop.cpp:58
double probKeepAddingToAvail_
The probability that the set of available regions will be augmented.
Definition Syclop.h:369
double probShortestPath_
The probability that a lead will be computed as a shortest-path instead of a random-DFS.
Definition Syclop.h:366
virtual void selectAndExtend(Region &region, std::vector< Motion * > &newMotions)=0
Select a Motion from the given Region, and extend the tree from the Motion. Add any new motions creat...
void clearEdgeCostFactors()
Clears all edge cost factors, making all edge weights equivalent to 1.
Definition Syclop.cpp:222
Syclop(const SpaceInformationPtr &si, DecompositionPtr d, const std::string &plannerName)
Constructor. Requires a Decomposition, which Syclop uses to create high-level leads.
Definition Syclop.h:103
void addEdgeCostFactor(const EdgeCostFactorFn &factor)
Adds an edge cost factor to be used for edge weights between adjacent regions.
Definition Syclop.cpp:217
int numTreeSelections_
The number of calls to selectAndExtend() in the low-level tree planner for a given lead and region.
Definition Syclop.h:376
double getProbAddingToAvailableRegions() const
Get the probability [0,1] that the set of available regions will be augmented.
Definition Syclop.h:181
virtual Motion * addRoot(const base::State *s)=0
Add State s as a new root in the low-level tree, and return the Motion corresponding to s.
double probAbandonLeadEarly_
The probability that a lead will be abandoned early, before a new region is chosen for expansion.
Definition Syclop.h:380
int getNumFreeVolumeSamples() const
Get the number of states to sample when estimating free volume in the Decomposition.
Definition Syclop.h:153
void setProbAddingToAvailableRegions(double probability)
Set the probability [0,1] that the set of available regions will be augmented.
Definition Syclop.h:188
double getProbShortestPathLead() const
Get the probability [0,1] that a lead will be computed as a shortest-path instead of a random-DFS.
Definition Syclop.h:167
void setNumRegionExpansions(int regionExpansions)
Set the number of times a new region will be chosen and promoted for expansion from a given lead.
Definition Syclop.h:202
int numRegionExpansions_
The number of times a new region will be chosen and promoted for expansion from a given lead.
Definition Syclop.h:372
RNG rng_
Random number generator.
Definition Syclop.h:389
int getNumTreeExpansions() const
Get the number of calls to selectAndExtend() in the low-level tree planner for a given lead and regio...
Definition Syclop.h:209
std::function< void(int, int, std::vector< int > &)> LeadComputeFn
Leads should consist of a path of adjacent regions in the decomposition that start with the start reg...
Definition Syclop.h:100
void setProbAbandonLeadEarly(double probability)
The probability that a lead will be abandoned early, before a new region is chosen for expansion.
Definition Syclop.h:230
void setLeadComputeFn(const LeadComputeFn &compute)
Allows the user to override the lead computation function.
Definition Syclop.cpp:212
int numFreeVolSamples_
The number of states to sample to estimate free volume in the Decomposition.
Definition Syclop.h:363
DecompositionPtr decomp_
The high level decomposition used to focus tree expansion.
Definition Syclop.h:386
base::PlannerStatus solve(const base::PlannerTerminationCondition &ptc) override
Continues solving until a solution is found or a given planner termination condition is met....
Definition Syclop.cpp:69
int getNumRegionExpansions() const
Get the number of times a new region will be chosen and promoted for expansion from a given lead.
Definition Syclop.h:195
This namespace contains sampling based planning routines shared by both planning under geometric cons...
This namespace contains sampling based planning routines used by planning under differential constrai...
Definition Control.h:45
Main namespace. Contains everything in this library.
STL namespace.
A class to store the exit status of Planner::solve().
Contains default values for Syclop parameters.
Definition Syclop.h:238