WPILibC++ 2024.3.2
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 */
42 units::volt_t kS, units::volt_t kG, units::unit_t<kv_unit> kV,
44 : kS(kS), kG(kG), kV(kV), kA(kA) {
45 if (kV.value() < 0) {
47 "kV must be a non-negative number, got {}!", kV.value());
50 }
51 if (kA.value() < 0) {
53 "kA must be a non-negative number, got {}!", kA.value());
56 }
57 }
58
59 /**
60 * Calculates the feedforward from the gains and setpoints.
61 *
62 * @param velocity The velocity setpoint, in distance per second.
63 * @param acceleration The acceleration setpoint, in distance per second².
64 * @return The computed feedforward, in volts.
65 */
66 constexpr units::volt_t Calculate(units::unit_t<Velocity> velocity,
67 units::unit_t<Acceleration> acceleration =
69 return kS * wpi::sgn(velocity) + kG + kV * velocity + kA * acceleration;
70 }
71
72 /**
73 * Calculates the feedforward from the gains and setpoints.
74 *
75 * @param currentVelocity The current velocity setpoint, in distance per
76 * second.
77 * @param nextVelocity The next velocity setpoint, in distance per second.
78 * @param dt Time between velocity setpoints in seconds.
79 * @return The computed feedforward, in volts.
80 */
81 units::volt_t Calculate(units::unit_t<Velocity> currentVelocity,
82 units::unit_t<Velocity> nextVelocity,
83 units::second_t dt) const {
84 // Discretize the affine model.
85 //
86 // dx/dt = Ax + Bu + c
87 // dx/dt = Ax + B(u + B⁺c)
88 // xₖ₊₁ = eᴬᵀxₖ + A⁻¹(eᴬᵀ - I)B(uₖ + B⁺cₖ)
89 // xₖ₊₁ = A_d xₖ + B_d (uₖ + B⁺cₖ)
90 // xₖ₊₁ = A_d xₖ + B_duₖ + B_d B⁺cₖ
91 //
92 // Solve for uₖ.
93 //
94 // B_duₖ = xₖ₊₁ − A_d xₖ − B_d B⁺cₖ
95 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ − B_d B⁺cₖ)
96 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) − B⁺cₖ
97 //
98 // For an elevator with the model
99 // dx/dt = -Kv/Ka x + 1/Ka u - Kg/Ka - Ks/Ka sgn(x),
100 // A = -Kv/Ka, B = 1/Ka, and c = -(Kg/Ka + Ks/Ka sgn(x)). Substitute in B
101 // assuming sgn(x) is a constant for the duration of the step.
102 //
103 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) − Ka(-(Kg/Ka + Ks/Ka sgn(x)))
104 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) + Ka(Kg/Ka + Ks/Ka sgn(x))
105 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) + Kg + Ks sgn(x)
106 auto plant = LinearSystemId::IdentifyVelocitySystem<Distance>(kV, kA);
107 LinearPlantInversionFeedforward<1, 1> feedforward{plant, dt};
108
109 Vectord<1> r{currentVelocity.value()};
110 Vectord<1> nextR{nextVelocity.value()};
111
112 return kG + kS * wpi::sgn(currentVelocity.value()) +
113 units::volt_t{feedforward.Calculate(r, nextR)(0)};
114 }
115
116 // Rearranging the main equation from the calculate() method yields the
117 // formulas for the methods below:
118
119 /**
120 * Calculates the maximum achievable velocity given a maximum voltage supply
121 * and an acceleration. Useful for ensuring that velocity and
122 * acceleration constraints for a trapezoidal profile are simultaneously
123 * achievable - enter the acceleration constraint, and this will give you
124 * a simultaneously-achievable velocity constraint.
125 *
126 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
127 * @param acceleration The acceleration of the elevator.
128 * @return The maximum possible velocity at the given acceleration.
129 */
131 units::volt_t maxVoltage, units::unit_t<Acceleration> acceleration) {
132 // Assume max velocity is positive
133 return (maxVoltage - kS - kG - kA * acceleration) / kV;
134 }
135
136 /**
137 * Calculates the minimum achievable velocity given a maximum voltage supply
138 * and an acceleration. Useful for ensuring that velocity and
139 * acceleration constraints for a trapezoidal profile are simultaneously
140 * achievable - enter the acceleration constraint, and this will give you
141 * a simultaneously-achievable velocity constraint.
142 *
143 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
144 * @param acceleration The acceleration of the elevator.
145 * @return The minimum possible velocity at the given acceleration.
146 */
148 units::volt_t maxVoltage, units::unit_t<Acceleration> acceleration) {
149 // Assume min velocity is negative, ks flips sign
150 return (-maxVoltage + kS - kG - kA * acceleration) / kV;
151 }
152
153 /**
154 * Calculates the maximum achievable acceleration given a maximum voltage
155 * supply and a velocity. Useful for ensuring that velocity and
156 * acceleration constraints for a trapezoidal profile are simultaneously
157 * achievable - enter the velocity constraint, and this will give you
158 * a simultaneously-achievable acceleration constraint.
159 *
160 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
161 * @param velocity The velocity of the elevator.
162 * @return The maximum possible acceleration at the given velocity.
163 */
165 units::volt_t maxVoltage, units::unit_t<Velocity> velocity) {
166 return (maxVoltage - kS * wpi::sgn(velocity) - kG - kV * velocity) / kA;
167 }
168
169 /**
170 * Calculates the minimum achievable acceleration given a maximum voltage
171 * supply and a velocity. Useful for ensuring that velocity and
172 * acceleration constraints for a trapezoidal profile are simultaneously
173 * achievable - enter the velocity constraint, and this will give you
174 * a simultaneously-achievable acceleration constraint.
175 *
176 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
177 * @param velocity The velocity of the elevator.
178 * @return The minimum possible acceleration at the given velocity.
179 */
181 units::volt_t maxVoltage, units::unit_t<Velocity> velocity) {
182 return MaxAchievableAcceleration(-maxVoltage, velocity);
183 }
184
185 /// The static gain.
186 const units::volt_t kS;
187
188 /// The gravity gain.
189 const units::volt_t kG;
190
191 /// The velocity gain.
193
194 /// The acceleration gain.
196};
197} // namespace frc
198
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:147
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:164
const units::volt_t kG
The gravity gain.
Definition: ElevatorFeedforward.h:189
const units::volt_t kS
The static gain.
Definition: ElevatorFeedforward.h:186
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))
Creates a new ElevatorFeedforward with the specified gains.
Definition: ElevatorFeedforward.h:41
units::compound_unit< Distance, units::inverse< units::seconds > > Velocity
Definition: ElevatorFeedforward.h:26
const units::unit_t< ka_unit > kA
The acceleration gain.
Definition: ElevatorFeedforward.h:195
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:130
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:180
constexpr units::volt_t Calculate(units::unit_t< Velocity > velocity, units::unit_t< Acceleration > acceleration=units::unit_t< Acceleration >(0))
Calculates the feedforward from the gains and setpoints.
Definition: ElevatorFeedforward.h:66
units::compound_unit< units::volts, units::inverse< Velocity > > kv_unit
Definition: ElevatorFeedforward.h:29
const units::unit_t< kv_unit > kV
The velocity gain.
Definition: ElevatorFeedforward.h:192
units::compound_unit< Velocity, units::inverse< units::seconds > > Acceleration
Definition: ElevatorFeedforward.h:28
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.
Definition: ElevatorFeedforward.h:81
units::compound_unit< units::volts, units::inverse< Acceleration > > ka_unit
Definition: ElevatorFeedforward.h:31
Constructs a plant inversion model-based feedforward from a LinearSystem.
Definition: LinearPlantInversionFeedforward.h:33
constexpr underlying_type value() const noexcept
unit value
Definition: base.h:2107
static void ReportError(const S &format, Args &&... args)
Definition: MathShared.h:60
static void ReportWarning(const S &format, Args &&... args)
Definition: MathShared.h:69
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
Eigen::Vector< double, Size > Vectord
Definition: EigenCore.h:12
constexpr int sgn(T val)
Definition: MathExtras.h:624