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