WPILibC++ 2024.1.1-beta-4
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
16namespace frc {
17/**
18 * A helper class that computes feedforward outputs for a simple elevator
19 * (modeled as a motor acting against the force of gravity).
20 */
22 public:
23 using Distance = units::meters;
24 using Velocity =
29 using ka_unit =
31
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 */
43 units::volt_t kS, units::volt_t kG, units::unit_t<kv_unit> kV,
45 : kS(kS), kG(kG), kV(kV), kA(kA) {}
46
47 /**
48 * Calculates the feedforward from the gains and setpoints.
49 *
50 * @param velocity The velocity setpoint, in distance per second.
51 * @param acceleration The acceleration setpoint, in distance per second².
52 * @return The computed feedforward, in volts.
53 */
54 constexpr units::volt_t Calculate(units::unit_t<Velocity> velocity,
55 units::unit_t<Acceleration> acceleration =
57 return kS * wpi::sgn(velocity) + kG + kV * velocity + kA * acceleration;
58 }
59
60 /**
61 * Calculates the feedforward from the gains and setpoints.
62 *
63 * @param currentVelocity The current velocity setpoint, in distance per
64 * second.
65 * @param nextVelocity The next velocity setpoint, in distance per second.
66 * @param dt Time between velocity setpoints in seconds.
67 * @return The computed feedforward, in volts.
68 */
69 units::volt_t Calculate(units::unit_t<Velocity> currentVelocity,
70 units::unit_t<Velocity> nextVelocity,
71 units::second_t dt) const {
72 // Discretize the affine model.
73 //
74 // dx/dt = Ax + Bu + c
75 // dx/dt = Ax + B(u + B⁺c)
76 // xₖ₊₁ = eᴬᵀxₖ + A⁻¹(eᴬᵀ - I)B(uₖ + B⁺cₖ)
77 // xₖ₊₁ = A_d xₖ + B_d (uₖ + B⁺cₖ)
78 // xₖ₊₁ = A_d xₖ + B_duₖ + B_d B⁺cₖ
79 //
80 // Solve for uₖ.
81 //
82 // B_duₖ = xₖ₊₁ − A_d xₖ − B_d B⁺cₖ
83 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ − B_d B⁺cₖ)
84 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) − B⁺cₖ
85 //
86 // For an elevator with the model
87 // dx/dt = -Kv/Ka x + 1/Ka u - Kg/Ka - Ks/Ka sgn(x),
88 // A = -Kv/Ka, B = 1/Ka, and c = -(Kg/Ka + Ks/Ka sgn(x)). Substitute in B
89 // assuming sgn(x) is a constant for the duration of the step.
90 //
91 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) − Ka(-(Kg/Ka + Ks/Ka sgn(x)))
92 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) + Ka(Kg/Ka + Ks/Ka sgn(x))
93 // uₖ = B_d⁺(xₖ₊₁ − A_d xₖ) + Kg + Ks sgn(x)
94 auto plant = LinearSystemId::IdentifyVelocitySystem<Distance>(kV, kA);
95 LinearPlantInversionFeedforward<1, 1> feedforward{plant, dt};
96
97 Vectord<1> r{currentVelocity.value()};
98 Vectord<1> nextR{nextVelocity.value()};
99
100 return kG + kS * wpi::sgn(currentVelocity.value()) +
101 units::volt_t{feedforward.Calculate(r, nextR)(0)};
102 }
103
104 // Rearranging the main equation from the calculate() method yields the
105 // formulas for the methods below:
106
107 /**
108 * Calculates the maximum achievable velocity given a maximum voltage supply
109 * and an acceleration. Useful for ensuring that velocity and
110 * acceleration constraints for a trapezoidal profile are simultaneously
111 * achievable - enter the acceleration constraint, and this will give you
112 * a simultaneously-achievable velocity constraint.
113 *
114 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
115 * @param acceleration The acceleration of the elevator.
116 * @return The maximum possible velocity at the given acceleration.
117 */
119 units::volt_t maxVoltage, units::unit_t<Acceleration> acceleration) {
120 // Assume max velocity is positive
121 return (maxVoltage - kS - kG - kA * acceleration) / kV;
122 }
123
124 /**
125 * Calculates the minimum achievable velocity given a maximum voltage supply
126 * and an acceleration. Useful for ensuring that velocity and
127 * acceleration constraints for a trapezoidal profile are simultaneously
128 * achievable - enter the acceleration constraint, and this will give you
129 * a simultaneously-achievable velocity constraint.
130 *
131 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
132 * @param acceleration The acceleration of the elevator.
133 * @return The minimum possible velocity at the given acceleration.
134 */
136 units::volt_t maxVoltage, units::unit_t<Acceleration> acceleration) {
137 // Assume min velocity is negative, ks flips sign
138 return (-maxVoltage + kS - kG - kA * acceleration) / kV;
139 }
140
141 /**
142 * Calculates the maximum achievable acceleration given a maximum voltage
143 * supply and a velocity. Useful for ensuring that velocity and
144 * acceleration constraints for a trapezoidal profile are simultaneously
145 * achievable - enter the velocity constraint, and this will give you
146 * a simultaneously-achievable acceleration constraint.
147 *
148 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
149 * @param velocity The velocity of the elevator.
150 * @return The maximum possible acceleration at the given velocity.
151 */
153 units::volt_t maxVoltage, units::unit_t<Velocity> velocity) {
154 return (maxVoltage - kS * wpi::sgn(velocity) - kG - kV * velocity) / kA;
155 }
156
157 /**
158 * Calculates the minimum achievable acceleration given a maximum voltage
159 * supply and a velocity. Useful for ensuring that velocity and
160 * acceleration constraints for a trapezoidal profile are simultaneously
161 * achievable - enter the velocity constraint, and this will give you
162 * a simultaneously-achievable acceleration constraint.
163 *
164 * @param maxVoltage The maximum voltage that can be supplied to the elevator.
165 * @param velocity The velocity of the elevator.
166 * @return The minimum possible acceleration at the given velocity.
167 */
169 units::volt_t maxVoltage, units::unit_t<Velocity> velocity) {
170 return MaxAchievableAcceleration(-maxVoltage, velocity);
171 }
172
173 units::volt_t kS{0};
174 units::volt_t kG{0};
177};
178} // namespace frc
179
A helper class that computes feedforward outputs for a simple elevator (modeled as a motor acting aga...
Definition: ElevatorFeedforward.h:21
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:135
units::unit_t< kv_unit > kV
Definition: ElevatorFeedforward.h:175
units::meters Distance
Definition: ElevatorFeedforward.h:23
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:152
units::volt_t kS
Definition: ElevatorFeedforward.h:173
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:42
units::compound_unit< Distance, units::inverse< units::seconds > > Velocity
Definition: ElevatorFeedforward.h:25
units::volt_t kG
Definition: ElevatorFeedforward.h:174
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:118
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:168
units::unit_t< ka_unit > kA
Definition: ElevatorFeedforward.h:176
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:54
units::compound_unit< units::volts, units::inverse< Velocity > > kv_unit
Definition: ElevatorFeedforward.h:28
units::compound_unit< Velocity, units::inverse< units::seconds > > Acceleration
Definition: ElevatorFeedforward.h:27
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:69
units::compound_unit< units::volts, units::inverse< Acceleration > > ka_unit
Definition: ElevatorFeedforward.h:30
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:2119
typename units::detail::compound_impl< U, Us... >::type compound_unit
Represents a unit type made up from other units.
Definition: base.h:1446
Definition: AprilTagPoseEstimator.h:15
Eigen::Vector< double, Size > Vectord
Definition: EigenCore.h:12
constexpr int sgn(T val)
Definition: MathExtras.h:624