WPILibC++ 2024.3.2
ExponentialProfile.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include "units/time.h"
9
10namespace frc {
11
12/**
13 * A Exponential-shaped velocity profile.
14 *
15 * While this class can be used for a profiled movement from start to finish,
16 * the intended usage is to filter a reference's dynamics based on
17 * ExponentialProfile velocity constraints. To compute the reference obeying
18 * this constraint, do the following.
19 *
20 * Initialization:
21 * @code{.cpp}
22 * ExponentialProfile::Constraints constraints{kMaxV, kV, kA};
23 * State previousProfiledReference = {initialReference, 0_mps};
24 * @endcode
25 *
26 * Run on update:
27 * @code{.cpp}
28 * previousProfiledReference = profile.Calculate(timeSincePreviousUpdate,
29 * previousProfiledReference, unprofiledReference);
30 * @endcode
31 *
32 * where `unprofiledReference` is free to change between calls. Note that when
33 * the unprofiled reference is within the constraints, `Calculate()` returns the
34 * unprofiled reference unchanged.
35 *
36 * Otherwise, a timer can be started to provide monotonic values for
37 * `Calculate()` and to determine when the profile has completed via
38 * `IsFinished()`.
39 */
40template <class Distance, class Input>
42 public:
44 using Velocity =
51 using B_t =
57
58 /**
59 * Profile timing.
60 */
62 public:
63 /// Profile inflection time.
64 units::second_t inflectionTime;
65
66 /// Total profile time.
67 units::second_t totalTime;
68
69 /**
70 * Decides if the profile is finished by time t.
71 *
72 * @param t The time since the beginning of the profile.
73 * @return if the profile is finished at time t.
74 */
75 bool IsFinished(const units::second_t& t) const { return t >= totalTime; }
76 };
77
78 /**
79 * Profile constraints.
80 */
82 public:
83 /**
84 * Constructs constraints for an ExponentialProfile.
85 *
86 * @param maxInput maximum unsigned input voltage
87 * @param A The State-Space 1x1 system matrix.
88 * @param B The State-Space 1x1 input matrix.
89 */
91 : maxInput{maxInput}, A{A}, B{B} {}
92
93 /**
94 * Constructs constraints for an ExponentialProfile from characteristics.
95 *
96 * @param maxInput maximum unsigned input voltage
97 * @param kV The velocity gain.
98 * @param kA The acceleration gain.
99 */
101 : maxInput{maxInput}, A{-kV / kA}, B{1 / kA} {}
102
103 /**
104 * Computes the max achievable velocity for an Exponential Profile.
105 *
106 * @return The seady-state velocity achieved by this profile.
107 */
108 Velocity_t MaxVelocity() const { return -maxInput * B / A; }
109
110 /// Maximum unsigned input voltage.
112
113 /// The State-Space 1x1 system matrix.
114 A_t A{0};
115
116 /// The State-Space 1x1 input matrix.
117 B_t B{0};
118 };
119
120 /** Profile state. */
121 class State {
122 public:
123 /// The position at this state.
125
126 /// The velocity at this state.
128
129 bool operator==(const State&) const = default;
130 };
131
132 /**
133 * Constructs a ExponentialProfile.
134 *
135 * @param constraints The constraints on the profile, like maximum input.
136 */
137 explicit ExponentialProfile(Constraints constraints);
138
143
144 /**
145 * Calculates the position and velocity for the profile at a time t where the
146 * current state is at time t = 0.
147 *
148 * @param t How long to advance from the current state toward the desired
149 * state.
150 * @param current The current state.
151 * @param goal The desired state when the profile is complete.
152 * @return The position and velocity of the profile at time t.
153 */
154 State Calculate(const units::second_t& t, const State& current,
155 const State& goal) const;
156
157 /**
158 * Calculates the point after which the fastest way to reach the goal state is
159 * to apply input in the opposite direction.
160 *
161 * @param current The current state.
162 * @param goal The desired state when the profile is complete.
163 * @return The position and velocity of the profile at the inflection point.
164 */
165 State CalculateInflectionPoint(const State& current, const State& goal) const;
166
167 /**
168 * Calculates the time it will take for this profile to reach the goal state.
169 *
170 * @param current The current state.
171 * @param goal The desired state when the profile is complete.
172 * @return The total duration of this profile.
173 */
174 units::second_t TimeLeftUntil(const State& current, const State& goal) const;
175
176 /**
177 * Calculates the time it will take for this profile to reach the inflection
178 * point, and the time it will take for this profile to reach the goal state.
179 *
180 * @param current The current state.
181 * @param goal The desired state when the profile is complete.
182 * @return The timing information for this profile.
183 */
185 const State& goal) const;
186
187 private:
188 /**
189 * Calculates the point after which the fastest way to reach the goal state is
190 * to apply input in the opposite direction.
191 *
192 * @param current The current state.
193 * @param goal The desired state when the profile is complete.
194 * @param input The signed input applied to this profile from the current
195 * state.
196 * @return The position and velocity of the profile at the inflection point.
197 */
198 State CalculateInflectionPoint(const State& current, const State& goal,
199 const Input_t& input) const;
200
201 /**
202 * Calculates the time it will take for this profile to reach the inflection
203 * point, and the time it will take for this profile to reach the goal state.
204 *
205 * @param current The current state.
206 * @param inflectionPoint The inflection point of this profile.
207 * @param goal The desired state when the profile is complete.
208 * @param input The signed input applied to this profile from the current
209 * state.
210 * @return The timing information for this profile.
211 */
213 const State& inflectionPoint,
214 const State& goal,
215 const Input_t& input) const;
216
217 /**
218 * Calculates the position reached after t seconds when applying an input from
219 * the initial state.
220 *
221 * @param t The time since the initial state.
222 * @param input The signed input applied to this profile from the initial
223 * state.
224 * @param initial The initial state.
225 * @return The distance travelled by this profile.
226 */
227 Distance_t ComputeDistanceFromTime(const units::second_t& time,
228 const Input_t& input,
229 const State& initial) const;
230
231 /**
232 * Calculates the velocity reached after t seconds when applying an input from
233 * the initial state.
234 *
235 * @param t The time since the initial state.
236 * @param input The signed input applied to this profile from the initial
237 * state.
238 * @param initial The initial state.
239 * @return The distance travelled by this profile.
240 */
241 Velocity_t ComputeVelocityFromTime(const units::second_t& time,
242 const Input_t& input,
243 const State& initial) const;
244
245 /**
246 * Calculates the time required to reach a specified velocity given the
247 * initial velocity.
248 *
249 * @param velocity The goal velocity.
250 * @param input The signed input applied to this profile from the initial
251 * state.
252 * @param initial The initial velocity.
253 * @return The time required to reach the goal velocity.
254 */
255 units::second_t ComputeTimeFromVelocity(const Velocity_t& velocity,
256 const Input_t& input,
257 const Velocity_t& initial) const;
258
259 /**
260 * Calculates the distance reached at the same time as the given velocity when
261 * applying the given input from the initial state.
262 *
263 * @param velocity The velocity reached by this profile
264 * @param input The signed input applied to this profile from the initial
265 * state.
266 * @param initial The initial state.
267 * @return The distance reached when the given velocity is reached.
268 */
269 Distance_t ComputeDistanceFromVelocity(const Velocity_t& velocity,
270 const Input_t& input,
271 const State& initial) const;
272
273 /**
274 * Calculates the velocity at which input should be reversed in order to reach
275 * the goal state from the current state.
276 *
277 * @param input The signed input applied to this profile from the current
278 * state.
279 * @param current The current state.
280 * @param goal The goal state.
281 * @return The inflection velocity.
282 */
283 Velocity_t SolveForInflectionVelocity(const Input_t& input,
284 const State& current,
285 const State& goal) const;
286
287 /**
288 * Returns true if the profile should be inverted.
289 *
290 * The profile is inverted if we should first apply negative input in order to
291 * reach the goal state.
292 *
293 * @param current The initial state (usually the current state).
294 * @param goal The desired state when the profile is complete.
295 */
296 bool ShouldFlipInput(const State& current, const State& goal) const;
297
298 Constraints m_constraints;
299};
300} // namespace frc
301
302#include "ExponentialProfile.inc"
Profile constraints.
Definition: ExponentialProfile.h:81
Input_t maxInput
Maximum unsigned input voltage.
Definition: ExponentialProfile.h:111
A_t A
The State-Space 1x1 system matrix.
Definition: ExponentialProfile.h:114
Constraints(Input_t maxInput, A_t A, B_t B)
Constructs constraints for an ExponentialProfile.
Definition: ExponentialProfile.h:90
Constraints(Input_t maxInput, kV_t kV, kA_t kA)
Constructs constraints for an ExponentialProfile from characteristics.
Definition: ExponentialProfile.h:100
Velocity_t MaxVelocity() const
Computes the max achievable velocity for an Exponential Profile.
Definition: ExponentialProfile.h:108
B_t B
The State-Space 1x1 input matrix.
Definition: ExponentialProfile.h:117
Profile timing.
Definition: ExponentialProfile.h:61
bool IsFinished(const units::second_t &t) const
Decides if the profile is finished by time t.
Definition: ExponentialProfile.h:75
units::second_t totalTime
Total profile time.
Definition: ExponentialProfile.h:67
units::second_t inflectionTime
Profile inflection time.
Definition: ExponentialProfile.h:64
Profile state.
Definition: ExponentialProfile.h:121
bool operator==(const State &) const =default
Distance_t position
The position at this state.
Definition: ExponentialProfile.h:124
Velocity_t velocity
The velocity at this state.
Definition: ExponentialProfile.h:127
A Exponential-shaped velocity profile.
Definition: ExponentialProfile.h:41
units::second_t TimeLeftUntil(const State &current, const State &goal) const
Calculates the time it will take for this profile to reach the goal state.
Definition: ExponentialProfile.inc:54
ExponentialProfile(const ExponentialProfile &)=default
State Calculate(const units::second_t &t, const State &current, const State &goal) const
Calculates the position and velocity for the profile at a time t where the current state is at time t...
Definition: ExponentialProfile.inc:21
ProfileTiming CalculateProfileTiming(const State &current, const State &goal) const
Calculates the time it will take for this profile to reach the inflection point, and the time it will...
Definition: ExponentialProfile.inc:63
units::compound_unit< Distance, units::inverse< units::seconds > > Velocity
Definition: ExponentialProfile.h:45
ExponentialProfile & operator=(ExponentialProfile &&)=default
units::compound_unit< Input, units::inverse< Acceleration > > KA
Definition: ExponentialProfile.h:55
ExponentialProfile & operator=(const ExponentialProfile &)=default
ExponentialProfile(ExponentialProfile &&)=default
ExponentialProfile(Constraints constraints)
Constructs a ExponentialProfile.
Definition: ExponentialProfile.inc:16
units::compound_unit< Input, units::inverse< Velocity > > KV
Definition: ExponentialProfile.h:53
units::compound_unit< Velocity, units::inverse< units::seconds > > Acceleration
Definition: ExponentialProfile.h:48
State CalculateInflectionPoint(const State &current, const State &goal) const
Calculates the point after which the fastest way to reach the goal state is to apply input in the opp...
Definition: ExponentialProfile.inc:45
typename units::detail::compound_impl< U, Us... >::type compound_unit
Represents a unit type made up from other units.
Definition: base.h:1434
Definition: AprilTagPoseEstimator.h:15