30 #include <Eigen/Dense> 41 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
48 virtual T
pos(
double t)
const = 0;
55 virtual T
vel(
double t)
const = 0;
62 virtual T
accel(
double t)
const = 0;
93 double arcLength(
double t_start,
double t_end)
const 95 struct GaussLengendreCoefficient
100 static constexpr GaussLengendreCoefficient coeffs[] = {{0.0, 128. / 225.},
101 {-0.53846931010568311, 0.47862867049936647},
102 {+0.53846931010568311, 0.47862867049936647},
103 {-0.90617984593866396, 0.23692688505618908},
104 {+0.90617984593866396, 0.23692688505618908}};
105 double a = (t_end - t_start) / 2.;
106 double b = (t_end + t_start) / 2.;
108 for(
auto coeff : coeffs)
110 length += coeff.w * this->
vel(a * coeff.t + b).norm();
130 constexpr
double PRECISION = 1e-3;
133 t_guess = t_start + 1.;
135 double l_guess =
arcLength(t_start, t_guess);
136 if(std::abs(l_guess - length) < PRECISION)
140 else if(l_guess < length)
157 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
170 CubicPolynomialBase(
const T & C0,
const T & C1,
const T & C2,
const T & C3) : C0_(C0), C1_(C1), C2_(C2), C3_(C3) {}
179 return C0_ + t * (C1_ + t * (C2_ + t * C3_));
189 return C1_ + t * (2 * C2_ + 3 * t * C3_);
199 return 2 * C2_ + 6 * t * C3_;
212 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
231 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
253 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
276 reset(initPos, initVel, targetPos, targetVel);
290 void reset(
const T & initPos,
const T & initVel,
const T & targetPos,
const T & targetVel)
294 targetPos_ = targetPos;
295 targetVel_ = targetVel;
306 void reset(
const T & initPos,
const T & targetPos)
309 initVel_ = this->zero();
310 targetPos_ = targetPos;
311 targetVel_ = this->zero();
320 this->C0_ = initPos_;
321 this->C1_ = initVel_;
322 this->C2_ = 3. * (targetPos_ - initPos_) - 2. * initVel_ - targetVel_;
323 this->C3_ = -2. * (targetPos_ - initPos_) + initVel_ + targetVel_;
342 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
355 T Delta = this->targetPos_ - this->initPos_;
356 double Delta_v0 = Delta.dot(this->initVel_);
357 double Delta_v1 = Delta.dot(this->targetVel_);
358 double v0_v0 = this->initVel_.dot(this->initVel_);
359 double v0_v1 = this->initVel_.dot(this->targetVel_);
360 double v1_v1 = this->targetVel_.dot(this->targetVel_);
361 double houbaInitVelScaling =
362 6. * (3. * Delta_v0 * v1_v1 - 2. * Delta_v1 * v0_v1) / (9. * v0_v0 * v1_v1 - 4. * v0_v1 * v0_v1);
363 if(houbaInitVelScaling < 0.)
365 houbaInitVelScaling *= -1.;
367 double houbaTargetVelScaling =
368 6. * (-2. * Delta_v0 * v0_v1 + 3. * Delta_v1 * v0_v0) / (9. * v0_v0 * v1_v1 - 4. * v0_v1 * v0_v1);
369 if(houbaTargetVelScaling < 0.)
371 houbaTargetVelScaling *= -1.;
373 this->initVel_ *= houbaInitVelScaling;
374 this->initVel_ *= extraInitVelScaling_;
375 this->targetVel_ *= houbaTargetVelScaling;
376 this->targetVel_ *= extraTargetVelScaling_;
385 return extraInitVelScaling_;
393 extraInitVelScaling_ = scaling;
401 return extraTargetVelScaling_;
409 extraTargetVelScaling_ = scaling;
413 double extraInitVelScaling_ = 1.0;
414 double extraTargetVelScaling_ = 1.0;
423 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
441 : C0_(C0), C1_(C1), C2_(C2), C3_(C3), C4_(C4), C5_(C5)
452 return C0_ + t * (C1_ + t * (C2_ + t * (C3_ + t * (C4_ + t * C5_))));
462 return C1_ + t * (2 * C2_ + t * (3 * C3_ + t * (4 * C4_ + t * 5 * C5_)));
472 return 2 * C2_ + t * (6 * C3_ + t * (12 * C4_ + t * 20 * C5_));
490 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
512 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
534 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
557 reset(initPos, initVel, targetPos, targetVel);
580 const T & targetAccel)
584 initAccel_ = initAccel;
585 targetPos_ = targetPos;
586 targetVel_ = targetVel;
587 targetAccel_ = targetAccel;
602 void reset(
const T & initPos,
const T & initVel,
const T & targetPos,
const T & targetVel)
606 initAccel_ = this->zero();
607 targetPos_ = targetPos;
608 targetVel_ = targetVel;
609 targetAccel_ = this->zero();
620 void reset(
const T & initPos,
const T & targetPos)
623 initVel_ = this->zero();
624 initAccel_ = this->zero();
625 targetPos_ = targetPos;
626 targetVel_ = this->zero();
627 targetAccel_ = this->zero();
636 auto Delta = targetPos_ - initPos_;
637 auto Sigma = initVel_ + targetVel_;
638 auto Gamma = 0.5 * (targetAccel_ - initAccel_);
639 auto kappa = initVel_ + 0.5 * initAccel_;
640 this->C0_ = initPos_;
641 this->C1_ = initVel_;
642 this->C2_ = 0.5 * initAccel_;
643 this->C3_ = 10 * Delta - 4 * Sigma + Gamma - 2 * kappa;
644 this->C4_ = -15 * Delta + 7 * Sigma - 2 * Gamma + kappa;
645 this->C5_ = 6 * Delta - 3 * Sigma + Gamma;
661 template<
template<
class>
class Polynomial,
typename T>
664 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
697 void reset(
const T & initPos,
const T & targetPos,
double duration)
699 duration_ = duration;
700 poly_.reset(initPos, targetPos);
716 void reset(
const T & initPos,
const T & initVel,
const T & targetPos,
const T & targetVel,
double duration)
718 duration_ = duration;
719 poly_.reset(initPos, duration * initVel, targetPos, duration * targetVel);
744 const T & targetAccel,
747 duration_ = duration;
748 double duration2 = duration * duration;
749 poly_.reset(initPos, duration * initVel, duration2 * initAccel, targetPos, duration * targetVel,
750 duration2 * targetAccel);
756 double s(
double t)
const 758 return (t < 0.) ? 0. : (t > duration_) ? 1. : t / duration_;
765 double sd(
double t)
const 767 return (t < 0.) ? 0. : (t > duration_) ? 0. : 1. / duration_;
777 return poly_.pos(s(t));
787 return sd(t) * poly_.vel(s(t));
797 return std::pow(sd(t), 2) * poly_.accel(s(t));
Hermite polynomial with Overall Uniformly-Bounded Accelerations (HOUBA).
double extraTargetVelScaling()
Get extra target velocity scaling.
void reset(const T &initPos, const T &targetPos)
Reset boundaries with zero tangents.
void reset(const T &initPos, const T &targetPos, double duration)
Reset duration and boundary positions.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW T zero()
Return T's zero.
void reset(const T &initPos, const T &initVel, const T &targetPos, const T &targetVel)
Reset boundaries with zero boundary velocities.
T vel(double t) const
Velocity along the retimed trajectory.
QuinticPolynomial()
Empty constructor.
void reset(const T &initPos, const T &targetPos)
Reset boundaries with zero tangents.
void reset()
Reset underlying cubic polynomial coefficients.
T vel(double t) const
Get the value of the first-order derivative (velocity) at time t.
T accel(double t) const
Acceleration along the retimed trajectory.
QuinticPolynomial()
Empty constructor.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW CubicPolynomialBase(const T &C0, const T &C1, const T &C2, const T &C3)
Build a new curve from its monomial vector coefficients.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW QuinticPolynomialBase(const T &C0, const T &C1, const T &C2, const T &C3, const T &C4, const T &C5)
Build a new curve from its monomial vector coefficients.
T vel(double t) const
Get the value of the first-order derivative (velocity) at time t.
RetimedPolynomial(Polynomial< T > poly, double duration)
Constructor.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW RetimedPolynomial()
Empty constructor.
T accel(double t) const
Get the value of the second-order derivative (acceleration) at time t.
Cubic Hermite polynomial.
virtual void reset()
Reset underlying cubic polynomial coefficients.
double duration() const
Get trajectory duration.
double extraInitVelScaling()
Get extra initial velocity scaling.
CubicPolynomial()
Empty constructor.
T pos(double t) const
Get the value of the polynomial at time t.
void reset(const T &initPos, const T &initVel, const T &targetPos, const T &targetVel)
Reset boundaries.
Quintic polynomial over vectors.
virtual EIGEN_MAKE_ALIGNED_OPERATOR_NEW T pos(double t) const =0
Get the value of the polynomial at time t.
Quintic polynomial with zero velocity and zero acceleration at 0 and 1.
CubicPolynomial()
Empty constructor.
void extraTargetVelScaling(double scaling)
Add extra target velocity scaling to the HOUBA one.
Polynomial whose argument is retimed to by .
T pos(double t) const
Position along the retimed trajectory.
double arcLengthInverse(double t_start, double length, double t_guess=-1.) const
Inverse of the arc length function.
T accel(double t) const
Get the value of the second-order derivative (acceleration) at time t.
virtual T accel(double t) const =0
Get the value of the second-order derivative (acceleration) at time t.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW double zero()
Zero function used for double specialization.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW QuinticHermitePolynomial()
Empty constructor.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW T zero()
Return T's zero.
double arcLength(double t_start, double t_end) const
Compute the arc length between two points of the polynomial curve.
QuinticHermitePolynomial(const T &initPos, const T &initVel, const T &targetPos, const T &targetVel)
Build a new cubic Hermite polynomial.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW CubicHermitePolynomial()
Empty constructor.
void reset(const T &initPos, const T &initVel, const T &targetPos, const T &targetVel, double duration)
Reset duration and boundary positions and velocities.
Utility functions and classes.
double s(double t) const
Mapping from to .
virtual T vel(double t) const =0
Get the value of the first-order derivative (velocity) at time t.
void reset(const T &initPos, const T &initVel, const T &initAccel, const T &targetPos, const T &targetVel, const T &targetAccel, double duration)
Reset duration and boundary positions, velocities and accelerations.
void extraInitVelScaling(double scaling)
Add extra initial velocity scaling to the HOUBA one.
T tangent(double t) const
Get the value of the tangent vector at time t.
CubicHermitePolynomial(const T &initPos, const T &initVel, const T &targetPos, const T &targetVel)
Build a new cubic Hermite polynomial.
void reset(const T &initPos, const T &initVel, const T &initAccel, const T &targetPos, const T &targetVel, const T &targetAccel)
Reset boundary values.
T pos(double t) const
Get the value of the polynomial at time t.
void reset() override
Rescale boundary velocities, then reset as Hermite polynomial.
double sd(double t) const
Mapping from to .
EIGEN_MAKE_ALIGNED_OPERATOR_NEW double zero()
Zero function used for double specialization.