Loading...
Searching...
No Matches
XXL.h
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2015, 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: Ryan Luna */
36
37#ifndef OMPL_GEOMETRIC_PLANNERS_XXL_XXL_
38#define OMPL_GEOMETRIC_PLANNERS_XXL_XXL_
39
40#include <thread>
41#include <unordered_map>
42#include "ompl/util/Hash.h"
43#include "ompl/datastructures/AdjacencyList.h"
44#include "ompl/geometric/planners/PlannerIncludes.h"
45#include "ompl/geometric/planners/xxl/XXLDecomposition.h"
46
47namespace ompl
48{
49 namespace geometric
50 {
71 class XXL : public base::Planner
72 {
73 public:
74 // Standard planner constructor. Must call setDecomposition before calling solve()
75 XXL(const base::SpaceInformationPtr &si);
76
77 // Initialize HiLo with the given decomposition
78 XXL(const base::SpaceInformationPtr &si, const XXLDecompositionPtr &decomp);
79
80 virtual ~XXL();
81
82 virtual void getPlannerData(base::PlannerData &data) const;
83
85
86 virtual void clear();
87
88 virtual void setup();
89
90 void setDecomposition(const XXLDecompositionPtr &decomp);
91
92 double getRandWalkRate() const
93 {
94 return rand_walk_rate_;
95 }
96 void setRandWalkRate(double rate)
97 {
98 if (rate < 0.0 || rate > 1.0)
99 throw;
100 rand_walk_rate_ = rate;
101 }
102
103 protected:
104 // Quickly insert, check membership, and grab a unique integer from a range [0, max)
105 class PerfectSet
106 {
107 public:
108 PerfectSet(std::size_t max)
109 {
110 exists.assign(max, false);
111 elements.reserve(max / 10); // reserve, but do not "allocate" the space
112 }
113
114 std::size_t numElements() const
115 {
116 return elements.size();
117 }
118
119 bool isElement(unsigned int val) const
120 {
121 if (val >= (unsigned int)exists.size())
122 return false;
123 return exists[val];
124 }
125
126 bool addElement(unsigned int val)
127 {
128 if (val >= (unsigned int)exists.size() || exists[val])
129 return false;
130
131 elements.push_back(val);
132 exists[val] = true;
133 return true;
134 }
135
136 int getElement(std::size_t idx) const
137 {
138 return elements[idx];
139 }
140
141 protected:
142 std::vector<bool> exists;
143 std::vector<unsigned int> elements;
144 };
145
146 struct Motion
147 {
148 base::State *state;
149 std::vector<int> levels;
150 int index;
151 };
152
153 struct Region
154 {
155 std::vector<int> allMotions;
156 std::vector<int> motionsInTree; // subset of allMotions that are connected to the tree
157 };
158
159 class Layer
160 {
161 public:
162 Layer(int _id, int numRegions, int lvl, Layer *_parent)
163 : regions(numRegions)
164 , weights(numRegions, 0.5)
165 , exterior(numRegions, true)
166 , connections(numRegions, 0)
167 , selections(numRegions, 0)
168 , leads(numRegions, 0)
169 , goalStates(numRegions, std::vector<int>())
170 , connectionPoints(numRegions)
171 , regionGraph(new AdjacencyList(numRegions))
172 , level(lvl)
173 , id(_id)
174 , parent(_parent)
175 {
176 }
177
178 ~Layer()
179 {
180 delete regionGraph;
181 for (auto &sublayer : sublayers)
182 delete sublayer;
183 }
184
185 size_t numRegions() const
186 {
187 return regions.size();
188 }
189
190 int getLevel() const
191 {
192 return level;
193 }
194
195 Layer *getParent() const
196 {
197 return parent;
198 }
199
200 int getID() const
201 {
202 return id;
203 }
204
205 Region &getRegion(int r)
206 {
207 if (r < 0 || r >= (int)regions.size())
208 {
209 OMPL_ERROR("Requested region %d, but there are only %lu regions", r, regions.size());
210 throw ompl::Exception("Region out of bounds");
211 }
212
213 return regions[r];
214 }
215
216 const Region &getRegion(int r) const
217 {
218 if (r < 0 || r >= (int)regions.size())
219 {
220 OMPL_ERROR("Requested region %d, but there are only %lu regions", r, regions.size());
221 throw ompl::Exception("Region out of bounds");
222 }
223
224 return regions[r];
225 }
226
227 const std::vector<double> &getWeights() const
228 {
229 return weights;
230 }
231
232 std::vector<double> &getWeights()
233 {
234 return weights;
235 }
236
237 const std::vector<bool> &getExterior() const
238 {
239 return exterior;
240 }
241
242 std::vector<bool> &getExterior()
243 {
244 return exterior;
245 }
246
247 const std::vector<int> &getConnections() const
248 {
249 return connections;
250 }
251
252 const std::vector<int> &getSelections() const
253 {
254 return selections;
255 }
256
257 const std::vector<std::vector<int>> &getGoalStates() const
258 {
259 return goalStates;
260 }
261
262 const std::vector<int> &getGoalStates(int reg) const
263 {
264 return goalStates[reg];
265 }
266
267 size_t numGoalStates() const
268 {
269 return totalGoalStates;
270 }
271
272 size_t numGoalStates(int reg) const
273 {
274 return goalStates[reg].size();
275 }
276
277 void addGoalState(int reg, int id)
278 {
279 goalStates[reg].push_back(id);
280 totalGoalStates++;
281 }
282
283 AdjacencyList &getRegionGraph()
284 {
285 return *regionGraph;
286 }
287
288 const AdjacencyList &getRegionGraph() const
289 {
290 return *regionGraph;
291 }
292
293 Layer *getSublayer(int l)
294 {
295 return sublayers[l];
296 }
297
298 const Layer *getSublayer(int l) const
299 {
300 return sublayers[l];
301 }
302
303 void allocateSublayers()
304 {
305 if (sublayers.size())
306 throw;
307
308 for (size_t i = 0; i < regions.size(); ++i)
309 sublayers.push_back(new Layer(i, regions.size(), level + 1, this));
310 }
311
312 bool hasSublayers()
313 {
314 return !sublayers.empty();
315 }
316
317 void selectRegion(int r, int count = 1)
318 {
319 // numSelections++;
320 // selections[r]++;
321 numSelections += count;
322 selections[r] += count;
323 }
324
325 void connectRegion(int r)
326 {
327 numConnections++;
328 connections[r]++;
329 connectionPoints.addElement(r);
330 }
331
332 int totalSelections() const
333 {
334 return numSelections;
335 }
336
337 int totalConnections() const
338 {
339 return numConnections;
340 }
341
342 int connectibleRegions() const
343 {
344 return connectionPoints.numElements();
345 }
346
347 int connectibleRegion(int idx) const
348 {
349 return connectionPoints.getElement(idx);
350 }
351
352 int leadAppearances(int idx) const
353 {
354 return leads[idx];
355 }
356
357 int numLeads() const
358 {
359 return numTotalLeads;
360 }
361
362 void markLead(const std::vector<int> &lead)
363 {
364 numTotalLeads++;
365 for (size_t i = 0; i < lead.size(); ++i)
366 leads[lead[i]]++;
367 }
368
369 protected:
370 std::vector<Region> regions; // The list of regions in this layer
371 std::vector<double> weights; // Weight for each region
372 std::vector<bool> exterior; // Exterior status for the regions in this layer
373 std::vector<int> connections; // Number of times the search has tried internal connections in this
374 // region
375 std::vector<int> selections; // Number of times the search has selected this region for expansion
376 std::vector<int> leads; // Number of times each region has appeared in a lead
377 std::vector<std::vector<int>> goalStates; // A list of goal states in each region
378 PerfectSet connectionPoints; // The set of regions we have tried to do internal connections on
379
380 AdjacencyList *regionGraph; // The connectivity of regions in this layer
381 std::vector<Layer *> sublayers; // The layers descending from this layer
382 int level; // The level of this layer in the hierarchy (0 is top)
383 int numSelections{0}; // The total number of selections in this layer
384 int numConnections{0}; // The total number of internal connection attempts in this layer
385 int id;
386 int totalGoalStates{0}; // The total number of goal states in this layer
387 int numTotalLeads{0};
388 Layer *parent;
389 };
390
391 void freeMemory();
392 void allocateLayers(Layer *layer);
393
394 void updateRegionConnectivity(const Motion *m1, const Motion *m2, int layer);
395 Layer *getLayer(const std::vector<int> &regions, int layer);
396
397 int addState(const base::State *state);
398 int addThisState(base::State *state); // add state using this state memory, no copy
399 int addGoalState(const base::State *state);
400 int addStartState(const base::State *state);
401
402 // Update the various statistics for the regions and their subregions in the vector
403 void updateRegionProperties(const std::vector<int> &regions);
404 // Update the various statistics for the region specified
405 void updateRegionProperties(Layer *layer, int region);
406
407 // Sample states uniformly at random in the given layer until ptc is triggered
408 void sampleStates(Layer *layer, const ompl::base::PlannerTerminationCondition &ptc);
409 bool sampleAlongLead(Layer *layer, const std::vector<int> &lead,
411
412 int steerToRegion(Layer *layer, int from, int to);
413 int expandToRegion(Layer *layer, int from, int to, bool useExisting = false);
414
415 bool feasibleLead(Layer *layer, const std::vector<int> &lead,
417 bool connectLead(Layer *layer, const std::vector<int> &lead, std::vector<int> &candidateRegions,
419 void connectRegion(Layer *layer, int region, const base::PlannerTerminationCondition &ptc);
420 void connectRegions(Layer *layer, int r1, int r2, const base::PlannerTerminationCondition &ptc,
421 bool all = false);
422
423 // Compute a new lead in the given decomposition layer from start to goal
424 void computeLead(Layer *layer, std::vector<int> &lead);
425
426 // Search for a solution path in the given layer
428
429 // Return a list of neighbors and the edge weights from rid
430 void getNeighbors(int rid, const std::vector<double> &weights,
431 std::vector<std::pair<int, double>> &neighbors) const;
432
433 // Shortest (weight) path from r1 to r2
434 bool shortestPath(int r1, int r2, std::vector<int> &path, const std::vector<double> &weights);
435
436 // Compute a path from r1 to r2 via a random walk
437 bool randomWalk(int r1, int r2, std::vector<int> &path);
438
439 void getGoalStates();
440 // Thread that gets us goal states
441 void getGoalStates(const base::PlannerTerminationCondition &ptc);
442
443 bool constructSolutionPath();
444
445 bool isStartState(int idx) const;
446 bool isGoalState(int idx) const;
447
448 void writeDebugOutput() const;
449
450 // Root layer of the decomposition data
451 Layer *topLayer_{nullptr};
452
453 // Raw storage for all motions explored during search
454 std::vector<Motion *> motions_;
455 // Indexes into motions_ for start states
456 std::vector<int> startMotions_;
457 // Index into motions_ for goal states
458 std::vector<int> goalMotions_;
459 // The number of goal states in each decomposition cell
460 std::unordered_map<std::vector<int>, int> goalCount_;
461
462 base::State *xstate_;
463
464 // The number of states in realGraph that have verified edges in the graph
465 unsigned int statesConnectedInRealGraph_;
466
467 unsigned int maxGoalStatesPerRegion_;
468 unsigned int maxGoalStates_;
469
470 // Random number generator
471 RNG rng_;
472
473 base::StateSamplerPtr sampler_;
474
475 // A decomposition of the search space
476 XXLDecompositionPtr decomposition_;
477
478 // A lazily constructed graph where edges between states have not been collision checked
479 AdjacencyList lazyGraph_;
480 // The verified graph where all edges have been collision checked. An edge in this graph
481 // should not exist in lazyGraph
482 AdjacencyList realGraph_;
483
484 // Variable for the goal state sampling thread
485 bool kill_{false};
486
487 // Scratch space for shortest path computation
488 std::vector<int> predecessors_;
489 std::vector<bool> closedList_;
490
491 double rand_walk_rate_{-1.0};
492 };
493 } // namespace geometric
494} // namespace ompl
495
496#endif
The exception type for ompl.
Definition Exception.h:47
Random number generation. An instance of this class cannot be used by multiple threads at once (membe...
Object containing planner generated vertex and edge data. It is assumed that all vertices are unique,...
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
Base class for a planner.
Definition Planner.h:216
Definition of an abstract state.
Definition State.h:50
A shared pointer wrapper for ompl::geometric::XXLDecomposition.
virtual void setup()
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition XXL.cpp:109
bool searchForPath(Layer *layer, const ompl::base::PlannerTerminationCondition &ptc)
Definition XXL.cpp:1288
virtual void getPlannerData(base::PlannerData &data) const
Get information about the current run of the motion planner. Repeated calls to this function will upd...
Definition XXL.cpp:1464
virtual void clear()
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
Definition XXL.cpp:65
virtual base::PlannerStatus solve(const base::PlannerTerminationCondition &ptc)
Function that can solve the motion planning problem. This function can be called multiple times on th...
Definition XXL.cpp:1339
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
Definition Console.h:64
This namespace contains code that is specific to planning under geometric constraints.
Main namespace. Contains everything in this library.
A class to store the exit status of Planner::solve().