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