WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
LinearSystemLoop.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
7#include <functional>
8
14#include "wpi/units/time.hpp"
15#include "wpi/units/voltage.hpp"
17
18namespace wpi::math {
19
20/**
21 * Combines a controller, feedforward, and observer for controlling a mechanism
22 * with full state feedback.
23 *
24 * For everything in this file, "inputs" and "outputs" are defined from the
25 * perspective of the plant. This means U is an input and Y is an output
26 * (because you give the plant U (powers) and it gives you back a Y (sensor
27 * values). This is the opposite of what they mean from the perspective of the
28 * controller (U is an output because that's what goes to the motors and Y is an
29 * input because that's what comes back from the sensors).
30 *
31 * For more on the underlying math, read
32 * https://file.tavsys.net/control/controls-engineering-in-frc.pdf.
33 *
34 * @tparam States Number of states.
35 * @tparam Inputs Number of inputs.
36 * @tparam Outputs Number of outputs.
37 */
38template <int States, int Inputs, int Outputs>
40 public:
44
45 /**
46 * Constructs a state-space loop with the given plant, controller, and
47 * observer. By default, the initial reference is all zeros. Users should
48 * call reset with the initial system state before enabling the loop. This
49 * constructor assumes that the input(s) to this system are voltage.
50 *
51 * @param plant State-space plant.
52 * @param controller State-space controller.
53 * @param observer State-space observer.
54 * @param maxVoltage The maximum voltage that can be applied. Commonly 12.
55 * @param dt The nominal timestep.
56 */
60 wpi::units::volt_t maxVoltage, wpi::units::second_t dt)
62 plant, controller, observer,
63 [=](const InputVector& u) {
65 u, maxVoltage.value());
66 },
67 dt) {}
68
69 /**
70 * Constructs a state-space loop with the given plant, controller, and
71 * observer. By default, the initial reference is all zeros. Users should
72 * call reset with the initial system state before enabling the loop. This
73 * constructor assumes that the input(s) to this system are voltage.
74 *
75 * @param plant State-space plant.
76 * @param controller State-space controller.
77 * @param observer State-space observer.
78 * @param clampFunction The function used to clamp the input vector.
79 * @param dt The nominal timestep.
80 */
84 std::function<InputVector(const InputVector&)> clampFunction,
85 wpi::units::second_t dt)
87 controller,
88 LinearPlantInversionFeedforward<States, Inputs>{plant, dt},
89 observer, clampFunction) {}
90
91 /**
92 * Constructs a state-space loop with the given controller, feedforward and
93 * observer. By default, the initial reference is all zeros. Users should
94 * call reset with the initial system state.
95 *
96 * @param controller State-space controller.
97 * @param feedforward Plant inversion feedforward.
98 * @param observer State-space observer.
99 * @param maxVoltage The maximum voltage that can be applied. Assumes
100 * that the inputs are voltages.
101 */
106 wpi::units::volt_t maxVoltage)
107 : LinearSystemLoop(controller, feedforward, observer,
108 [=](const InputVector& u) {
110 u, maxVoltage.value());
111 }) {}
112
113 /**
114 * Constructs a state-space loop with the given controller, feedforward,
115 * observer and clamp function. By default, the initial reference is all
116 * zeros. Users should call reset with the initial system state.
117 *
118 * @param controller State-space controller.
119 * @param feedforward Plant-inversion feedforward.
120 * @param observer State-space observer.
121 * @param clampFunction The function used to clamp the input vector.
122 */
127 std::function<InputVector(const InputVector&)> clampFunction)
128 : m_controller(&controller),
129 m_feedforward(feedforward),
130 m_observer(&observer),
131 m_clampFunc(clampFunction) {
132 m_nextR.setZero();
133 Reset(m_nextR);
134 wpi::math::MathSharedStore::ReportUsage("LinearSystemLoop", "");
135 }
136
139
140 /**
141 * Returns the observer's state estimate x-hat.
142 */
143 const StateVector& Xhat() const { return m_observer->Xhat(); }
144
145 /**
146 * Returns an element of the observer's state estimate x-hat.
147 *
148 * @param i Row of x-hat.
149 */
150 double Xhat(int i) const { return m_observer->Xhat(i); }
151
152 /**
153 * Returns the controller's next reference r.
154 */
155 const StateVector& NextR() const { return m_nextR; }
156
157 /**
158 * Returns an element of the controller's next reference r.
159 *
160 * @param i Row of r.
161 */
162 double NextR(int i) const { return NextR()(i); }
163
164 /**
165 * Returns the controller's calculated control input u.
166 */
167 InputVector U() const {
168 return ClampInput(m_controller->U() + m_feedforward.Uff());
169 }
170
171 /**
172 * Returns an element of the controller's calculated control input u.
173 *
174 * @param i Row of u.
175 */
176 double U(int i) const { return U()(i); }
177
178 /**
179 * Set the initial state estimate x-hat.
180 *
181 * @param xHat The initial state estimate x-hat.
182 */
183 void SetXhat(const StateVector& xHat) { m_observer->SetXhat(xHat); }
184
185 /**
186 * Set an element of the initial state estimate x-hat.
187 *
188 * @param i Row of x-hat.
189 * @param value Value for element of x-hat.
190 */
191 void SetXhat(int i, double value) { m_observer->SetXhat(i, value); }
192
193 /**
194 * Set the next reference r.
195 *
196 * @param nextR Next reference.
197 */
198 void SetNextR(const StateVector& nextR) { m_nextR = nextR; }
199
200 /**
201 * Return the controller used internally.
202 */
206
207 /**
208 * Return the feedforward used internally.
209 *
210 * @return the feedforward used internally.
211 */
215
216 /**
217 * Return the observer used internally.
218 */
220 return *m_observer;
221 }
222
223 /**
224 * Zeroes reference r and controller output u. The previous reference
225 * of the PlantInversionFeedforward and the initial state estimate of
226 * the KalmanFilter are set to the initial state provided.
227 *
228 * @param initialState The initial state.
229 */
230 void Reset(const StateVector& initialState) {
231 m_nextR.setZero();
232 m_controller->Reset();
233 m_feedforward.Reset(initialState);
234 m_observer->SetXhat(initialState);
235 }
236
237 /**
238 * Returns difference between reference r and current state x-hat.
239 */
240 StateVector Error() const { return m_controller->R() - m_observer->Xhat(); }
241
242 /**
243 * Correct the state estimate x-hat using the measurements in y.
244 *
245 * @param y Measurement vector.
246 */
247 void Correct(const OutputVector& y) { m_observer->Correct(U(), y); }
248
249 /**
250 * Sets new controller output, projects model forward, and runs observer
251 * prediction.
252 *
253 * After calling this, the user should send the elements of u to the
254 * actuators.
255 *
256 * @param dt Timestep for model update.
257 */
258 void Predict(wpi::units::second_t dt) {
259 InputVector u =
260 ClampInput(m_controller->Calculate(m_observer->Xhat(), m_nextR) +
261 m_feedforward.Calculate(m_nextR));
262 m_observer->Predict(u, dt);
263 }
264
265 /**
266 * Clamps input vector between system's minimum and maximum allowable input.
267 *
268 * @param u Input vector to clamp.
269 * @return Clamped input vector.
270 */
271 InputVector ClampInput(const InputVector& u) const { return m_clampFunc(u); }
272
273 protected:
277
278 /**
279 * Clamping function.
280 */
281 std::function<InputVector(const InputVector&)> m_clampFunc;
282
283 // Reference to go to in the next cycle (used by feedforward controller).
285
286 // These are accessible from non-templated subclasses.
287 static constexpr int kStates = States;
288 static constexpr int kInputs = Inputs;
289 static constexpr int kOutputs = Outputs;
290};
291
292extern template class EXPORT_TEMPLATE_DECLARE(WPILIB_DLLEXPORT)
294extern template class EXPORT_TEMPLATE_DECLARE(WPILIB_DLLEXPORT)
296
297} // namespace wpi::math
#define EXPORT_TEMPLATE_DECLARE(export)
Definition SymbolExports.hpp:94
#define WPILIB_DLLEXPORT
Definition SymbolExports.hpp:36
A Kalman filter combines predictions from a model and measurements to give an estimate of the true sy...
Definition KalmanFilter.hpp:45
Constructs a plant inversion model-based feedforward from a LinearSystem.
Definition LinearPlantInversionFeedforward.hpp:30
Contains the controller coefficients and logic for a linear-quadratic regulator (LQR).
Definition LinearQuadraticRegulator.hpp:38
A plant defined using state-space notation.
Definition LinearSystem.hpp:35
Combines a controller, feedforward, and observer for controlling a mechanism with full state feedback...
Definition LinearSystemLoop.hpp:39
InputVector U() const
Returns the controller's calculated control input u.
Definition LinearSystemLoop.hpp:167
LinearSystemLoop(LinearSystem< States, Inputs, Outputs > &plant, LinearQuadraticRegulator< States, Inputs > &controller, KalmanFilter< States, Inputs, Outputs > &observer, std::function< InputVector(const InputVector &)> clampFunction, wpi::units::second_t dt)
Constructs a state-space loop with the given plant, controller, and observer.
Definition LinearSystemLoop.hpp:81
double U(int i) const
Returns an element of the controller's calculated control input u.
Definition LinearSystemLoop.hpp:176
LinearQuadraticRegulator< States, Inputs > * m_controller
Definition LinearSystemLoop.hpp:274
void SetXhat(const StateVector &xHat)
Set the initial state estimate x-hat.
Definition LinearSystemLoop.hpp:183
void Correct(const OutputVector &y)
Correct the state estimate x-hat using the measurements in y.
Definition LinearSystemLoop.hpp:247
void Reset(const StateVector &initialState)
Zeroes reference r and controller output u.
Definition LinearSystemLoop.hpp:230
LinearSystemLoop(LinearQuadraticRegulator< States, Inputs > &controller, const LinearPlantInversionFeedforward< States, Inputs > &feedforward, KalmanFilter< States, Inputs, Outputs > &observer, wpi::units::volt_t maxVoltage)
Constructs a state-space loop with the given controller, feedforward and observer.
Definition LinearSystemLoop.hpp:102
const StateVector & Xhat() const
Returns the observer's state estimate x-hat.
Definition LinearSystemLoop.hpp:143
const LinearPlantInversionFeedforward< States, Inputs > Feedforward() const
Return the feedforward used internally.
Definition LinearSystemLoop.hpp:212
LinearSystemLoop(LinearSystemLoop &&)=default
KalmanFilter< States, Inputs, Outputs > * m_observer
Definition LinearSystemLoop.hpp:276
static constexpr int kOutputs
Definition LinearSystemLoop.hpp:289
StateVector m_nextR
Definition LinearSystemLoop.hpp:284
std::function< InputVector(const InputVector &)> m_clampFunc
Clamping function.
Definition LinearSystemLoop.hpp:281
LinearSystemLoop & operator=(LinearSystemLoop &&)=default
Vectord< Outputs > OutputVector
Definition LinearSystemLoop.hpp:43
static constexpr int kStates
Definition LinearSystemLoop.hpp:287
LinearPlantInversionFeedforward< States, Inputs > m_feedforward
Definition LinearSystemLoop.hpp:275
void SetXhat(int i, double value)
Set an element of the initial state estimate x-hat.
Definition LinearSystemLoop.hpp:191
double NextR(int i) const
Returns an element of the controller's next reference r.
Definition LinearSystemLoop.hpp:162
StateVector Error() const
Returns difference between reference r and current state x-hat.
Definition LinearSystemLoop.hpp:240
Vectord< States > StateVector
Definition LinearSystemLoop.hpp:41
InputVector ClampInput(const InputVector &u) const
Clamps input vector between system's minimum and maximum allowable input.
Definition LinearSystemLoop.hpp:271
void Predict(wpi::units::second_t dt)
Sets new controller output, projects model forward, and runs observer prediction.
Definition LinearSystemLoop.hpp:258
void SetNextR(const StateVector &nextR)
Set the next reference r.
Definition LinearSystemLoop.hpp:198
const LinearQuadraticRegulator< States, Inputs > & Controller() const
Return the controller used internally.
Definition LinearSystemLoop.hpp:203
const KalmanFilter< States, Inputs, Outputs > & Observer() const
Return the observer used internally.
Definition LinearSystemLoop.hpp:219
LinearSystemLoop(LinearSystem< States, Inputs, Outputs > &plant, LinearQuadraticRegulator< States, Inputs > &controller, KalmanFilter< States, Inputs, Outputs > &observer, wpi::units::volt_t maxVoltage, wpi::units::second_t dt)
Constructs a state-space loop with the given plant, controller, and observer.
Definition LinearSystemLoop.hpp:57
static constexpr int kInputs
Definition LinearSystemLoop.hpp:288
const StateVector & NextR() const
Returns the controller's next reference r.
Definition LinearSystemLoop.hpp:155
double Xhat(int i) const
Returns an element of the observer's state estimate x-hat.
Definition LinearSystemLoop.hpp:150
LinearSystemLoop(LinearQuadraticRegulator< States, Inputs > &controller, const LinearPlantInversionFeedforward< States, Inputs > &feedforward, KalmanFilter< States, Inputs, Outputs > &observer, std::function< InputVector(const InputVector &)> clampFunction)
Constructs a state-space loop with the given controller, feedforward, observer and clamp function.
Definition LinearSystemLoop.hpp:123
Vectord< Inputs > InputVector
Definition LinearSystemLoop.hpp:42
static void ReportUsage(std::string_view resource, std::string_view data)
Definition MathShared.hpp:61
Definition LinearSystem.hpp:20
Eigen::Vector< double, Inputs > DesaturateInputVector(const Eigen::Vector< double, Inputs > &u, double maxMagnitude)
Renormalize all inputs if any exceeds the maximum magnitude.
Definition StateSpaceUtil.hpp:195
Eigen::Vector< double, Size > Vectord
Definition EigenCore.hpp:12