Loading...
Searching...
No Matches
HySST.cpp
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2025, University of Santa Cruz Hybrid Systems Laboratory
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 Santa Cruz nor the names of
18 * its 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/* Authors: Beverly Xu */
36/* Adapted from: ompl/geometric/planners/src/SST.cpp by Zakary Littlefield of Rutgers the State University of New
37 * Jersey, New Brunswick */
38
39#include "ompl/control/planners/sst/HySST.h"
40#include "ompl/base/objectives/MinimaxObjective.h"
41#include "ompl/base/objectives/MaximizeMinClearanceObjective.h"
42#include "ompl/base/objectives/PathLengthOptimizationObjective.h"
43#include "ompl/tools/config/SelfConfig.h"
44#include "ompl/base/spaces/RealVectorStateSpace.h"
45#include "ompl/base/goals/GoalState.h"
46#include "ompl/control/spaces/RealVectorControlSpace.h"
47
48namespace base = ompl::base;
49namespace tools = ompl::tools;
50namespace control = ompl::control;
51
52ompl::control::HySST::HySST(const control::SpaceInformationPtr &si_) : base::Planner(si_, "HySST")
53{
54 specs_.approximateSolutions = true;
55 siC_ = si_.get();
56 prevSolution_.clear();
57
58 addPlannerProgressProperty("best cost REAL", [this] { return std::to_string(this->prevSolutionCost_.value()); });
59}
60
64
66{
68 if (!nn_)
70 nn_->setDistanceFunction([this](const Motion *a, const Motion *b)
71 { return ompl::control::HySST::distanceFunc_(a->state, b->state); });
72 if (!witnesses_)
74 witnesses_->setDistanceFunction([this](const Motion *a, const Motion *b)
75 { return ompl::control::HySST::distanceFunc_(a->state, b->state); });
76
77 if (pdef_ && pdef_->hasOptimizationObjective())
78 {
79 opt_ = pdef_->getOptimizationObjective();
80 if (dynamic_cast<base::MaximizeMinClearanceObjective *>(opt_.get()) ||
81 dynamic_cast<base::MinimaxObjective *>(opt_.get()))
82 OMPL_WARN("%s: Asymptotic near-optimality has only been proven with Lipschitz continuous cost "
83 "functions w.r.t. state and control. This optimization objective will result in undefined "
84 "behavior",
85 getName().c_str());
86 costFunc_ = [this](Motion *motion) -> base::Cost
87 { return opt_->motionCost(motion->parent->state, motion->state); };
88 }
89 else
90 { // if no optimization objective set, assume we want to minimize hybrid time
91 OMPL_WARN("%s: No optimization object set. Using hybrid time", getName().c_str());
92 costFunc_ = [](Motion *motion) -> base::Cost
93 {
95 ompl::base::HybridStateSpace::getStateTime(motion->parent->state) +
97 ompl::base::HybridStateSpace::getStateJumps(motion->parent->state));
98 };
99 opt_ = std::make_shared<base::PathLengthOptimizationObjective>(si_);
100 }
101 prevSolutionCost_ = opt_->infiniteCost();
102}
103
105{
106 Planner::clear();
107 sampler_.reset();
108 freeMemory();
109 if (nn_)
110 nn_->clear();
111 if (witnesses_)
112 witnesses_->clear();
113 if (opt_)
114 prevSolutionCost_ = opt_->infiniteCost();
115}
116
118{
119 if (nn_)
120 {
121 std::vector<Motion *> motions;
122 nn_->list(motions);
123 for (auto &motion : motions)
124 {
125 if (motion->state)
126 si_->freeState(motion->state);
127 delete motion;
128 }
129 }
130 if (witnesses_)
131 {
132 std::vector<Motion *> witnesses;
133 witnesses_->list(witnesses);
134 for (auto &witness : witnesses)
135 {
136 if (witness->state)
137 si_->freeState(witness->state);
138 delete witness;
139 }
140 }
141 prevSolution_.clear();
142}
143
145{
146 std::vector<Motion *> ret; // List of all nodes within the selection radius
147 Motion *selected = nullptr;
148 base::Cost bestCost = opt_->infiniteCost();
149 nn_->nearestR(sample, selectionRadius_,
150 ret); // Find the nearest nodes within the selection radius of the random sample
151
152 for (auto &i : ret) // Find the active node with the best cost within the selection radius
153 {
154 if (!i->inactive_ && i->accCost_.value() < bestCost.value())
155 {
156 bestCost = i->accCost_;
157 selected = i;
158 }
159 }
160 if (selected == nullptr) // However, if there are no active nodes within the selection radius, select the next
161 // nearest node
162 {
163 int k = 1;
164 while (selected == nullptr)
165 {
166 nn_->nearestK(sample, k, ret); // sample the k nearest nodes to the random sample into ret
167 for (unsigned int i = 0; i < ret.size() && selected == nullptr;
168 i++) // Find the active node with the best cost
169 if (!ret[i]->inactive_)
170 selected = ret[i];
171 k += 5; // If none found, increase the number of nearest nodes to sample
172 }
173 }
174 return selected;
175}
176
178{
179 auto *closest = new Witness(siC_);
180
181 if (witnesses_->size() > 0)
182 closest = static_cast<Witness *>(witnesses_->nearest(node));
183
184 if (distanceFunc_(closest->state, node->state) > pruningRadius_ ||
185 witnesses_->size() == 0) // If the closest witness is outside the pruning radius or if there are no witnesses
186 // yet, return a new witness at the same point as the node.
187 {
188 closest->linkRep(node);
189 si_->copyState(closest->state, node->state);
190 witnesses_->add(closest);
191 }
192 return closest;
193}
194
195std::vector<ompl::control::HySST::Motion *> ompl::control::HySST::extend(Motion *parentMotion)
196{
197 control::Control *compoundControl = siC_->allocControl();
198 siC_->allocControlSampler()->sample(compoundControl);
199
200 // Generate random maximum flow time
201 double random = rand();
202 double randomFlowTimeMax = random / RAND_MAX * tM_;
203
204 double tFlow = 0; // Tracking variable for the amount of flow time used in a given continuous simulation step
205 bool collision = false; // Set collision to false initially
206
207 // Choose whether to begin growing the tree in the flow or jump regime
208 bool in_jump = jumpSet_(parentMotion);
209 bool in_flow = flowSet_(parentMotion);
210 bool priority = in_jump && in_flow ? random / RAND_MAX > 0.5 : in_jump; // If both are true, there is an equal
211 // chance of being in flow or jump set.
212
213 // Sample and instantiate parent vertices and states in edges
214 base::State *previousState = si_->allocState();
215 si_->copyState(previousState, parentMotion->state);
216 auto *collisionParentMotion = parentMotion;
217
218 // Allocate memory for the new edge
219 std::vector<base::State *> *intermediateStates = new std::vector<base::State *>;
220
221 // Simulate in either the jump or flow regime
222 if (!priority) // Flow
223 {
224 while (tFlow < randomFlowTimeMax && flowSet_(parentMotion))
225 {
226 tFlow += flowStepDuration_;
227
228 // Find new state with continuous simulation
229 base::State *intermediateState = si_->allocState();
230 intermediateState = this->continuousSimulator_(getFlowControl(compoundControl), previousState,
231 flowStepDuration_, intermediateState);
233 intermediateState, ompl::base::HybridStateSpace::getStateTime(previousState) + flowStepDuration_);
236
237 // Add new intermediate state to edge
238 intermediateStates->push_back(intermediateState);
239
240 // Create motion to add to tree
241 auto *motion = new Motion(siC_);
242 si_->copyState(motion->state, intermediateState);
243 motion->parent = parentMotion;
244 motion->solutionPair = intermediateStates; // Set the new motion solutionPair
245 motion->control = compoundControl;
246
247 // Return nullptr if in unsafe set and exit function
248 if (unsafeSet_(motion))
249 return std::vector<Motion *>(); // Return empty vector
250
251 double *collisionTime = new double(-1.0);
252 collision = collisionChecker_(motion, jumpSet_, intermediateState, collisionTime);
253
254 if (*collisionTime != -1.0)
255 {
256 ompl::base::HybridStateSpace::setStateTime(motion->state, *collisionTime);
257 ompl::base::HybridStateSpace::setStateTime(intermediateState, *collisionTime);
258 }
259
260 // State has passed all tests so update parent, edge, and temporary states
261 si_->copyState(previousState, intermediateState);
262
263 // Calculate distance to goal to check if solution has been found
264 bool inGoalSet = pdef_->getGoal()->isSatisfied(intermediateState);
265
266 // If maximum flow time has been reached, a collision has occured, or a solution has been found, exit the
267 // loop
268 if (tFlow >= randomFlowTimeMax || collision || inGoalSet)
269 {
270 if (inGoalSet)
271 return std::vector<Motion *>{motion};
272 else if (collision)
273 {
274 collisionParentMotion = motion;
275 priority = true; // If collision has occurred, continue to jump regime
276 }
277 else
278 {
279 return std::vector<Motion *>{motion}; // Return the motion in vector form
280 }
281 break;
282 }
283 }
284 }
285
286 if (priority)
287 { // Jump
288 // Instantiate and find new state with discrete simulator
289 base::State *newState = si_->allocState();
290
291 newState = this->discreteSimulator_(previousState, getJumpControl(compoundControl), newState);
292
293 // Create motion to add to tree
294 auto *motion = new Motion(siC_);
295 si_->copyState(motion->state, newState);
296 motion->parent = collisionParentMotion;
297 motion->control = compoundControl;
302
303 // Return nullptr if in unsafe set and exit function
304 if (unsafeSet_(motion))
305 return std::vector<Motion *>(); // Return empty vector
306
307 // Add motions to tree, and free up memory allocated to newState
308 collisionParentMotion->numChildren_++;
309
310 if (tFlow > 0) // If coming from flow propagation
311 return std::vector<Motion *>{motion, collisionParentMotion};
312 else
313 return std::vector<Motion *>{motion};
314 }
315 return std::vector<Motion *>();
316}
317
319{
320 sampler_->sampleUniform(randomMotion->state);
321}
322
324{
328
329 while (const base::State *st = pis_.nextStart())
330 {
331 auto *motion = new Motion(siC_);
332 si_->copyState(motion->state, st);
333 siC_->nullControl(motion->control);
334 nn_->add(motion);
337 motion->accCost_ = base::Cost(0.0); // Initialize the accumulated cost to the identity cost
338 findClosestWitness(motion); // Set representatives for the witness set
339 }
340
341 if (!sampler_)
342 sampler_ = siC_->allocStateSampler();
343 if (!controlSampler_)
344 controlSampler_ = siC_->allocDirectedControlSampler();
345
346 if (nn_->size() == 0)
347 {
348 OMPL_ERROR("%s: There are no valid initial states!", getName().c_str());
350 }
351
352 Motion *solution = nullptr;
353 Motion *approxsol = nullptr;
354 double approxdif = std::numeric_limits<double>::infinity();
355 auto *rmotion = new Motion(siC_);
356 base::State *rstate = rmotion->state;
357
358 int solutions = 0;
359
360 while (!ptc)
361 {
362 // sample random state
363 randomSample(rmotion);
364
365 // find closest state in the tree
366 Motion *nmotion = selectNode(rmotion);
367
368 std::vector<Motion *> dMotion = {new Motion(siC_)};
369
370 dMotion = extend(nmotion);
371
372 if (dMotion.size() == 0) // If extension failed, continue to next iteration
373 continue;
374
375 si_->copyState(rstate,
376 dMotion[0]->state); // copy the new state to the random state pointer. First value of dMotion
377 // vector will always be the newest state, even if a collision occurs
378
379 base::Cost incCost = costFunc_(dMotion[0]); // Compute incremental cost
380 base::Cost cost = base::Cost(nmotion->accCost_.value() + incCost.value()); // Combine total cost
381
382 auto *collisionParentMotion = new Motion(siC_);
383 if (dMotion.size() > 1) // If collision occured during extension
384 {
385 collisionParentMotion = dMotion[1];
386 collisionParentMotion->accCost_ = base::Cost(nmotion->accCost_.value() + costFunc_(dMotion[1]).value());
387 cost = base::Cost(cost.value() + costFunc_(dMotion[1]).value());
388 }
389
390 Witness *closestWitness = findClosestWitness(rmotion); // Find closest witness
391
392 if (closestWitness->rep_ == rmotion ||
393 cost.value() < closestWitness->rep_->accCost_.value()) // If the newly propagated state is a child of the
394 // new representative of the witness (previously had
395 // no rep) or it dominates the old representative's
396 // cost
397 {
398 Motion *oldRep = closestWitness->rep_; // Set a copy of the old representative
399 /* create a motion copy of the newly propagated state */
400 auto *motion = new Motion(siC_);
401
402 if (dMotion.size() > 1) // If collision occured during extension
403 {
404 nn_->add(collisionParentMotion);
405 }
406
407 motion = dMotion[0];
408 motion->accCost_ = cost;
409
410 nmotion->numChildren_++;
411 closestWitness->linkRep(motion); // Create new edge and set the new node as the representative
412
413 nn_->add(motion); // Add new node to tree
414 bool solved = pdef_->getGoal()->isSatisfied(motion->state, &dist_);
415
416 if (solved && motion->accCost_.value() < prevSolutionCost_.value()) // If the new state is a solution and
417 // it has a lower cost than the
418 // previous solution
419 {
420 approxdif = dist_;
421 solution = motion;
422
423 prevSolution_.clear();
424 Motion *solTrav = solution; // Traverse the solution and save the states in prevSolution_
425 while (solTrav != nullptr)
426 {
427 prevSolution_.push_back(solTrav);
428 solTrav = solTrav->parent;
429 }
430
431 prevSolutionCost_ = solution->accCost_;
432
433 OMPL_INFORM("Solution found with cost of %f", prevSolutionCost_.value());
434 solutions++;
435 if (solutions >= batchSize_)
436 break;
437 }
438 if (solution == nullptr && dist_ < approxdif) // If no solution found and distance to goal of this new
439 // state is closer than before (because no guarantee of
440 // probabilistic completeness). Also where approximate
441 // solutions are filled.
442 {
443 approxdif = dist_;
444 approxsol = motion;
445
446 prevSolution_.clear();
447 Motion *solTrav = approxsol;
448 while (solTrav != nullptr)
449 {
450 prevSolution_.push_back(solTrav);
451 solTrav = solTrav->parent;
452 }
453 prevSolutionCost_ = motion->accCost_;
454 }
455
456 if (oldRep != rmotion) // If the representative has changed (prune)
457 {
458 oldRep->inactive_ = true; // Mark the node as inactive
459 while (oldRep->inactive_ && oldRep->numChildren_ == 0) // While the current node is inactive and is a
460 // leaf, remove it (non-leaf nodes have been
461 // marked inactive)
462 {
463 Motion *oldRepParent = oldRep->parent;
464 oldRep = oldRepParent;
465 oldRep->numChildren_--;
466
467 if (oldRep->numChildren_ == 0)
468 oldRep->inactive_ =
469 true; // Now that its only child has been removed, this node is inactive as well
470 }
471 }
472 }
473 }
474
475 bool solved = false;
476 bool approximate = false;
477
478 if (solution == nullptr) // If closest state to goal is outside goal set
479 solution = approxsol;
480 else
481 solved = true;
482
483 if (approxdif != 0) // Approximate if not exactly the goal state
484 approximate = true;
485
486 if (solution != nullptr) // If any state has been successfully propagated
487 {
488 // Set the solution path
489 constructSolution(solution);
490 }
491
492 return {solved, approximate};
493}
494
496{
497 std::vector<Motion *> trajectory;
498 nn_->list(trajectory);
499 std::vector<Motion *> mpath;
500
501 double finalDistance = 0;
502 pdef_->getGoal()->isSatisfied(trajectory.back()->state, &finalDistance);
503
504 Motion *solution = last_motion;
505
506 int pathSize = 0;
507
508 // Construct the path from the goal to the start by following the parent pointers
509 while (solution != nullptr)
510 {
511 mpath.push_back(solution);
512 if (solution->solutionPair != nullptr) // A jump motion does not contain an edge
513 pathSize += solution->solutionPair->size() + 1; // +1 for the end state
514 solution = solution->parent;
515 }
516
517 // Create a new path object to store the solution path
518 auto path(std::make_shared<control::PathControl>(si_));
519
520 // Reserve space for the path states
521 path->getStates().reserve(pathSize);
522
523 // Add the states to the path in reverse order (from start to goal)
524 for (int i = mpath.size() - 1; i >= 0; --i)
525 {
526 // Append all intermediate states to the path, including starting state,
527 // excluding end vertex
528 if (mpath[i]->solutionPair != nullptr)
529 { // A jump motion does not contain an edge
530 for (unsigned int j = 0; j < mpath[i]->solutionPair->size(); j++)
531 {
532 if (i == 0 && j == 0) // Starting state has no control
533 {
534 path->append(mpath[i]->solutionPair->at(j));
535 continue;
536 }
537 path->append(mpath[i]->solutionPair->at(j), mpath[i]->control,
538 siC_->getPropagationStepSize()); // Need to make a new motion to append to trajectory
539 // matrix
540 }
541 }
542 else
543 { // If a jump motion
544 if (i == 0)
545 path->append(mpath[i]->state);
546 else
547 path->append(mpath[i]->state, mpath[i]->control, 0);
548 }
549 }
550
551 // Add the solution path to the problem definition
552 pdef_->addSolutionPath(path, finalDistance > 0.0, finalDistance, getName());
553 OMPL_INFORM("%s: Created %u states", getName().c_str(), nn_->size());
554
555 // Return a status indicating that an exact solution has been found
556 if (finalDistance > 0.0)
558 else
560}
561
563{
564 Planner::getPlannerData(data);
565
566 std::vector<Motion *> motions;
567 std::vector<Motion *> allMotions;
568 if (nn_)
569 nn_->list(motions);
570
571 for (auto &motion : motions)
572 if (motion->numChildren_ == 0)
573 allMotions.push_back(motion);
574 for (unsigned i = 0; i < allMotions.size(); i++)
575 if (allMotions[i]->getParent() != nullptr)
576 allMotions.push_back(allMotions[i]->getParent());
577
578 if (prevSolution_.size() != 0)
580
581 for (auto &allMotion : allMotions)
582 {
583 if (allMotion->getParent() == nullptr)
584 data.addStartVertex(base::PlannerDataVertex(allMotion->getState()));
585 else
586 data.addEdge(base::PlannerDataVertex(allMotion->getParent()->getState()),
587 base::PlannerDataVertex(allMotion->getState()));
588 }
589}
Definition of a cost value. Can represent the cost of a motion or the cost of a state.
Definition Cost.h:48
double value() const
The value of the cost.
Definition Cost.h:56
static void setStateTime(ompl::base::State *state, double position)
Set the time position value of the given state.
static double getStateTime(const ompl::base::State *state)
The time value of the given state.
static void setStateJumps(ompl::base::State *state, int jumps)
Set the jumps value of the given state.
static int getStateJumps(const ompl::base::State *state)
The jumps value of the given state.
Objective for attempting to maximize the minimum clearance along a path.
The cost of a path is defined as the worst state cost over the entire path. This objective attempts t...
Base class for a vertex in the PlannerData structure. All derived classes must implement the clone an...
Definition PlannerData.h:59
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...
Encapsulate a termination condition for a motion planner. Planners will call operator() to decide whe...
PlannerInputStates pis_
Utility class to extract valid input states.
Definition Planner.h:407
void addPlannerProgressProperty(const std::string &progressPropertyName, const PlannerProgressProperty &prop)
Add a planner progress property called progressPropertyName with a property querying function prop to...
Definition Planner.h:394
PlannerSpecs specs_
The specifications of the planner (its capabilities).
Definition Planner.h:413
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
SpaceInformationPtr si_
The space information for which planning is done.
Definition Planner.h:401
virtual void checkValidity()
Check to see if the planner is in a working state (setup has been called, a goal was set,...
Definition Planner.cpp:106
virtual void setup()
Perform extra configuration steps, if needed. This call will also issue a call to ompl::base::SpaceIn...
Definition Planner.cpp:92
Definition of an abstract state.
Definition State.h:50
Definition of an abstract control.
Definition Control.h:48
Representation of a motion.
Definition HySST.h:80
base::Cost accCost_
The total cost accumulated from the root to this vertex.
Definition HySST.h:106
unsigned numChildren_
Number of children. Starting with 0.
Definition HySST.h:115
std::vector< base::State * > * solutionPair
The integration steps defining the edge of the motion, between the parent and child vertices.
Definition HySST.h:121
Motion * parent
The parent motion in the exploration tree.
Definition HySST.h:112
bool inactive_
If inactive, this node is not considered for selection.
Definition HySST.h:118
base::State * state
The state contained by the motion.
Definition HySST.h:109
Representation of a witness vertex in the search tree.
Definition HySST.h:372
Motion * rep_
The node in the tree that is within the pruning radius.
Definition HySST.h:410
void linkRep(Motion *lRep)
Set the representative of the witness.
Definition HySST.h:404
int batchSize_
The number of solutions allowed until the most optimal solution is returned.
Definition HySST.h:587
double flowStepDuration_
The flow time for a given integration step, within a flow propagation step. Must be set by user.
Definition HySST.h:483
std::shared_ptr< NearestNeighbors< Motion * > > nn_
A nearest-neighbors datastructure containing the tree of motions.
Definition HySST.h:426
HySST(const control::SpaceInformationPtr &si)
Constructor.
Definition HySST.cpp:52
control::SpaceInformation * siC_
The base::SpaceInformation cast as control::SpaceInformation, for convenience.
Definition HySST.h:465
void clear() override
Clear all allocated memory.
Definition HySST.cpp:104
std::function< base::State *(base::State *curState, const control::Control *u, base::State *newState)> discreteSimulator_
Simulator for propagation under jump regime.
Definition HySST.h:493
std::function< ompl::base::State *(const control::Control *control, ompl::base::State *x_cur, double tFlow, ompl::base::State *new_state)> continuousSimulator
Simulates the dynamics of the system.
Definition HySST.h:308
std::function< bool(Motion *motion, std::function< bool(Motion *motion)> obstacleSet, base::State *newState, double *collisionTime)> collisionChecker_
Collision checker. Default is point-by-point collision checking using the jump set.
Definition HySST.h:447
Motion * selectNode(Motion *sample)
Finds the best node in the tree withing the selection radius around a random sample.
Definition HySST.cpp:144
double pruningRadius_
The radius for determining the size of the pruning region. Delta_bn.
Definition HySST.h:572
void checkMandatoryParametersSet(void) const
Check if all required parameters have been set.
Definition HySST.h:339
std::function< double(base::State *state1, base::State *state2)> distanceFunc_
Compute distance between states, default is Euclidean distance.
Definition HySST.h:473
void freeMemory()
Free the memory allocated by this planner.
Definition HySST.cpp:117
void setup() override
Set the problem instance to solve.
Definition HySST.cpp:65
base::OptimizationObjectivePtr opt_
The optimization objective. Default is a shortest path objective.
Definition HySST.h:517
std::function< base::State *(const control::Control *u, base::State *curState, double tFlowMax, base::State *newState)> continuousSimulator_
Simulator for propagation under flow regime.
Definition HySST.h:532
std::shared_ptr< NearestNeighbors< Motion * > > witnesses_
A nearest-neighbors datastructure containing the tree of witness motions.
Definition HySST.h:566
double tM_
The maximum flow time for a given flow propagation step. Must be set by the user.
Definition HySST.h:477
~HySST() override
Destructor.
Definition HySST.cpp:61
void setContinuousSimulator(std::function< base::State *(const control::Control *u, base::State *curState, double tFlowMax, base::State *newState)> function)
Define the continuous dynamics simulator.
Definition HySST.h:298
std::function< bool(Motion *motion)> flowSet_
Function that returns true if a motion intersects with the flow set, and false if not.
Definition HySST.h:507
void getPlannerData(base::PlannerData &data) const override
Get the PlannerData object associated with this planner.
Definition HySST.cpp:562
std::function< base::Cost(Motion *motion)> costFunc_
Calculate the cost of a motion. Default is using optimization objective.
Definition HySST.h:520
base::Cost prevSolutionCost_
The best solution cost we have found so far.
Definition HySST.h:584
Witness * findClosestWitness(Motion *node)
Find the closest witness node to a newly generated potential node.
Definition HySST.cpp:177
std::function< bool(Motion *motion)> unsafeSet_
Function that returns true if a motion intersects with the unsafe set, and false if not.
Definition HySST.h:514
std::function< bool(Motion *motion)> jumpSet_
Function that returns true if a motion intersects with the jump set, and false if not.
Definition HySST.h:500
double dist_
Minimum distance from goal to final vertex of generated trajectories.
Definition HySST.h:578
base::PlannerStatus solve(const base::PlannerTerminationCondition &ptc) override
Main solve function.
Definition HySST.cpp:323
std::vector< Motion * > prevSolution_
The best solution (with best cost) we have found so far.
Definition HySST.h:581
double selectionRadius_
The radius for determining the node selected for extension. Delta_s.
Definition HySST.h:569
std::vector< Motion * > extend(Motion *m)
Randomly propagate a new edge.
Definition HySST.cpp:195
base::StateSamplerPtr sampler_
State sampler.
Definition HySST.h:563
control::DirectedControlSamplerPtr controlSampler_
Control Sampler.
Definition HySST.h:462
base::PlannerStatus constructSolution(Motion *lastMotion)
Construct the path, starting at the last edge.
Definition HySST.cpp:495
void randomSample(Motion *randomMotion)
Sample the random motion.
Definition HySST.cpp:318
static NearestNeighbors< _T > * getDefaultNearestNeighbors(const base::Planner *planner)
Select a default nearest neighbor datastructure for the given space.
Definition SelfConfig.h:105
#define OMPL_INFORM(fmt,...)
Log a formatted information string.
Definition Console.h:68
#define OMPL_ERROR(fmt,...)
Log a formatted error string.
Definition Console.h:64
#define OMPL_WARN(fmt,...)
Log a formatted warning string.
Definition Console.h:66
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
Includes various tools such as self config, benchmarking, etc.
A class to store the exit status of Planner::solve().
@ INVALID_START
Invalid start state or no start state specified.
@ EXACT_SOLUTION
The planner found an exact solution.
@ APPROXIMATE_SOLUTION
The planner found an approximate solution.