37#include "CommonMath/Trajectory.h"
38#include "CommonMath/RectPrism.h"
41#include "CommonMath/RectPrism.h"
42#include "CommonMath/ConvexObj.h"
44#include "ompl/control/planners/sst/HySST.h"
45#include "ompl/base/GoalTypes.h"
46#include "ompl/base/Planner.h"
47#include "ompl/base/spaces/RealVectorStateSpace.h"
48#include "ompl/control/PathControl.h"
49#include "ompl/control/SpaceInformation.h"
50#include "ompl/control/ODESolver.h"
51#include "ompl/base/goals/GoalRegion.h"
59 CollisionIndeterminable = 2,
62struct DetailedCollisionResult
64 CollisionResult collisionType;
74std::shared_ptr<CommonMath::RectPrism> leftRectPrism = std::make_shared<CommonMath::RectPrism>((leftRect));
75std::shared_ptr<CommonMath::RectPrism> topRectPrism = std::make_shared<CommonMath::RectPrism>((topRect));
76std::shared_ptr<CommonMath::RectPrism> bottomRectPrism = std::make_shared<CommonMath::RectPrism>((bottomRect));
79DetailedCollisionResult polyCollisionChecker(
double ts,
double tf, std::shared_ptr<CommonMath::ConvexObj> obstacle,
80 double minTimeSection,
unsigned iterationNumber,
83 DetailedCollisionResult testResult;
86 double midTime = (ts + tf) / 2.0;
89 if (obstacle->IsPointInside(midpoint))
91 if ((tf - ts) <= minTimeSection)
94 testResult.collisionType = Collision;
95 testResult.collisionTime = ts;
101 unsigned nextIterationNumber = iterationNumber + 1;
102 DetailedCollisionResult firstHalfResult =
103 polyCollisionChecker(ts, midTime, obstacle, minTimeSection, nextIterationNumber, _traj);
104 DetailedCollisionResult secondHalfResult =
105 polyCollisionChecker(midTime, tf, obstacle, minTimeSection, nextIterationNumber, _traj);
109 if (firstHalfResult.collisionType != NoCollision)
110 return firstHalfResult;
112 return secondHalfResult;
116 if (tf - ts < minTimeSection)
119 testResult.collisionType = CollisionIndeterminable;
120 testResult.collisionTime = ts;
125 if (obstacle->IsPointInside(endPoint))
128 DetailedCollisionResult firstHalfResult;
129 unsigned nextIterationNumber = iterationNumber + 1;
130 firstHalfResult = polyCollisionChecker(ts, midTime, obstacle, minTimeSection, nextIterationNumber, _traj);
131 if (firstHalfResult.collisionType != NoCollision)
132 return firstHalfResult;
136 unsigned nextIterationNumber = iterationNumber + 1;
137 return polyCollisionChecker(midTime, tf, obstacle, minTimeSection, nextIterationNumber, _traj);
146 double c[5] = {0, 0, 0, 0, 0};
148 for (
unsigned dim = 0; dim < 3; dim++)
150 c[0] += tangentPlane.
normal[dim] * trajDerivativeCoeffs[0][dim];
151 c[1] += tangentPlane.
normal[dim] * trajDerivativeCoeffs[1][dim];
152 c[2] += tangentPlane.
normal[dim] * trajDerivativeCoeffs[2][dim];
153 c[3] += tangentPlane.
normal[dim] * trajDerivativeCoeffs[3][dim];
154 c[4] += tangentPlane.
normal[dim] * trajDerivativeCoeffs[4][dim];
160 if (fabs(c[0]) >
double(1e-6))
161 rootCount = Quartic::solve_quartic(c[1] / c[0], c[2] / c[0], c[3] / c[0], c[4] / c[0], roots);
163 rootCount = Quartic::solveP3(c[2] / c[1], c[3] / c[1], c[4] / c[1], roots);
165 std::sort(roots, roots + rootCount);
169 std::vector<double> testPointsLow;
170 std::vector<double> testPointsHigh;
171 testPointsLow.reserve(6);
172 testPointsHigh.reserve(6);
173 testPointsLow.push_back(ts);
174 testPointsHigh.push_back(midTime);
175 for (
unsigned int i = 0; i < rootCount; i++)
179 else if (roots[i] < midTime)
180 testPointsLow.push_back(roots[i]);
181 else if (roots[i] < tf)
182 testPointsHigh.push_back(roots[i]);
186 testPointsLow.push_back(midTime);
187 testPointsHigh.push_back(tf);
191 for (
typename std::vector<double>::reverse_iterator it = testPointsLow.rbegin() + 1; it != testPointsLow.rend();
202 DetailedCollisionResult lowTestPointsResult;
203 lowTestPointsResult = polyCollisionChecker(ts, *(it - 1), obstacle, minTimeSection, iterationNumber, _traj);
204 if (lowTestPointsResult.collisionType == NoCollision)
207 return lowTestPointsResult;
211 for (
typename std::vector<double>::iterator it = testPointsHigh.begin() + 1; it != testPointsHigh.end(); it++)
219 DetailedCollisionResult highTestPointsResult;
220 unsigned nextIterationNumber = iterationNumber + 1;
221 highTestPointsResult =
222 polyCollisionChecker(*(it - 1), tf, obstacle, minTimeSection, nextIterationNumber, _traj);
223 if (highTestPointsResult.collisionType ==
229 return highTestPointsResult;
234 testResult.collisionType = NoCollision;
235 testResult.collisionTime = 100000;
240Trajectory polyFit3D(std::vector<std::vector<double>> states, std::vector<double> tValues)
242 Eigen::VectorXd yValues(states.size());
243 Eigen::VectorXd xValues(states.size());
244 Eigen::VectorXd xCoeffs(5);
245 Eigen::VectorXd yCoeffs(5);
246 Eigen::VectorXd zCoeffs(5);
248 for (
unsigned rows = 0; rows < states.size(); rows++)
250 xValues[rows] = states[rows][0];
251 yValues[rows] = states[rows][1];
254 xCoeffs = polyfit_Eigen(tValues, xValues, 5);
255 yCoeffs = polyfit_Eigen(tValues, yValues, 5);
257 std::vector<Vec3> coeffs;
259 for (
int i = 5; i >= 0; i--)
260 coeffs.push_back(
Vec3(xCoeffs.coeffRef(i), yCoeffs.coeffRef(i), zCoeffs.coeffRef(i)));
262 Trajectory traj(coeffs, tValues.front(), tValues.back());
269 for (
int i = 0; i < 6; i++)
280 return fabs(sqrt(distSqr));
283bool collisionregion1(
double x1,
double x2)
285 return x1 <= 4.5 && x1 >= 0.5 && x2 >= 1 && x2 <= 1.5;
288bool collisionregion2(
double x1,
double x2)
290 return x1 <= 4.5 && x1 >= 0.5 && x2 >= 1.4 && x2 <= 1.5;
293bool collisionregion3(
double x1,
double x2)
295 return x1 <= 4.5 && x1 >= 0.5 && x2 >= 2.5 && x2 <= 3.0;
298bool collisionregion4(
double x1,
double x2)
300 return x1 <= 4.5 && x1 >= 0.5 && x2 >= 2.9 && x2 <= 3;
303bool collisionregion5(
double x1,
double x2)
305 return x1 <= 0.5 && x1 >= 0.0 && x2 >= 1.5 && x2 <= 2.5;
308bool collisionregion6(
double x1,
double x2)
310 return x1 <= 4.5 && x1 >= 4.4 && x2 >= 1 && x2 <= 1.5;
313bool collisionregion7(
double x1,
double x2)
315 return x1 <= 4.5 && x1 >= 4.4 && x2 >= 2.5 && x2 <= 3;
318bool Xu(
double x1,
double x2)
320 if (x1 <= 4.4 && x1 >= 0 && x2 >= 1.1 && x2 <= 1.4)
322 if (x1 <= 0.4 && x1 >= 0 && x2 >= 1.1 && x2 <= 2.9)
324 if (x1 <= 4.4 && x1 >= 0 && x2 >= 2.6 && x2 <= 2.9)
333 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
336 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
341 if (Xu(x1, x2) || collisionregion1(x1, x2) || collisionregion2(x1, x2) || collisionregion3(x1, x2) ||
342 collisionregion4(x1, x2) || collisionregion5(x1, x2) || collisionregion6(x1, x2) || collisionregion7(x1, x2))
351 return !jumpSet(motion);
358 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
361 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
364 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
367 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
369 if (x_cur[0] < 0.5 || x_cur[0] > 6 || x_cur[1] < 0 || x_cur[1] > 7)
381 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
384 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
387 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
390 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
395 double vn, vt, vnplus, vtplus;
397 if (collisionregion1(x1, x2) || collisionregion2(x1, x2) || collisionregion3(x1, x2) || collisionregion4(x1, x2))
402 vtplus = vt + kappa * (-e - 1) * std::atan(vt / vn) * vn;
411 vtplus = vt + kappa * (-e - 1) * std::atan(vt / vn) * vn;
417 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
420 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
423 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
426 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
429 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
432 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
445 ->as<ompl::base::HybridTimeStateSpace::StateType>(1)
448 ->as<ompl::base::HybridTimeStateSpace::StateType>(1)
450 std::vector<std::vector<double>> *propStepStatesDouble =
new std::vector<std::vector<double>>();
451 for (
unsigned int i = 0; i < motion->
solutionPair->size(); i++)
453 std::vector<double> row;
454 for (
int j = 0; j < 6; j++)
459 propStepStatesDouble->push_back(row);
462 std::vector<double> tValues;
463 for (
unsigned int i = 0; i < motion->
solutionPair->size(); i++)
471 if (tValues.front() == tValues.back())
474 ts = tValues.front();
477 Trajectory _traj = polyFit3D(*propStepStatesDouble, tValues);
479 DetailedCollisionResult leftCollisionResult = polyCollisionChecker(ts, tf, leftRectPrism, 1e-03, 0, _traj);
480 DetailedCollisionResult topCollisionResult = polyCollisionChecker(ts, tf, topRectPrism, 1e-03, 0, _traj);
481 DetailedCollisionResult bottomCollisionResult = polyCollisionChecker(ts, tf, bottomRectPrism, 1e-03, 0, _traj);
483 DetailedCollisionResult trueCollisionResult;
486 if (leftCollisionResult.collisionType == Collision)
487 trueCollisionResult = leftCollisionResult;
488 else if (topCollisionResult.collisionType == Collision)
489 trueCollisionResult = topCollisionResult;
490 else if (bottomCollisionResult.collisionType == Collision)
491 trueCollisionResult = bottomCollisionResult;
497 bool collision = run && trueCollisionResult.collisionType == Collision;
498 std::vector<double> collision_point;
502 Vec3 collision_point = _traj.
GetValue(trueCollisionResult.collisionTime);
504 collision_vel_coeffs.insert(collision_vel_coeffs.begin(),
Vec3(0.0, 0.0, 0.0));
505 Trajectory _deriv_traj(collision_vel_coeffs, ts, tf);
506 Vec3 vel_collision_point = _deriv_traj.GetValue(trueCollisionResult.collisionTime);
510 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
511 ->values[0] = collision_point[0];
513 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
514 ->values[1] = collision_point[1];
516 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
517 ->values[2] = vel_collision_point[0];
519 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
520 ->values[3] = vel_collision_point[1];
521 *collisionTime = trueCollisionResult.collisionTime;
523 return collision && run;
533 const double u_1 = input[0];
534 const double u_2 = input[1];
537 const double v_1 = x_cur[2];
538 const double v_2 = x_cur[3];
539 const double a_1 = x_cur[4];
540 const double a_2 = x_cur[5];
543 x_new.resize(x_cur.size(), 0);
557 EuclideanGoalRegion(
const ompl::base::SpaceInformationPtr &si) : ompl::base::Goal(si)
561 virtual bool isSatisfied(
const ompl::base::State *st,
double *distance)
const
564 std::vector<double> goal = {5, 4};
566 for (
int i = 0; i < 2; i++)
574 *distance = sqrt(distSqr);
582 virtual bool isSatisfied(
const ompl::base::State *st)
const
584 double distance = 0.0;
585 return isSatisfied(st, &distance);
600 ompl::base::StateSpacePtr stateSpacePtr(statespace);
602 ompl::base::StateSpacePtr hybridSpacePtr(hybridSpace);
611 flowBounds.setLow(0, -0.5);
612 flowBounds.setLow(1, -1);
613 flowBounds.setHigh(0, 1);
614 flowBounds.setHigh(1, 1);
618 jumpBounds.setLow(0, 0);
619 jumpBounds.setLow(0, 0);
620 jumpBounds.setHigh(0, 0);
621 jumpBounds.setHigh(0, 0);
627 {
return std::make_shared<ompl::control::RealVectorControlUniformSampler>(space); });
634 {
return std::make_shared<ompl::control::RealVectorControlUniformSampler>(space); });
636 ompl::control::ControlSpacePtr flowControlSpacePtr(flowControlSpace);
637 ompl::control::ControlSpacePtr jumpControlSpacePtr(jumpControlSpace);
643 ompl::control::ControlSpacePtr controlSpacePtr(controlSpace);
650 si->setPropagationStepSize(0.05);
651 si->setMinMaxControlDuration(1, 1);
658 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
661 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
664 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
667 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
670 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
673 ->as<ompl::base::RealVectorStateSpace::StateType>(0)
676 std::shared_ptr<EuclideanGoalRegion> goal = std::make_shared<EuclideanGoalRegion>(si);
682 pdef->addStartState(start);
688 cHySST.setProblemDefinition(pdef);
690 cHySST.setDistanceFunction(distanceFunc);
691 cHySST.setDiscreteSimulator(discreteSimulator);
692 cHySST.setFlowSet(flowSet);
693 cHySST.setJumpSet(jumpSet);
695 cHySST.setFlowStepDuration(0.05);
696 cHySST.setUnsafeSet(unsafeSet);
697 cHySST.setCollisionChecker(collisionChecker);
698 cHySST.setSelectionRadius(0.2);
699 cHySST.setPruningRadius(0.1);
700 cHySST.setBatchSize(1);
708 OMPL_INFORM(
"Solution found in %f seconds", planTime);
Represents a qunitic polynomial in 3D.
Vec3 GetValue(double t) const
Returns the 3D position of the polynomial at a given time.
std::vector< Vec3 > GetDerivativeCoeffs() const
Returns the coefficient of the time derivative of the trajectory.
3D vector class with common vector operations.
Abstract definition of goals.
A state space consisting of a space and a time component.
The definition of a time state.
double position
The position in time.
Definition of a problem to be solved. This includes the start state(s) for the system and a goal spec...
The lower and upper bounds for an Rn space.
The definition of a state in Rn.
double * values
The value of the actual vector in Rn.
A state space representing Rn. The distance function is the L2 norm.
void addDimension(double minBound=0.0, double maxBound=0.0)
Increase the dimensionality of the state space by 1. Optionally, bounds can be specified for this add...
Definition of a scoped state.
ompl::base::State StateType
Define the type of state allocated by this space.
Definition of an abstract state.
const T * as() const
Cast this instance to a desired type.
A control space to allow the composition of control spaces.
virtual void addSubspace(const ControlSpacePtr &component)
Adds a control space as a component of the compound control space.
A control space representing the space of applicable controls.
void setControlSamplerAllocator(const ControlSamplerAllocator &csa)
Set the sampler allocator to use.
Definition of an abstract control.
const T * as() const
Cast this instance to a desired type.
Representation of a motion.
std::vector< base::State * > * solutionPair
The integration steps defining the edge of the motion, between the parent and child vertices.
base::State * state
The state contained by the motion.
Basic solver for ordinary differential equations of the type q' = f(q, u), where q is the current sta...
std::vector< double > StateType
Portable data type for the state values.
static StatePropagatorPtr getStatePropagator(ODESolverPtr solver, const PostPropagationEvent &postEvent=nullptr)
Retrieve a StatePropagator object that solves a system of ordinary differential equations defined by ...
Definition of a control path.
The definition of a control in Rn.
A control space representing Rn.
void setBounds(const base::RealVectorBounds &bounds)
Set the bounds (min max values for each dimension) for the control.
#define OMPL_INFORM(fmt,...)
Log a formatted information string.
PlannerTerminationCondition timedPlannerTerminationCondition(double duration)
Return a termination condition that will become true duration seconds in the future (wall-time).
std::chrono::system_clock::time_point point
Representation of a point in time.
point now()
Get the current time point.
duration seconds(double sec)
Return the time duration representing a given number of seconds.
A struct defining the properties of a plane.
Vec3 point
A point on the plane.
Vec3 normal
A unit vector normal to the plane.
A class to store the exit status of Planner::solve().
std::string asString() const
Return a string representation.