WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
ElevatorFeedforward.hpp
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
10#include "wpi/units/length.hpp"
11#include "wpi/units/time.hpp"
12#include "wpi/units/voltage.hpp"
14
15namespace wpi::math {
16/**
17 * A helper class that computes feedforward outputs for a simple elevator
18 * (modeled as a motor acting against the force of gravity).
19 */
21 public:
22 using Distance = wpi::units::meters;
23 using Velocity =
24 wpi::units::compound_unit<Distance,
25 wpi::units::inverse<wpi::units::seconds>>;
27 wpi::units::compound_unit<Velocity,
28 wpi::units::inverse<wpi::units::seconds>>;
29 using kv_unit = wpi::units::compound_unit<wpi::units::volts,
30 wpi::units::inverse<Velocity>>;
31 using ka_unit = wpi::units::compound_unit<wpi::units::volts,
32 wpi::units::inverse<Acceleration>>;
33
34 /**
35 * Creates a new ElevatorFeedforward with the specified gains.
36 *
37 * @param kS The static gain, in volts.
38 * @param kG The gravity gain, in volts.
39 * @param kV The velocity gain, in volt seconds per distance.
40 * @param kA The acceleration gain, in volt seconds² per distance.
41 * @param dt The period in seconds.
42 * @throws IllegalArgumentException for kv &lt; zero.
43 * @throws IllegalArgumentException for ka &lt; zero.
44 * @throws IllegalArgumentException for period &le; zero.
45 */
47 wpi::units::volt_t kS, wpi::units::volt_t kG,
48 wpi::units::unit_t<kv_unit> kV,
49 wpi::units::unit_t<ka_unit> kA = wpi::units::unit_t<ka_unit>(0),
50 wpi::units::second_t dt = 20_ms)
51 : kS(kS), kG(kG), kV(kV), kA(kA), m_dt(dt) {
52 if (kV.value() < 0) {
53 wpi::math::MathSharedStore::ReportError(
54 "kV must be a non-negative number, got {}!", kV.value());
55 this->kV = wpi::units::unit_t<kv_unit>{0};
57 }
58 if (kA.value() < 0) {
59 wpi::math::MathSharedStore::ReportError(
60 "kA must be a non-negative number, got {}!", kA.value());
61 this->kA = wpi::units::unit_t<ka_unit>{0};
63 }
64 if (dt <= 0_ms) {
66 "period must be a positive number, got {}!", dt.value());
67 this->m_dt = 20_ms;
68 wpi::math::MathSharedStore::ReportWarning("period defaulted to 20 ms.");
69 }
70 }
71
72 /**
73 * Calculates the feedforward from the gains and setpoint assuming discrete
74 * control. Use this method when the setpoint does not change.
75 *
76 * @param currentVelocity The velocity setpoint.
77 * @return The computed feedforward, in volts.
78 */
79 constexpr wpi::units::volt_t Calculate(
80 wpi::units::unit_t<Velocity> currentVelocity) const {
81 return Calculate(currentVelocity, currentVelocity);
82 }
83
84 /**
85 * Calculates the feedforward from the gains and setpoints assuming discrete
86 * control.
87 *
88 * <p>Note this method is inaccurate when the velocity crosses 0.
89 *
90 * @param currentVelocity The current velocity setpoint.
91 * @param nextVelocity The next velocity setpoint.
92 * @return The computed feedforward, in volts.
93 */
94 constexpr wpi::units::volt_t Calculate(
95 wpi::units::unit_t<Velocity> currentVelocity,
96 wpi::units::unit_t<Velocity> nextVelocity) const {
97 // See wpimath/algorithms.md#Elevator_feedforward for derivation
98 if (kA < decltype(kA)(1e-9)) {
99 return kS * wpi::util::sgn(nextVelocity) + kG + kV * nextVelocity;
100 } else {
101 double A = -kV.value() / kA.value();
102 double B = 1.0 / kA.value();
103 double A_d = gcem::exp(A * m_dt.value());
104 double B_d = A > -1e-9 ? B * m_dt.value() : 1.0 / A * (A_d - 1.0) * B;
105 return kG + kS * wpi::util::sgn(currentVelocity) +
106 wpi::units::volt_t{
107 1.0 / B_d *
108 (nextVelocity.value() - A_d * currentVelocity.value())};
109 }
110 }
111
112 // Rearranging the main equation from the calculate() method yields the
113 // formulas for the methods below:
114
115 /**
116 * Calculates the maximum achievable velocity given a maximum voltage supply
117 * and an acceleration. Useful for ensuring that velocity and
118 * acceleration constraints for a trapezoidal profile are simultaneously
119 * achievable - enter the acceleration constraint, and this will give you
120 * a simultaneously-achievable velocity constraint.
121 *
122 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
123 * @param acceleration The acceleration of the elevator.
124 * @return The maximum possible velocity at the given acceleration.
125 */
126 constexpr wpi::units::unit_t<Velocity> MaxAchievableVelocity(
127 wpi::units::volt_t maxVoltage,
128 wpi::units::unit_t<Acceleration> acceleration) {
129 // Assume max velocity is positive
130 return (maxVoltage - kS - kG - kA * acceleration) / kV;
131 }
132
133 /**
134 * Calculates the minimum achievable velocity given a maximum voltage supply
135 * and an acceleration. Useful for ensuring that velocity and
136 * acceleration constraints for a trapezoidal profile are simultaneously
137 * achievable - enter the acceleration constraint, and this will give you
138 * a simultaneously-achievable velocity constraint.
139 *
140 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
141 * @param acceleration The acceleration of the elevator.
142 * @return The minimum possible velocity at the given acceleration.
143 */
144 constexpr wpi::units::unit_t<Velocity> MinAchievableVelocity(
145 wpi::units::volt_t maxVoltage,
146 wpi::units::unit_t<Acceleration> acceleration) {
147 // Assume min velocity is negative, ks flips sign
148 return (-maxVoltage + kS - kG - kA * acceleration) / kV;
149 }
150
151 /**
152 * Calculates the maximum achievable acceleration given a maximum voltage
153 * supply and a velocity. Useful for ensuring that velocity and
154 * acceleration constraints for a trapezoidal profile are simultaneously
155 * achievable - enter the velocity constraint, and this will give you
156 * a simultaneously-achievable acceleration constraint.
157 *
158 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
159 * @param velocity The velocity of the elevator.
160 * @return The maximum possible acceleration at the given velocity.
161 */
162 constexpr wpi::units::unit_t<Acceleration> MaxAchievableAcceleration(
163 wpi::units::volt_t maxVoltage, wpi::units::unit_t<Velocity> velocity) {
164 return (maxVoltage - kS * wpi::util::sgn(velocity) - kG - kV * velocity) /
165 kA;
166 }
167
168 /**
169 * Calculates the minimum achievable acceleration given a maximum voltage
170 * supply and a velocity. Useful for ensuring that velocity and
171 * acceleration constraints for a trapezoidal profile are simultaneously
172 * achievable - enter the velocity constraint, and this will give you
173 * a simultaneously-achievable acceleration constraint.
174 *
175 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
176 * @param velocity The velocity of the elevator.
177 * @return The minimum possible acceleration at the given velocity.
178 */
179 constexpr wpi::units::unit_t<Acceleration> MinAchievableAcceleration(
180 wpi::units::volt_t maxVoltage, wpi::units::unit_t<Velocity> velocity) {
181 return MaxAchievableAcceleration(-maxVoltage, velocity);
182 }
183
184 /**
185 * Sets the static gain.
186 *
187 * @param kS The static gain.
188 */
189 constexpr void SetKs(wpi::units::volt_t kS) { this->kS = kS; }
190
191 /**
192 * Sets the gravity gain.
193 *
194 * @param kG The gravity gain.
195 */
196 constexpr void SetKg(wpi::units::volt_t kG) { this->kG = kG; }
197
198 /**
199 * Sets the velocity gain.
200 *
201 * @param kV The velocity gain.
202 */
203 constexpr void SetKv(wpi::units::unit_t<kv_unit> kV) { this->kV = kV; }
204
205 /**
206 * Sets the acceleration gain.
207 *
208 * @param kA The acceleration gain.
209 */
210 constexpr void SetKa(wpi::units::unit_t<ka_unit> kA) { this->kA = kA; }
211
212 /**
213 * Returns the static gain.
214 *
215 * @return The static gain.
216 */
217 constexpr wpi::units::volt_t GetKs() const { return kS; }
218
219 /**
220 * Returns the gravity gain.
221 *
222 * @return The gravity gain.
223 */
224 constexpr wpi::units::volt_t GetKg() const { return kG; }
225
226 /**
227 * Returns the velocity gain.
228 *
229 * @return The velocity gain.
230 */
231 constexpr wpi::units::unit_t<kv_unit> GetKv() const { return kV; }
232
233 /**
234 * Returns the acceleration gain.
235 *
236 * @return The acceleration gain.
237 */
238 constexpr wpi::units::unit_t<ka_unit> GetKa() const { return kA; }
239
240 private:
241 /// The static gain.
242 wpi::units::volt_t kS;
243
244 /// The gravity gain.
245 wpi::units::volt_t kG;
246
247 /// The velocity gain.
248 wpi::units::unit_t<kv_unit> kV;
249
250 /// The acceleration gain.
251 wpi::units::unit_t<ka_unit> kA;
252
253 /** The period. */
254 wpi::units::second_t m_dt;
255};
256} // namespace wpi::math
257
wpi::units::compound_unit< wpi::units::volts, wpi::units::inverse< Velocity > > kv_unit
Definition ElevatorFeedforward.hpp:29
constexpr void SetKa(wpi::units::unit_t< ka_unit > kA)
Sets the acceleration gain.
Definition ElevatorFeedforward.hpp:210
constexpr wpi::units::volt_t Calculate(wpi::units::unit_t< Velocity > currentVelocity) const
Calculates the feedforward from the gains and setpoint assuming discrete control.
Definition ElevatorFeedforward.hpp:79
wpi::units::meters Distance
Definition ElevatorFeedforward.hpp:22
constexpr wpi::units::unit_t< ka_unit > GetKa() const
Returns the acceleration gain.
Definition ElevatorFeedforward.hpp:238
constexpr ElevatorFeedforward(wpi::units::volt_t kS, wpi::units::volt_t kG, wpi::units::unit_t< kv_unit > kV, wpi::units::unit_t< ka_unit > kA=wpi::units::unit_t< ka_unit >(0), wpi::units::second_t dt=20_ms)
Creates a new ElevatorFeedforward with the specified gains.
Definition ElevatorFeedforward.hpp:46
wpi::units::compound_unit< Distance, wpi::units::inverse< wpi::units::seconds > > Velocity
Definition ElevatorFeedforward.hpp:23
constexpr wpi::units::unit_t< Velocity > MaxAchievableVelocity(wpi::units::volt_t maxVoltage, wpi::units::unit_t< Acceleration > acceleration)
Calculates the maximum achievable velocity given a maximum voltage supply and an acceleration.
Definition ElevatorFeedforward.hpp:126
constexpr void SetKv(wpi::units::unit_t< kv_unit > kV)
Sets the velocity gain.
Definition ElevatorFeedforward.hpp:203
wpi::units::compound_unit< Velocity, wpi::units::inverse< wpi::units::seconds > > Acceleration
Definition ElevatorFeedforward.hpp:26
constexpr wpi::units::volt_t GetKg() const
Returns the gravity gain.
Definition ElevatorFeedforward.hpp:224
constexpr void SetKg(wpi::units::volt_t kG)
Sets the gravity gain.
Definition ElevatorFeedforward.hpp:196
constexpr wpi::units::unit_t< Acceleration > MaxAchievableAcceleration(wpi::units::volt_t maxVoltage, wpi::units::unit_t< Velocity > velocity)
Calculates the maximum achievable acceleration given a maximum voltage supply and a velocity.
Definition ElevatorFeedforward.hpp:162
constexpr void SetKs(wpi::units::volt_t kS)
Sets the static gain.
Definition ElevatorFeedforward.hpp:189
constexpr wpi::units::volt_t GetKs() const
Returns the static gain.
Definition ElevatorFeedforward.hpp:217
constexpr wpi::units::unit_t< Velocity > MinAchievableVelocity(wpi::units::volt_t maxVoltage, wpi::units::unit_t< Acceleration > acceleration)
Calculates the minimum achievable velocity given a maximum voltage supply and an acceleration.
Definition ElevatorFeedforward.hpp:144
constexpr wpi::units::volt_t Calculate(wpi::units::unit_t< Velocity > currentVelocity, wpi::units::unit_t< Velocity > nextVelocity) const
Calculates the feedforward from the gains and setpoints assuming discrete control.
Definition ElevatorFeedforward.hpp:94
constexpr wpi::units::unit_t< Acceleration > MinAchievableAcceleration(wpi::units::volt_t maxVoltage, wpi::units::unit_t< Velocity > velocity)
Calculates the minimum achievable acceleration given a maximum voltage supply and a velocity.
Definition ElevatorFeedforward.hpp:179
wpi::units::compound_unit< wpi::units::volts, wpi::units::inverse< Acceleration > > ka_unit
Definition ElevatorFeedforward.hpp:31
constexpr wpi::units::unit_t< kv_unit > GetKv() const
Returns the velocity gain.
Definition ElevatorFeedforward.hpp:231
static void ReportError(const S &format, Args &&... args)
Definition MathShared.hpp:48
static void ReportWarning(const S &format, Args &&... args)
Definition MathShared.hpp:57
constexpr return_t< T > exp(const T x) noexcept
Compile-time exponential function.
Definition exp.hpp:130
Definition LinearSystem.hpp:20
constexpr int sgn(T val)
Definition MathExtras.hpp:766