77#include < functional>
88#include < stdexcept>
99#include < stdlib.h>
10-
10+ # include < iostream >
1111
1212namespace RRT
1313{
1414 /* *
15- * Base class for an rrt tree node
15+ * Base class for an RRT tree node.
1616 *
1717 * @param T The datatype representing the state in the space the RRT
1818 * will be searching.
@@ -23,7 +23,7 @@ namespace RRT
2323 Node (const T &state, Node<T> *parent = nullptr ) {
2424 _parent = parent;
2525 _state = state;
26-
26+
2727 if (_parent) {
2828 _parent->_children .push_back (this );
2929 }
@@ -72,6 +72,11 @@ namespace RRT
7272 * placed in callbacks (C++ lambdas), which must be supplied by the
7373 * user of this class.
7474 *
75+ * If adaptive stepsize control (ASC) is enabled, then the stepsize for extending new nodes from
76+ * the tree will be dynamically updated depending on how close the nearest obstacle is. If there are
77+ * no nearby obstacles, then the stepsize will be extended in order to safely cover more ground. If
78+ * there are nearby obstacles, then the stepsize will shrink so that the RRT can take more precise steps.
79+ *
7580 * USAGE:
7681 * 1) Create a new Tree with the appropriate StateSpace
7782 * RRT::Tree<My2dPoint> tree(stateSpace);
@@ -80,7 +85,10 @@ namespace RRT
8085 * tree->setStartState(s);
8186 * tree->setGoalState(g);
8287 *
83- * 3) Run the RRT algorithm! This can be done in one of two ways:
88+ * 3) (Optional) If adaptive stepsize control is enabled:
89+ * _stateSpace->setMaxStepSize sets the maximum stepsize the tree can take for any step.
90+ *
91+ * 4) Run the RRT algorithm! This can be done in one of two ways:
8492 * Option 1) Call the run() method - it will grow the tree
8593 * until it finds a solution or runs out of iterations.
8694 *
@@ -89,7 +97,7 @@ namespace RRT
8997 * Either way works fine, just choose whatever works best for your
9098 * application.
9199 *
92- * 4 ) Use getPath() to get the series of states that make up the solution
100+ * 5 ) Use getPath() to get the series of states that make up the solution
93101 *
94102 * @param T The type that represents a state within the state-space that
95103 * the tree is searching. This could be a 2D Point or something else,
@@ -103,7 +111,9 @@ namespace RRT
103111
104112 // default values
105113 setStepSize (0.1 );
114+ setMaxStepSize (5 );
106115 setMaxIterations (1000 );
116+ setASCEnabled (false );
107117 setGoalBias (0 );
108118 setWaypointBias (0 );
109119 setGoalMaxDist (0.1 );
@@ -134,6 +144,16 @@ namespace RRT
134144 }
135145
136146
147+ /* *
148+ * Whether or not the tree is to run with adaptive stepsize control.
149+ */
150+ bool isASCEnabled () const {
151+ return _isASCEnabled;
152+ }
153+ void setASCEnabled (bool checked) {
154+ _isASCEnabled = checked;
155+ }
156+
137157 /* *
138158 * @brief The chance we extend towards the goal rather than a random point.
139159 * @details At each iteration of the RRT algorithm, we extend() towards a particular state. The goalBias
@@ -187,6 +207,14 @@ namespace RRT
187207 _stepSize = stepSize;
188208 }
189209
210+ // / Max step size used in ASC
211+ float maxStepSize () const {
212+ return _maxStepSize;
213+ }
214+ void setMaxStepSize (float maxStep) {
215+ _maxStepSize = maxStep;
216+ }
217+
190218
191219 /* *
192220 * @brief How close we have to get to the goal in order to consider it reached.
@@ -279,22 +307,33 @@ namespace RRT
279307 * Grow the tree in the direction of @state
280308 *
281309 * @return the new tree Node (may be nullptr if we hit Obstacles)
310+ * @param target The point to extend the tree to
282311 * @param source The Node to connect from. If source == nullptr, then
283312 * the closest tree point is used
284313 */
285314 virtual Node<T> *extend (const T &target, Node<T> *source = nullptr ) {
286315 // if we weren't given a source point, try to find a close node
287316 if (!source) {
288- source = nearest (target);
317+ source = nearest (target, nullptr );
289318 if (!source) {
290319 return nullptr ;
291320 }
292321 }
293-
322+
294323 // Get a state that's in the direction of @target from @source.
295324 // This should take a step in that direction, but not go all the
296325 // way unless the they're really close together.
297- T intermediateState = _stateSpace->intermediateState (source->state (), target, stepSize ());
326+ T intermediateState;
327+ if (_isASCEnabled) {
328+ intermediateState = _stateSpace->intermediateState (
329+ source->state (),
330+ target,
331+ stepSize (),
332+ maxStepSize ()
333+ );
334+ } else {
335+ intermediateState = _stateSpace->intermediateState (source->state (), target, stepSize ());
336+ }
298337
299338 // Make sure there's actually a direct path from @source to
300339 // @intermediateState. If not, abort
@@ -413,6 +452,8 @@ namespace RRT
413452
414453 int _maxIterations;
415454
455+ bool _isASCEnabled;
456+
416457 float _goalBias;
417458
418459 // / used for Extended RRTs where growth is biased towards waypoints from previously grown tree
@@ -422,6 +463,7 @@ namespace RRT
422463 float _goalMaxDist;
423464
424465 float _stepSize;
466+ float _maxStepSize;
425467
426468 std::shared_ptr<StateSpace<T>> _stateSpace;
427469 };
0 commit comments