10#include "wpi/units/math.hpp"
11#include "wpi/units/time.hpp"
45template <
class Distance>
50 wpi::units::compound_unit<Distance,
51 wpi::units::inverse<wpi::units::seconds>>;
55 wpi::units::inverse<wpi::units::seconds>>;
73 if (!std::is_constant_evaluated()) {
87 if (!std::is_constant_evaluated()) {
92 throw std::domain_error(
"Constraints must be non-negative");
117 : m_constraints(constraints) {}
135 m_direction = ShouldFlipAcceleration(current, goal) ? -1 : 1;
136 m_current = Direct(current);
138 if (wpi::units::math::abs(m_current.velocity) > m_constraints.maxVelocity) {
139 m_current.velocity = wpi::units::math::copysign(m_constraints.maxVelocity,
146 wpi::units::second_t cutoffBegin =
147 m_current.velocity / m_constraints.maxAcceleration;
149 cutoffBegin * cutoffBegin * m_constraints.maxAcceleration / 2.0;
151 wpi::units::second_t cutoffEnd =
152 goal.
velocity / m_constraints.maxAcceleration;
154 cutoffEnd * cutoffEnd * m_constraints.maxAcceleration / 2.0;
160 cutoffDistBegin + (goal.
position - m_current.position) + cutoffDistEnd;
161 wpi::units::second_t accelerationTime =
162 m_constraints.maxVelocity / m_constraints.maxAcceleration;
166 accelerationTime * accelerationTime * m_constraints.maxAcceleration;
170 accelerationTime = wpi::units::math::sqrt(fullTrapezoidDist /
171 m_constraints.maxAcceleration);
175 m_endAccel = accelerationTime - cutoffBegin;
177 m_endAccel + fullVelocityDist / m_constraints.maxVelocity;
178 m_endDecel = m_endFullVelocity + accelerationTime - cutoffEnd;
179 State result = m_current;
181 if (t < m_endAccel) {
182 result.
velocity += t * m_constraints.maxAcceleration;
184 (m_current.velocity + t * m_constraints.maxAcceleration / 2.0) * t;
185 }
else if (t < m_endFullVelocity) {
186 result.
velocity = m_constraints.maxVelocity;
187 result.
position += (m_current.velocity +
188 m_endAccel * m_constraints.maxAcceleration / 2.0) *
190 m_constraints.maxVelocity * (t - m_endAccel);
191 }
else if (t <= m_endDecel) {
193 goal.
velocity + (m_endDecel - t) * m_constraints.maxAcceleration;
194 wpi::units::second_t timeLeft = m_endDecel - t;
197 (goal.
velocity + timeLeft * m_constraints.maxAcceleration / 2.0) *
203 return Direct(result);
214 Distance_t position = m_current.position * m_direction;
215 Velocity_t velocity = m_current.velocity * m_direction;
217 wpi::units::second_t endAccel = m_endAccel * m_direction;
218 wpi::units::second_t endFullVelocity =
219 m_endFullVelocity * m_direction - endAccel;
221 if (target < position) {
223 endFullVelocity *= -1.0;
227 endAccel = wpi::units::math::max(endAccel, 0_s);
228 endFullVelocity = wpi::units::math::max(endFullVelocity, 0_s);
230 const Acceleration_t acceleration = m_constraints.maxAcceleration;
231 const Acceleration_t deceleration = -m_constraints.maxAcceleration;
233 Distance_t distToTarget = wpi::units::math::abs(target - position);
240 velocity * endAccel + 0.5 * acceleration * endAccel * endAccel;
243 if (endAccel > 0_s) {
244 decelVelocity = wpi::units::math::sqrt(wpi::units::math::abs(
245 velocity * velocity + 2 * acceleration * accelDist));
247 decelVelocity = velocity;
250 Distance_t fullVelocityDist = m_constraints.maxVelocity * endFullVelocity;
253 if (accelDist > distToTarget) {
254 accelDist = distToTarget;
257 }
else if (accelDist + fullVelocityDist > distToTarget) {
258 fullVelocityDist = distToTarget - accelDist;
261 decelDist = distToTarget - fullVelocityDist - accelDist;
264 wpi::units::second_t accelTime =
265 (-velocity + wpi::units::math::sqrt(wpi::units::math::abs(
266 velocity * velocity + 2 * acceleration * accelDist))) /
269 wpi::units::second_t decelTime =
271 wpi::units::math::sqrt(wpi::units::math::abs(
272 decelVelocity * decelVelocity + 2 * deceleration * decelDist))) /
275 wpi::units::second_t fullVelocityTime =
276 fullVelocityDist / m_constraints.maxVelocity;
278 return accelTime + fullVelocityTime + decelTime;
287 constexpr wpi::units::second_t
TotalTime()
const {
return m_endDecel; }
311 static constexpr bool ShouldFlipAcceleration(
const State& initial,
313 return initial.position > goal.position;
317 constexpr State Direct(
const State& in)
const {
319 result.position *= m_direction;
320 result.velocity *= m_direction;
327 Constraints m_constraints;
330 wpi::units::second_t m_endAccel = 0_s;
331 wpi::units::second_t m_endFullVelocity = 0_s;
332 wpi::units::second_t m_endDecel = 0_s;
static void ReportUsage(std::string_view resource, std::string_view data)
Definition MathShared.hpp:61
Profile constraints.
Definition TrapezoidProfile.hpp:61
constexpr Constraints(Velocity_t maxVelocity, Acceleration_t maxAcceleration)
Constructs constraints for a Trapezoid Profile.
Definition TrapezoidProfile.hpp:84
Velocity_t maxVelocity
Maximum velocity.
Definition TrapezoidProfile.hpp:64
Acceleration_t maxAcceleration
Maximum acceleration.
Definition TrapezoidProfile.hpp:67
constexpr Constraints()
Default constructor.
Definition TrapezoidProfile.hpp:72
Profile state.
Definition TrapezoidProfile.hpp:100
Distance_t position
The position at this state.
Definition TrapezoidProfile.hpp:103
Velocity_t velocity
The velocity at this state.
Definition TrapezoidProfile.hpp:106
constexpr bool operator==(const State &) const =default
constexpr bool IsFinished(wpi::units::second_t t) const
Returns true if the profile has reached the goal.
Definition TrapezoidProfile.hpp:298
wpi::units::unit_t< Acceleration > Acceleration_t
Definition TrapezoidProfile.hpp:56
wpi::units::unit_t< Velocity > Velocity_t
Definition TrapezoidProfile.hpp:52
constexpr TrapezoidProfile(const TrapezoidProfile &)=default
constexpr TrapezoidProfile(Constraints constraints)
Constructs a TrapezoidProfile.
Definition TrapezoidProfile.hpp:116
wpi::units::compound_unit< Velocity, wpi::units::inverse< wpi::units::seconds > > Acceleration
Definition TrapezoidProfile.hpp:53
constexpr wpi::units::second_t TotalTime() const
Returns the total time the profile takes to reach the goal.
Definition TrapezoidProfile.hpp:287
constexpr State Calculate(wpi::units::second_t t, State current, State goal)
Calculates the position and velocity for the profile at a time t where the current state is at time t...
Definition TrapezoidProfile.hpp:134
constexpr TrapezoidProfile & operator=(const TrapezoidProfile &)=default
wpi::units::compound_unit< Distance, wpi::units::inverse< wpi::units::seconds > > Velocity
Definition TrapezoidProfile.hpp:49
constexpr wpi::units::second_t TimeLeftUntil(Distance_t target) const
Returns the time left until a target distance in the profile is reached.
Definition TrapezoidProfile.hpp:213
constexpr TrapezoidProfile & operator=(TrapezoidProfile &&)=default
constexpr TrapezoidProfile(TrapezoidProfile &&)=default
wpi::units::unit_t< Distance > Distance_t
Definition TrapezoidProfile.hpp:48
Definition LinearSystem.hpp:20