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 {
88 const unsigned int steps =
89 motion->solutionPair != nullptr ? static_cast<unsigned int>(motion->solutionPair->size()) : 0u;
90 return opt_->controlMotionCost(motion->parent->state, motion->control, steps, motion->state);
91 };
92 }
93 else
94 { // if no optimization objective set, assume we want to minimize hybrid time
95 OMPL_WARN("%s: No optimization object set. Using hybrid time", getName().c_str());
96 costFunc_ = [](Motion *motion) -> base::Cost
97 {
99 ompl::base::HybridStateSpace::getStateTime(motion->parent->state) +
101 ompl::base::HybridStateSpace::getStateJumps(motion->parent->state));
102 };
103 opt_ = std::make_shared<base::PathLengthOptimizationObjective>(si_);
104 }
105 prevSolutionCost_ = opt_->infiniteCost();
106}
107
109{
110 Planner::clear();
111 sampler_.reset();
112 freeMemory();
113 if (nn_)
114 nn_->clear();
115 if (witnesses_)
116 witnesses_->clear();
117 if (opt_)
118 prevSolutionCost_ = opt_->infiniteCost();
119}
120
122{
123 if (nn_)
124 {
125 std::vector<Motion *> motions;
126 nn_->list(motions);
127 for (auto &motion : motions)
128 {
129 if (motion->state)
130 si_->freeState(motion->state);
131 delete motion;
132 }
133 }
134 if (witnesses_)
135 {
136 std::vector<Motion *> witnesses;
137 witnesses_->list(witnesses);
138 for (auto &witness : witnesses)
139 {
140 if (witness->state)
141 si_->freeState(witness->state);
142 delete witness;
143 }
144 }
145 prevSolution_.clear();
146}
147
149{
150 std::vector<Motion *> ret; // List of all nodes within the selection radius
151 Motion *selected = nullptr;
152 base::Cost bestCost = opt_->infiniteCost();
153 nn_->nearestR(sample, selectionRadius_,
154 ret); // Find the nearest nodes within the selection radius of the random sample
155
156 for (auto &i : ret) // Find the active node with the best cost within the selection radius
157 {
158 if (!i->inactive_ && i->accCost_.value() < bestCost.value())
159 {
160 bestCost = i->accCost_;
161 selected = i;
162 }
163 }
164 if (selected == nullptr) // However, if there are no active nodes within the selection radius, select the next
165 // nearest node
166 {
167 int k = 1;
168 while (selected == nullptr)
169 {
170 nn_->nearestK(sample, k, ret); // sample the k nearest nodes to the random sample into ret
171 for (unsigned int i = 0; i < ret.size() && selected == nullptr;
172 i++) // Find the active node with the best cost
173 if (!ret[i]->inactive_)
174 selected = ret[i];
175 k += 5; // If none found, increase the number of nearest nodes to sample
176 }
177 }
178 return selected;
179}
180
182{
183 auto *closest = new Witness(siC_);
184
185 if (witnesses_->size() > 0)
186 closest = static_cast<Witness *>(witnesses_->nearest(node));
187
188 if (distanceFunc_(closest->state, node->state) > pruningRadius_ ||
189 witnesses_->size() == 0) // If the closest witness is outside the pruning radius or if there are no witnesses
190 // yet, return a new witness at the same point as the node.
191 {
192 closest->linkRep(node);
193 si_->copyState(closest->state, node->state);
194 witnesses_->add(closest);
195 }
196 return closest;
197}
198
199std::vector<ompl::control::HySST::Motion *> ompl::control::HySST::extend(Motion *parentMotion)
200{
201 control::Control *compoundControl = siC_->allocControl();
202 siC_->allocControlSampler()->sample(compoundControl);
203
204 // Generate random maximum flow time
205 double random = rand();
206 double randomFlowTimeMax = random / RAND_MAX * tM_;
207
208 double tFlow = 0; // Tracking variable for the amount of flow time used in a given continuous simulation step
209 bool collision = false; // Set collision to false initially
210
211 // Choose whether to begin growing the tree in the flow or jump regime
212 bool in_jump = jumpSet_(parentMotion);
213 bool in_flow = flowSet_(parentMotion);
214 bool priority = in_jump && in_flow ? random / RAND_MAX > 0.5 : in_jump; // If both are true, there is an equal
215 // chance of being in flow or jump set.
216
217 // Sample and instantiate parent vertices and states in edges
218 base::State *previousState = si_->allocState();
219 si_->copyState(previousState, parentMotion->state);
220 auto *collisionParentMotion = parentMotion;
221
222 // Allocate memory for the new edge
223 std::vector<base::State *> *intermediateStates = new std::vector<base::State *>;
224
225 // Simulate in either the jump or flow regime
226 if (!priority) // Flow
227 {
228 while (tFlow < randomFlowTimeMax && flowSet_(parentMotion))
229 {
230 tFlow += flowStepDuration_;
231
232 // Find new state with continuous simulation
233 base::State *intermediateState = si_->allocState();
234 intermediateState = this->continuousSimulator_(getFlowControl(compoundControl), previousState,
235 flowStepDuration_, intermediateState);
237 intermediateState, ompl::base::HybridStateSpace::getStateTime(previousState) + flowStepDuration_);
240
241 // Add new intermediate state to edge
242 intermediateStates->push_back(intermediateState);
243
244 // Create motion to add to tree
245 auto *motion = new Motion(siC_);
246 si_->copyState(motion->state, intermediateState);
247 motion->parent = parentMotion;
248 motion->solutionPair = intermediateStates; // Set the new motion solutionPair
249 motion->control = compoundControl;
250
251 // Return nullptr if in unsafe set and exit function
252 if (unsafeSet_(motion))
253 return std::vector<Motion *>(); // Return empty vector
254
255 double *collisionTime = new double(-1.0);
256 collision = collisionChecker_(motion, jumpSet_, intermediateState, collisionTime);
257
258 if (*collisionTime != -1.0)
259 {
260 ompl::base::HybridStateSpace::setStateTime(motion->state, *collisionTime);
261 ompl::base::HybridStateSpace::setStateTime(intermediateState, *collisionTime);
262 }
263
264 // State has passed all tests so update parent, edge, and temporary states
265 si_->copyState(previousState, intermediateState);
266
267 // Calculate distance to goal to check if solution has been found
268 bool inGoalSet = pdef_->getGoal()->isSatisfied(intermediateState);
269
270 // If maximum flow time has been reached, a collision has occured, or a solution has been found, exit the
271 // loop
272 if (tFlow >= randomFlowTimeMax || collision || inGoalSet)
273 {
274 if (inGoalSet)
275 return std::vector<Motion *>{motion};
276 else if (collision)
277 {
278 collisionParentMotion = motion;
279 priority = true; // If collision has occurred, continue to jump regime
280 }
281 else
282 {
283 return std::vector<Motion *>{motion}; // Return the motion in vector form
284 }
285 break;
286 }
287 }
288 }
289
290 if (priority)
291 { // Jump
292 // Instantiate and find new state with discrete simulator
293 base::State *newState = si_->allocState();
294
295 newState = this->discreteSimulator_(previousState, getJumpControl(compoundControl), newState);
296
297 // Create motion to add to tree
298 auto *motion = new Motion(siC_);
299 si_->copyState(motion->state, newState);
300 motion->parent = collisionParentMotion;
301 motion->control = compoundControl;
306
307 // Return nullptr if in unsafe set and exit function
308 if (unsafeSet_(motion))
309 return std::vector<Motion *>(); // Return empty vector
310
311 // Add motions to tree, and free up memory allocated to newState
312 collisionParentMotion->numChildren_++;
313
314 if (tFlow > 0) // If coming from flow propagation
315 return std::vector<Motion *>{motion, collisionParentMotion};
316 else
317 return std::vector<Motion *>{motion};
318 }
319 return std::vector<Motion *>();
320}
321
323{
324 sampler_->sampleUniform(randomMotion->state);
325}
326
328{
332
333 while (const base::State *st = pis_.nextStart())
334 {
335 auto *motion = new Motion(siC_);
336 si_->copyState(motion->state, st);
337 siC_->nullControl(motion->control);
338 nn_->add(motion);
341 motion->accCost_ = base::Cost(0.0); // Initialize the accumulated cost to the identity cost
342 findClosestWitness(motion); // Set representatives for the witness set
343 }
344
345 if (!sampler_)
346 sampler_ = siC_->allocStateSampler();
347 if (!controlSampler_)
348 controlSampler_ = siC_->allocDirectedControlSampler();
349
350 if (nn_->size() == 0)
351 {
352 OMPL_ERROR("%s: There are no valid initial states!", getName().c_str());
354 }
355
356 Motion *solution = nullptr;
357 Motion *approxsol = nullptr;
358 double approxdif = std::numeric_limits<double>::infinity();
359 auto *rmotion = new Motion(siC_);
360 base::State *rstate = rmotion->state;
361
362 int solutions = 0;
363
364 while (!ptc)
365 {
366 // sample random state
367 randomSample(rmotion);
368
369 // find closest state in the tree
370 Motion *nmotion = selectNode(rmotion);
371
372 std::vector<Motion *> dMotion = {new Motion(siC_)};
373
374 dMotion = extend(nmotion);
375
376 if (dMotion.size() == 0) // If extension failed, continue to next iteration
377 continue;
378
379 si_->copyState(rstate,
380 dMotion[0]->state); // copy the new state to the random state pointer. First value of dMotion
381 // vector will always be the newest state, even if a collision occurs
382
383 base::Cost incCost = costFunc_(dMotion[0]); // Compute incremental cost
384 base::Cost cost = base::Cost(nmotion->accCost_.value() + incCost.value()); // Combine total cost
385
386 auto *collisionParentMotion = new Motion(siC_);
387 if (dMotion.size() > 1) // If collision occured during extension
388 {
389 collisionParentMotion = dMotion[1];
390 collisionParentMotion->accCost_ = base::Cost(nmotion->accCost_.value() + costFunc_(dMotion[1]).value());
391 cost = base::Cost(cost.value() + costFunc_(dMotion[1]).value());
392 }
393
394 Witness *closestWitness = findClosestWitness(rmotion); // Find closest witness
395
396 if (closestWitness->rep_ == rmotion ||
397 cost.value() < closestWitness->rep_->accCost_.value()) // If the newly propagated state is a child of the
398 // new representative of the witness (previously had
399 // no rep) or it dominates the old representative's
400 // cost
401 {
402 Motion *oldRep = closestWitness->rep_; // Set a copy of the old representative
403 /* create a motion copy of the newly propagated state */
404 auto *motion = new Motion(siC_);
405
406 if (dMotion.size() > 1) // If collision occured during extension
407 {
408 nn_->add(collisionParentMotion);
409 }
410
411 motion = dMotion[0];
412 motion->accCost_ = cost;
413
414 nmotion->numChildren_++;
415 closestWitness->linkRep(motion); // Create new edge and set the new node as the representative
416
417 nn_->add(motion); // Add new node to tree
418 bool solved = pdef_->getGoal()->isSatisfied(motion->state, &dist_);
419
420 if (solved && motion->accCost_.value() < prevSolutionCost_.value()) // If the new state is a solution and
421 // it has a lower cost than the
422 // previous solution
423 {
424 approxdif = dist_;
425 solution = motion;
426
427 prevSolution_.clear();
428 Motion *solTrav = solution; // Traverse the solution and save the states in prevSolution_
429 while (solTrav != nullptr)
430 {
431 prevSolution_.push_back(solTrav);
432 solTrav = solTrav->parent;
433 }
434
435 prevSolutionCost_ = solution->accCost_;
436
437 OMPL_INFORM("Solution found with cost of %f", prevSolutionCost_.value());
438 solutions++;
439 if (solutions >= batchSize_)
440 break;
441 }
442 if (solution == nullptr && dist_ < approxdif) // If no solution found and distance to goal of this new
443 // state is closer than before (because no guarantee of
444 // probabilistic completeness). Also where approximate
445 // solutions are filled.
446 {
447 approxdif = dist_;
448 approxsol = motion;
449
450 prevSolution_.clear();
451 Motion *solTrav = approxsol;
452 while (solTrav != nullptr)
453 {
454 prevSolution_.push_back(solTrav);
455 solTrav = solTrav->parent;
456 }
457 prevSolutionCost_ = motion->accCost_;
458 }
459
460 if (oldRep != rmotion) // If the representative has changed (prune)
461 {
462 oldRep->inactive_ = true; // Mark the node as inactive
463 while (oldRep->inactive_ && oldRep->numChildren_ == 0) // While the current node is inactive and is a
464 // leaf, remove it (non-leaf nodes have been
465 // marked inactive)
466 {
467 Motion *oldRepParent = oldRep->parent;
468 oldRep = oldRepParent;
469 oldRep->numChildren_--;
470
471 if (oldRep->numChildren_ == 0)
472 oldRep->inactive_ =
473 true; // Now that its only child has been removed, this node is inactive as well
474 }
475 }
476 }
477 }
478
479 bool solved = false;
480 bool approximate = false;
481
482 if (solution == nullptr) // If closest state to goal is outside goal set
483 solution = approxsol;
484 else
485 solved = true;
486
487 if (approxdif != 0) // Approximate if not exactly the goal state
488 approximate = true;
489
490 if (solution != nullptr) // If any state has been successfully propagated
491 {
492 // Set the solution path
493 constructSolution(solution);
494 }
495
496 return {solved, approximate};
497}
498
500{
501 std::vector<Motion *> trajectory;
502 nn_->list(trajectory);
503 std::vector<Motion *> mpath;
504
505 double finalDistance = 0;
506 pdef_->getGoal()->isSatisfied(trajectory.back()->state, &finalDistance);
507
508 Motion *solution = last_motion;
509
510 int pathSize = 0;
511
512 // Construct the path from the goal to the start by following the parent pointers
513 while (solution != nullptr)
514 {
515 mpath.push_back(solution);
516 if (solution->solutionPair != nullptr) // A jump motion does not contain an edge
517 pathSize += solution->solutionPair->size() + 1; // +1 for the end state
518 solution = solution->parent;
519 }
520
521 // Create a new path object to store the solution path
522 auto path(std::make_shared<control::PathControl>(si_));
523
524 // Reserve space for the path states
525 path->getStates().reserve(pathSize);
526
527 // Add the states to the path in reverse order (from start to goal)
528 for (int i = mpath.size() - 1; i >= 0; --i)
529 {
530 // Append all intermediate states to the path, including starting state,
531 // excluding end vertex
532 if (mpath[i]->solutionPair != nullptr)
533 { // A jump motion does not contain an edge
534 for (unsigned int j = 0; j < mpath[i]->solutionPair->size(); j++)
535 {
536 if (i == 0 && j == 0) // Starting state has no control
537 {
538 path->append(mpath[i]->solutionPair->at(j));
539 continue;
540 }
541 path->append(mpath[i]->solutionPair->at(j), mpath[i]->control,
542 siC_->getPropagationStepSize()); // Need to make a new motion to append to trajectory
543 // matrix
544 }
545 }
546 else
547 { // If a jump motion
548 if (i == 0)
549 path->append(mpath[i]->state);
550 else
551 path->append(mpath[i]->state, mpath[i]->control, 0);
552 }
553 }
554
555 // Add the solution path to the problem definition
556 pdef_->addSolutionPath(path, finalDistance > 0.0, finalDistance, getName());
557 OMPL_INFORM("%s: Created %u states", getName().c_str(), nn_->size());
558
559 // Return a status indicating that an exact solution has been found
560 if (finalDistance > 0.0)
562 else
564}
565
567{
568 Planner::getPlannerData(data);
569
570 std::vector<Motion *> motions;
571 std::vector<Motion *> allMotions;
572 if (nn_)
573 nn_->list(motions);
574
575 for (auto &motion : motions)
576 if (motion->numChildren_ == 0)
577 allMotions.push_back(motion);
578 for (unsigned i = 0; i < allMotions.size(); i++)
579 if (allMotions[i]->getParent() != nullptr)
580 allMotions.push_back(allMotions[i]->getParent());
581
582 if (prevSolution_.size() != 0)
584
585 for (auto &allMotion : allMotions)
586 {
587 if (allMotion->getParent() == nullptr)
588 data.addStartVertex(base::PlannerDataVertex(allMotion->getState()));
589 else
590 data.addEdge(base::PlannerDataVertex(allMotion->getParent()->getState()),
591 base::PlannerDataVertex(allMotion->getState()));
592 }
593}
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:108
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:148
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:121
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:566
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:181
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:327
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:199
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:499
void randomSample(Motion *randomMotion)
Sample the random motion.
Definition HySST.cpp:322
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.