BiTRRT.cpp
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 #include <limits>
38 
39 #include "ompl/geometric/planners/rrt/BiTRRT.h"
40 #include "ompl/base/goals/GoalSampleableRegion.h"
41 #include "ompl/base/objectives/MechanicalWorkOptimizationObjective.h"
42 #include "ompl/tools/config/MagicConstants.h"
43 #include "ompl/tools/config/SelfConfig.h"
44 
45 ompl::geometric::BiTRRT::BiTRRT(const base::SpaceInformationPtr &si) : base::Planner(si, "BiTRRT")
46 {
48  specs_.directed = true;
49 
50  maxDistance_ = 0.0; // set in setup()
51  connectionPoint_ = std::make_pair<Motion*, Motion*>(nullptr, nullptr);
52 
53  Planner::declareParam<double>("range", this, &BiTRRT::setRange, &BiTRRT::getRange, "0.:1.:10000.");
54 
55  // BiTRRT Specific Variables
56  frontierThreshold_ = 0.0; // set in setup()
57  setTempChangeFactor(0.1); // how much to increase the temp each time
58  costThreshold_ = base::Cost(std::numeric_limits<double>::infinity());
59  initTemperature_ = 100; // where the temperature starts out
60  frontierNodeRatio_ = 0.1; // 1/10, or 1 non-frontier for every 10 frontier
61 
62  Planner::declareParam<double>("temp_change_factor", this, &BiTRRT::setTempChangeFactor, &BiTRRT::getTempChangeFactor,"0.:.1:1.");
63  Planner::declareParam<double>("init_temperature", this, &BiTRRT::setInitTemperature, &BiTRRT::getInitTemperature);
64  Planner::declareParam<double>("frontier_threshold", this, &BiTRRT::setFrontierThreshold, &BiTRRT::getFrontierThreshold);
65  Planner::declareParam<double>("frontier_node_ratio", this, &BiTRRT::setFrontierNodeRatio, &BiTRRT::getFrontierNodeRatio);
66  Planner::declareParam<double>("cost_threshold", this, &BiTRRT::setCostThreshold, &BiTRRT::getCostThreshold);
67 }
68 
69 ompl::geometric::BiTRRT::~BiTRRT()
70 {
71  freeMemory();
72 }
73 
75 {
76  std::vector<Motion*> motions;
77 
78  if (tStart_)
79  {
80  tStart_->list(motions);
81  for (unsigned int i = 0 ; i < motions.size() ; ++i)
82  {
83  if (motions[i]->state)
84  si_->freeState(motions[i]->state);
85  delete motions[i];
86  }
87  }
88 
89  if (tGoal_)
90  {
91  tGoal_->list(motions);
92  for (unsigned int i = 0 ; i < motions.size() ; ++i)
93  {
94  if (motions[i]->state)
95  si_->freeState(motions[i]->state);
96  delete motions[i];
97  }
98  }
99 }
100 
102 {
103  Planner::clear();
104  freeMemory();
105  if (tStart_)
106  tStart_->clear();
107  if (tGoal_)
108  tGoal_->clear();
109  connectionPoint_ = std::make_pair<Motion*, Motion*>(nullptr, nullptr);
110 
111  // TRRT specific variables
112  temp_ = initTemperature_;
113  nonfrontierCount_ = 1;
114  frontierCount_ = 1; // init to 1 to prevent division by zero error
115  if (opt_)
116  bestCost_ = worstCost_ = opt_->identityCost();
117 }
118 
120 {
121  Planner::setup();
122  tools::SelfConfig sc(si_, getName());
123 
124  // Configuring the range of the planner
125  if (maxDistance_ < std::numeric_limits<double>::epsilon())
126  {
127  sc.configurePlannerRange(maxDistance_);
129  }
130 
131  // Configuring nearest neighbors structures for the planning trees
132  if (!tStart_)
133  tStart_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Motion*>(this));
134  if (!tGoal_)
135  tGoal_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Motion*>(this));
136  tStart_->setDistanceFunction(std::bind(&BiTRRT::distanceFunction, this, std::placeholders::_1, std::placeholders::_2));
137  tGoal_->setDistanceFunction(std::bind(&BiTRRT::distanceFunction, this, std::placeholders::_1, std::placeholders::_2));
138 
139  // Setup the optimization objective, if it isn't specified
140  if (!pdef_ || !pdef_->hasOptimizationObjective())
141  {
142  OMPL_INFORM("%s: No optimization objective specified. Defaulting to mechanical work minimization.", getName().c_str());
143  opt_.reset(new base::MechanicalWorkOptimizationObjective(si_));
144  }
145  else
146  opt_ = pdef_->getOptimizationObjective();
147 
148  // Set the threshold that decides if a new node is a frontier node or non-frontier node
149  if (frontierThreshold_ < std::numeric_limits<double>::epsilon())
150  {
151  frontierThreshold_ = si_->getMaximumExtent() * 0.01;
152  OMPL_DEBUG("%s: Frontier threshold detected to be %lf", getName().c_str(), frontierThreshold_);
153  }
154 
155  // initialize TRRT specific variables
156  temp_ = initTemperature_;
157  nonfrontierCount_ = 1;
158  frontierCount_ = 1; // init to 1 to prevent division by zero error
159  bestCost_ = worstCost_ = opt_->identityCost();
160  connectionRange_ = 10.0 * si_->getStateSpace()->getLongestValidSegmentLength();
161 }
162 
164 {
165  Motion *motion = new Motion(si_);
166  si_->copyState(motion->state, state);
167  motion->cost = opt_->stateCost(motion->state);
168  motion->parent = parent;
169  motion->root = parent ? parent->root : nullptr;
170 
171  if (opt_->isCostBetterThan(motion->cost, bestCost_)) // motion->cost is better than the existing best
172  bestCost_ = motion->cost;
173  if (opt_->isCostBetterThan(worstCost_, motion->cost)) // motion->cost is worse than the existing worst
174  worstCost_ = motion->cost;
175 
176  // Add start motion to the tree
177  tree->add(motion);
178  return motion;
179 }
180 
182 {
183  // Disallow any cost that is not better than the cost threshold
184  if (!opt_->isCostBetterThan(motionCost, costThreshold_))
185  return false;
186 
187  // Always accept if the cost is near or below zero
188  if (motionCost.value() < 1e-4)
189  return true;
190 
191  double dCost = motionCost.value();
192  double transitionProbability = exp(-dCost / temp_);
193  if (transitionProbability > 0.5)
194  {
195  double costRange = worstCost_.value() - bestCost_.value();
196  if (fabs(costRange) > 1e-4) // Do not divide by zero
197  // Successful transition test. Decrease the temperature slightly
198  temp_ /= exp(dCost / (0.1 * costRange));
199 
200  return true;
201  }
202 
203  // The transition failed. Increase the temperature (slightly)
204  temp_ *= tempChangeFactor_;
205  return false;
206 }
207 
209 {
210  if (dist > frontierThreshold_) // Exploration
211  {
212  ++frontierCount_;
213  return true;
214  }
215  else // Refinement
216  {
217  // Check the current ratio first before accepting it
218  if ((double)nonfrontierCount_ / (double)frontierCount_ > frontierNodeRatio_)
219  return false;
220 
221  ++nonfrontierCount_;
222  return true;
223  }
224 }
225 
227 {
228  bool reach = true;
229 
230  // Compute the state to extend toward
231  double d = si_->distance(nearest->state, toMotion->state);
232  // Truncate the random state to be no more than maxDistance_ from nearest neighbor
233  if (d > maxDistance_)
234  {
235  si_->getStateSpace()->interpolate(nearest->state, toMotion->state, maxDistance_ / d, toMotion->state);
236  d = maxDistance_;
237  reach = false;
238  }
239 
240  // Validating the motion
241  // If we are in the goal tree, we validate the motion in reverse
242  // si_->checkMotion assumes that the first argument is valid, so we must check this explicitly
243  // If the motion is valid, check the probabilistic transition test and the
244  // expansion control to ensure high quality nodes are added.
245  bool validMotion = (tree == tStart_ ? si_->checkMotion(nearest->state, toMotion->state) :
246  si_->isValid(toMotion->state) && si_->checkMotion(toMotion->state, nearest->state)) &&
247  transitionTest(opt_->motionCost(nearest->state, toMotion->state)) &&
248  minExpansionControl(d);
249 
250  if (validMotion)
251  {
252  result = addMotion(toMotion->state, tree, nearest);
253  return reach ? SUCCESS : ADVANCED;
254  }
255 
256  return FAILED;
257 }
258 
260 {
261  // Nearest neighbor
262  Motion *nearest = tree->nearest(toMotion);
263  return extendTree(nearest, tree, toMotion, result);
264 }
265 
267 {
268  // Get the nearest state to nmotion in tree (nmotion is NOT in tree)
269  Motion *nearest = tree->nearest(nmotion);
270  double dist = si_->distance(nearest->state, nmotion->state);
271 
272  // Do not attempt a connection if the trees are far apart
273  if (dist > connectionRange_)
274  return false;
275 
276  // Copy the resulting state into our scratch space
277  si_->copyState(xmotion->state, nmotion->state);
278 
279  // Do not try to connect states directly. Must chop up the
280  // extension into segments, just in case one piece fails
281  // the transition test
282  GrowResult result;
283  Motion* next = nullptr;
284  do
285  {
286  // Extend tree from nearest toward xmotion
287  // Store the result into next
288  // This function MAY trash xmotion
289  result = extendTree(nearest, tree, xmotion, next);
290 
291  if (result == ADVANCED)
292  {
293  nearest = next;
294 
295  // xmotion may get trashed during extension, so we reload it here
296  si_->copyState(xmotion->state, nmotion->state); // xmotion may get trashed during extension, so we reload it here
297  }
298  } while (result == ADVANCED);
299 
300  // Successful connection
301  if (result == SUCCESS)
302  {
303  bool treeIsStart = tree == tStart_;
304  Motion* startMotion = treeIsStart ? next : nmotion;
305  Motion* goalMotion = treeIsStart ? nmotion : next;
306 
307  // Make sure start-goal pair is valid
308  if (pdef_->getGoal()->isStartGoalPairValid(startMotion->root, goalMotion->root))
309  {
310  // Since we have connected, nmotion->state and next->state have the same value
311  // We need to check one of their parents to avoid a duplicate state in the solution path
312  // One of these must be true, since we do not ever attempt to connect start and goal directly.
313  if (startMotion->parent)
314  startMotion = startMotion->parent;
315  else
316  goalMotion = goalMotion->parent;
317 
318  connectionPoint_ = std::make_pair(startMotion, goalMotion);
319  return true;
320  }
321  }
322 
323  return false;
324 }
325 
327 {
328  // Basic error checking
329  checkValidity();
330 
331  // Goal information
332  base::Goal *goal = pdef_->getGoal().get();
333  base::GoalSampleableRegion *gsr = dynamic_cast<base::GoalSampleableRegion*>(goal);
334 
335  if (!gsr)
336  {
337  OMPL_ERROR("%s: Goal object does not derive from GoalSampleableRegion", getName().c_str());
339  }
340 
341  // Loop through the (valid) input states and add them to the start tree
342  while (const base::State *state = pis_.nextStart())
343  {
344  Motion *motion = new Motion(si_);
345  si_->copyState(motion->state, state);
346  motion->cost = opt_->stateCost(motion->state);
347  motion->root = motion->state; // this state is the root of a tree
348 
349  if (tStart_->size() == 0) // do not overwrite best/worst from a prior call to solve
350  worstCost_ = bestCost_ = motion->cost;
351 
352  // Add start motion to the tree
353  tStart_->add(motion);
354  }
355 
356  if (tStart_->size() == 0)
357  {
358  OMPL_ERROR("%s: Start tree has no valid states!", getName().c_str());
360  }
361 
362  // Do the same for the goal tree, if it is empty, but only once
363  if (tGoal_->size() == 0)
364  {
365  const base::State *state = pis_.nextGoal(ptc);
366  if (state)
367  {
368  Motion* motion = addMotion(state, tGoal_);
369  motion->root = motion->state; // this state is the root of a tree
370  }
371  }
372 
373  if (tGoal_->size() == 0)
374  {
375  OMPL_ERROR("%s: Goal tree has no valid states!", getName().c_str());
377  }
378 
379  OMPL_INFORM("%s: Planning started with %d states already in datastructure", getName().c_str(), (int)(tStart_->size() + tGoal_->size()));
380 
381  base::StateSamplerPtr sampler = si_->allocStateSampler();
382 
383  Motion *rmotion = new Motion(si_);
384  base::State *rstate = rmotion->state;
385 
386  Motion *xmotion = new Motion(si_);
387  base::State *xstate = xmotion->state;
388 
389  TreeData tree = tStart_;
390  TreeData otherTree = tGoal_;
391 
392  bool solved = false;
393  // Planning loop
394  while (ptc == false)
395  {
396  // Check if there are more goal states
397  if (pis_.getSampledGoalsCount() < tGoal_->size() / 2)
398  {
399  if (const base::State *state = pis_.nextGoal())
400  {
401  Motion* motion = addMotion(state, tGoal_);
402  motion->root = motion->state; // this state is the root of a tree
403  }
404  }
405 
406  // Sample a state uniformly at random
407  sampler->sampleUniform(rstate);
408 
409  Motion* result; // the motion that gets added in extendTree
410  if (extendTree(rmotion, tree, result) != FAILED) // we added something new to the tree
411  {
412  // Try to connect the other tree to the node we just added
413  if (connectTrees(result, otherTree, xmotion))
414  {
415  // The trees have been connected. Construct the solution path
416  Motion *solution = connectionPoint_.first;
417  std::vector<Motion*> mpath1;
418  while (solution != nullptr)
419  {
420  mpath1.push_back(solution);
421  solution = solution->parent;
422  }
423 
424  solution = connectionPoint_.second;
425  std::vector<Motion*> mpath2;
426  while (solution != nullptr)
427  {
428  mpath2.push_back(solution);
429  solution = solution->parent;
430  }
431 
432  PathGeometric *path = new PathGeometric(si_);
433  path->getStates().reserve(mpath1.size() + mpath2.size());
434  for (int i = mpath1.size() - 1 ; i >= 0 ; --i)
435  path->append(mpath1[i]->state);
436  for (unsigned int i = 0 ; i < mpath2.size() ; ++i)
437  path->append(mpath2[i]->state);
438 
439  pdef_->addSolutionPath(base::PathPtr(path), false, 0.0, getName());
440  solved = true;
441  break;
442  }
443  }
444 
445  std::swap(tree, otherTree);
446  }
447 
448  si_->freeState(rstate);
449  si_->freeState(xstate);
450  delete rmotion;
451  delete xmotion;
452 
453  OMPL_INFORM("%s: Created %u states (%u start + %u goal)", getName().c_str(), tStart_->size() + tGoal_->size(), tStart_->size(), tGoal_->size());
455 }
456 
458 {
459  Planner::getPlannerData(data);
460 
461  std::vector<Motion*> motions;
462  if (tStart_)
463  tStart_->list(motions);
464  for (unsigned int i = 0 ; i < motions.size() ; ++i)
465  {
466  if (motions[i]->parent == nullptr)
467  data.addStartVertex(base::PlannerDataVertex(motions[i]->state, 1));
468  else
469  {
470  data.addEdge(base::PlannerDataVertex(motions[i]->parent->state, 1),
471  base::PlannerDataVertex(motions[i]->state, 1));
472  }
473  }
474 
475  motions.clear();
476  if (tGoal_)
477  tGoal_->list(motions);
478  for (unsigned int i = 0 ; i < motions.size() ; ++i)
479  {
480  if (motions[i]->parent == nullptr)
481  data.addGoalVertex(base::PlannerDataVertex(motions[i]->state, 2));
482  else
483  {
484  // The edges in the goal tree are reversed to be consistent with start tree
485  data.addEdge(base::PlannerDataVertex(motions[i]->state, 2),
486  base::PlannerDataVertex(motions[i]->parent->state, 2));
487  }
488  }
489 
490  // Add the edge connecting the two trees
491  if (connectionPoint_.first && connectionPoint_.second)
492  data.addEdge(data.vertexIndex(connectionPoint_.first->state), data.vertexIndex(connectionPoint_.second->state));
493 }
bool approximateSolutions
Flag indicating whether the planner is able to compute approximate solutions.
Definition: Planner.h:212
Object containing planner generated vertex and edge data. It is assumed that all vertices are unique...
Definition: PlannerData.h:163
Motion * addMotion(const base::State *state, TreeData &tree, Motion *parent=nullptr)
Add a state to the given tree. The motion created is returned.
Definition: BiTRRT.cpp:163
double frontierThreshold_
The distance between an existing state and a new state that qualifies it as a frontier state...
Definition: BiTRRT.h:276
base::State * state
The state contained by the motion.
Definition: BiTRRT.h:191
std::pair< Motion *, Motion * > connectionPoint_
The most recent connection point for the two trees. Used for PlannerData computation.
Definition: BiTRRT.h:296
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: BiTRRT.cpp:457
bool minExpansionControl(double dist)
Use frontier node ratio to filter nodes that do not add new information to the search tree...
Definition: BiTRRT.cpp:208
The planner failed to find a solution.
Definition: PlannerStatus.h:62
double getFrontierNodeRatio() const
Get the ratio between adding non-frontier nodes to frontier nodes.
Definition: BiTRRT.h:161
bool transitionTest(const base::Cost &motionCost)
Transition test that filters transitions based on the motion cost. If the motion cost is near or belo...
Definition: BiTRRT.cpp:181
virtual void setup()
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition: BiTRRT.cpp:119
An optimization objective which defines path cost using the idea of mechanical work. To be used in conjunction with TRRT.
A shared pointer wrapper for ompl::base::StateSampler.
GrowResult extendTree(Motion *rmotion, TreeData &tree, Motion *&xmotion)
Extend tree toward the state in rmotion. Store the result of the extension, if any, in result.
Definition: BiTRRT.cpp:259
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...
Abstract definition of goals.
Definition: Goal.h:62
virtual void clear()
Clear all internal datastructures. Planner settings are not affected. Subsequent calls to solve() wil...
Definition: BiTRRT.cpp:101
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
double getRange() const
Get the range the planner is using.
Definition: BiTRRT.h:86
double getTempChangeFactor() const
Get the factor by which the temperature is increased after a failed transition.
Definition: BiTRRT.h:103
Motion * parent
The parent motion in the exploration tree.
Definition: BiTRRT.h:194
void append(const base::State *state)
Append state to the end of this path. The memory for state is copied.
BiTRRT(const base::SpaceInformationPtr &si)
Constructor.
Definition: BiTRRT.cpp:45
bool directed
Flag indicating whether the planner is able to account for the fact that the validity of a motion fro...
Definition: Planner.h:220
double getFrontierThreshold() const
Get the distance between a new state and the nearest neighbor that qualifies a state as being a front...
Definition: BiTRRT.h:146
double initTemperature_
The temperature that planning begins at.
Definition: BiTRRT.h:272
void setFrontierNodeRatio(double frontierNodeRatio)
Set the ratio between adding non-frontier nodes to frontier nodes. For example: .1 is one non-frontie...
Definition: BiTRRT.h:154
Base class for a vertex in the PlannerData structure. All derived classes must implement the clone an...
Definition: PlannerData.h:59
Invalid start state or no start state specified.
Definition: PlannerStatus.h:56
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: BiTRRT.cpp:326
double maxDistance_
The maximum length of a motion to be added to a tree.
Definition: BiTRRT.h:256
Abstract definition of a goal region that can be sampled.
void freeMemory()
Free all memory allocated during planning.
Definition: BiTRRT.cpp:74
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...
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
Definition: Console.h:64
The planner found an exact solution.
Definition: PlannerStatus.h:66
GrowResult
The result of a call to extendTree.
Definition: BiTRRT.h:227
double value() const
The value of the cost.
Definition: Cost.h:54
const base::State * root
Pointer to the root of the tree this motion is contained in.
Definition: BiTRRT.h:201
void setTempChangeFactor(double factor)
Set the factor by which the temperature is increased after a failed transition test. This value should be in the range (0, 1], typically close to zero (default is 0.1). This value is an exponential (e^factor) that is multiplied with the current temperature.
Definition: BiTRRT.h:96
unsigned int vertexIndex(const PlannerDataVertex &v) const
Return the index for the vertex associated with the given data. INVALID_INDEX is returned if this ver...
*double getCostThreshold() const
Get the cost threshold (default is infinity). Any motion cost that is not better than this cost (acco...
Definition: BiTRRT.h:119
A class to store the exit status of Planner::solve()
Definition: PlannerStatus.h:48
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...
void setInitTemperature(double initTemperature)
Set the initial temperature at the start of planning. Should be high to allow for initial exploration...
Definition: BiTRRT.h:126
A shared pointer wrapper for ompl::base::SpaceInformation.
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...
Definition of an abstract state.
Definition: State.h:50
void setFrontierThreshold(double frontierThreshold)
Set the distance between a new state and the nearest neighbor that qualifies a state as being a front...
Definition: BiTRRT.h:139
PlannerSpecs specs_
The specifications of the planner (its capabilities)
Definition: Planner.h:410
#define OMPL_DEBUG(fmt,...)
Log a formatted debugging string.
Definition: Console.h:70
Representation of a motion in the search tree.
Definition: BiTRRT.h:177
static const double COST_MAX_MOTION_LENGTH_AS_SPACE_EXTENT_FRACTION
For cost-based planners it has been observed that smaller ranges are typically suitable. The same range computation strategy is used for all planners, but for cost planners an additional factor (smaller than 1) is multiplied in.
double frontierNodeRatio_
The target ratio of non-frontier nodes to frontier nodes.
Definition: BiTRRT.h:279
void configurePlannerRange(double &range)
Compute what a good length for motion segments is.
Definition: SelfConfig.cpp:230
void setRange(double distance)
Set the maximum possible length of any one motion in the search tree. Very short/long motions may inh...
Definition: BiTRRT.h:80
This class contains methods that automatically configure various parameters for motion planning...
Definition: SelfConfig.h:60
double distanceFunction(const Motion *a, const Motion *b) const
Compute distance between motions (actually distance between contained states)
Definition: BiTRRT.h:250
Definition of a geometric path.
Definition: PathGeometric.h:60
base::Cost costThreshold_
All motion costs must be better than this cost (default is infinity)
Definition: BiTRRT.h:269
double getInitTemperature() const
Get the initial temperature at the start of planning.
Definition: BiTRRT.h:132
void setCostThreshold(double maxCost)
Set the cost threshold (default is infinity). Any motion cost that is not better than this cost (acco...
Definition: BiTRRT.h:111
base::Cost cost
Cost of the state.
Definition: BiTRRT.h:197
bool connectTrees(Motion *nmotion, TreeData &tree, Motion *xmotion)
Attempt to connect tree to nmotion, which is in the other tree. xmotion is scratch space and will be ...
Definition: BiTRRT.cpp:266
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
Definition: Cost.h:47
A shared pointer wrapper for ompl::base::Path.
std::shared_ptr< NearestNeighbors< Motion * > > TreeData
The nearest-neighbors data structure that contains the entire the tree of motions generated during pl...
Definition: BiTRRT.h:210
#define OMPL_INFORM(fmt,...)
Log a formatted information string.
Definition: Console.h:68