mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-08-18 18:04:12 +08:00
102 lines
2.7 KiB
C++
102 lines
2.7 KiB
C++
#include "odrive_main.h"
|
|
#include <math.h>
|
|
|
|
// Standard sign function, implemented to match the Python impelmentation
|
|
template <typename T>
|
|
int sign(T val) {
|
|
if (val == T(0))
|
|
return T(0);
|
|
else
|
|
return (std::signbit(val)) ? -1 : 1;
|
|
}
|
|
|
|
TrapezoidalTrajectory::TrapezoidalTrajectory(){};
|
|
|
|
float TrapezoidalTrajectory::planTrapezoidal(float Xf, float Xi,
|
|
float Vi, float Vmax,
|
|
float Amax, float Dmax) {
|
|
float dx_stop = (Vi * Vi) / (Dmax * 2.0f);
|
|
float dX = Xf - Xi;
|
|
int s = sign(dX);
|
|
|
|
float Ar = s * Amax; // Maximum Acceleration (signed)
|
|
float Dr = -1.0f * s * Dmax; // Maximum Deceleration (signed)
|
|
float Vr = s * Vmax; // Maximum Velocity (signed)
|
|
|
|
float Ta;
|
|
float Tv;
|
|
float Td;
|
|
|
|
// Checking for overshoot on "minimum stop"
|
|
if (fabs(dX) <= dx_stop) {
|
|
Ta = 0;
|
|
Tv = 0;
|
|
Vr = Vi;
|
|
Dr = -1.0f * sign(Vi) * Dmax;
|
|
Td = fabs(Vi) / Dmax;
|
|
} else {
|
|
// Handle the case where initial velocity > Max velocity
|
|
if ((s * Vi) > (s * Vr)) {
|
|
Ar = -1.0f * s * Amax;
|
|
}
|
|
|
|
Ta = (Vr - Vi) / Ar; // Acceleration time
|
|
Td = (-Vr) / Dr; // Deceleration time
|
|
|
|
// Peak Velocity handling
|
|
float dXmin = Ta*(Vr + Vi)/2.0f + Td*Vr/2.0f;
|
|
|
|
// Short move handling
|
|
if (fabs(dX) < fabs(dXmin)) {
|
|
Vr = s*sqrt((-((Vi*Vi)/Ar)-2.0f*dX)/(1.0f/Dr-1.0f/Ar));
|
|
Ta = std::max(0.0f, (Vr - Vi) / Ar);
|
|
Tv = 0;
|
|
Td = std::max(0.0f, -Vr / Dr);
|
|
} else {
|
|
Tv = (dX - dXmin) / Vr;
|
|
}
|
|
}
|
|
|
|
// Populate object's values
|
|
|
|
Xf_ = Xf;
|
|
Xi_ = Xi;
|
|
Vi_ = Vi;
|
|
|
|
Ar_ = Ar;
|
|
Dr_ = Dr;
|
|
Vr_ = Vr;
|
|
|
|
Ta_ = Ta;
|
|
Tv_ = Tv;
|
|
Td_ = Td;
|
|
|
|
yAccel_ = (Ar * Ta * Ta) / 2.0f + (Vi * Ta) + Xi;
|
|
Tav_ = Ta + Tv;
|
|
|
|
return Ta + Tv + Td;
|
|
}
|
|
|
|
TrajectoryStep_t TrapezoidalTrajectory::evalTrapTraj(float t) {
|
|
TrajectoryStep_t trajStep;
|
|
if (t < 0.0f) { // Initial Conditions
|
|
trajStep.Y = Xi_;
|
|
trajStep.Yd = Vi_;
|
|
trajStep.Ydd = Ar_;
|
|
} else if (t < Ta_) { // Accelerating
|
|
trajStep.Y = (Ar_ * (t * t)/ 2.0f) + (Vi_ * t) + Xi_;
|
|
trajStep.Yd = (Ar_ * t) + Vi_;
|
|
trajStep.Ydd = Ar_;
|
|
} else if (t < Ta_ + Tv_) { // Coasting
|
|
trajStep.Y = yAccel_ + (Vr_ * (t - Ta_));
|
|
trajStep.Yd = Vr_;
|
|
trajStep.Ydd = 0;
|
|
} else if (t < Ta_ + Tv_ + Td_) { // Deceleration
|
|
float Tdc = t - Tav_;
|
|
trajStep.Y = yAccel_ + (Vr_ * (t - Ta_)) + Dr_ * (Tdc * Tdc) / 2.0f;
|
|
trajStep.Yd = Vr_ + Dr_ * Tdc;
|
|
trajStep.Ydd = Dr_;
|
|
}
|
|
|
|
return trajStep;
|
|
} |