WPILibC++ 2024.3.2
ControlAffinePlantInversionFeedforward.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 <array>
8#include <functional>
9
10#include <Eigen/QR>
11
12#include "frc/EigenCore.h"
14#include "units/time.h"
15
16namespace frc {
17
18/**
19 * Constructs a control-affine plant inversion model-based feedforward from
20 * given model dynamics.
21 *
22 * If given the vector valued function as f(x, u) where x is the state
23 * vector and u is the input vector, the B matrix(continuous input matrix)
24 * is calculated through a NumericalJacobian. In this case f has to be
25 * control-affine (of the form f(x) + Bu).
26 *
27 * The feedforward is calculated as
28 * <strong> u_ff = B<sup>+</sup> (rDot - f(x)) </strong>, where <strong>
29 * B<sup>+</sup> </strong> is the pseudoinverse of B.
30 *
31 * This feedforward does not account for a dynamic B matrix, B is either
32 * determined or supplied when the feedforward is created and remains constant.
33 *
34 * For more on the underlying math, read
35 * https://file.tavsys.net/control/controls-engineering-in-frc.pdf.
36 *
37 * @tparam States Number of states.
38 * @tparam Inputs Number of inputs.
39 */
40template <int States, int Inputs>
42 public:
45
46 /**
47 * Constructs a feedforward with given model dynamics as a function
48 * of state and input.
49 *
50 * @param f A vector-valued function of x, the state, and
51 * u, the input, that returns the derivative of
52 * the state vector. HAS to be control-affine
53 * (of the form f(x) + Bu).
54 * @param dt The timestep between calls of calculate().
55 */
57 std::function<StateVector(const StateVector&, const InputVector&)> f,
58 units::second_t dt)
59 : m_dt(dt), m_f(f) {
60 m_B = NumericalJacobianU<States, States, Inputs>(f, StateVector::Zero(),
61 InputVector::Zero());
62
63 Reset();
64 }
65
66 /**
67 * Constructs a feedforward with given model dynamics as a function of state,
68 * and the plant's B matrix(continuous input matrix).
69 *
70 * @param f A vector-valued function of x, the state,
71 * that returns the derivative of the state vector.
72 * @param B Continuous input matrix of the plant being controlled.
73 * @param dt The timestep between calls of calculate().
74 */
76 std::function<StateVector(const StateVector&)> f,
77 const Matrixd<States, Inputs>& B, units::second_t dt)
78 : m_B(B), m_dt(dt) {
79 m_f = [=](const StateVector& x, const InputVector& u) -> StateVector {
80 return f(x);
81 };
82
83 Reset();
84 }
85
90
91 /**
92 * Returns the previously calculated feedforward as an input vector.
93 *
94 * @return The calculated feedforward.
95 */
96 const InputVector& Uff() const { return m_uff; }
97
98 /**
99 * Returns an element of the previously calculated feedforward.
100 *
101 * @param i Row of uff.
102 *
103 * @return The row of the calculated feedforward.
104 */
105 double Uff(int i) const { return m_uff(i); }
106
107 /**
108 * Returns the current reference vector r.
109 *
110 * @return The current reference vector.
111 */
112 const StateVector& R() const { return m_r; }
113
114 /**
115 * Returns an element of the reference vector r.
116 *
117 * @param i Row of r.
118 *
119 * @return The row of the current reference vector.
120 */
121 double R(int i) const { return m_r(i); }
122
123 /**
124 * Resets the feedforward with a specified initial state vector.
125 *
126 * @param initialState The initial state vector.
127 */
128 void Reset(const StateVector& initialState) {
129 m_r = initialState;
130 m_uff.setZero();
131 }
132
133 /**
134 * Resets the feedforward with a zero initial state vector.
135 */
136 void Reset() {
137 m_r.setZero();
138 m_uff.setZero();
139 }
140
141 /**
142 * Calculate the feedforward with only the desired
143 * future reference. This uses the internally stored "current"
144 * reference.
145 *
146 * If this method is used the initial state of the system is the one set using
147 * Reset(const StateVector&). If the initial state is not
148 * set it defaults to a zero vector.
149 *
150 * @param nextR The reference state of the future timestep (k + dt).
151 *
152 * @return The calculated feedforward.
153 */
155 return Calculate(m_r, nextR);
156 }
157
158 /**
159 * Calculate the feedforward with current and future reference vectors.
160 *
161 * @param r The reference state of the current timestep (k).
162 * @param nextR The reference state of the future timestep (k + dt).
163 *
164 * @return The calculated feedforward.
165 */
167 StateVector rDot = (nextR - r) / m_dt.value();
168
169 // ṙ = f(r) + Bu
170 // Bu = ṙ − f(r)
171 // u = B⁺(ṙ − f(r))
172 m_uff = m_B.householderQr().solve(rDot - m_f(r, InputVector::Zero()));
173
174 m_r = nextR;
175 return m_uff;
176 }
177
178 private:
180
181 units::second_t m_dt;
182
183 /**
184 * The model dynamics.
185 */
186 std::function<StateVector(const StateVector&, const InputVector&)> m_f;
187
188 // Current reference
189 StateVector m_r;
190
191 // Computed feedforward
192 InputVector m_uff;
193};
194
195} // namespace frc
Constructs a control-affine plant inversion model-based feedforward from given model dynamics.
Definition: ControlAffinePlantInversionFeedforward.h:41
const InputVector & Uff() const
Returns the previously calculated feedforward as an input vector.
Definition: ControlAffinePlantInversionFeedforward.h:96
InputVector Calculate(const StateVector &nextR)
Calculate the feedforward with only the desired future reference.
Definition: ControlAffinePlantInversionFeedforward.h:154
Vectord< Inputs > InputVector
Definition: ControlAffinePlantInversionFeedforward.h:44
double R(int i) const
Returns an element of the reference vector r.
Definition: ControlAffinePlantInversionFeedforward.h:121
InputVector Calculate(const StateVector &r, const StateVector &nextR)
Calculate the feedforward with current and future reference vectors.
Definition: ControlAffinePlantInversionFeedforward.h:166
void Reset()
Resets the feedforward with a zero initial state vector.
Definition: ControlAffinePlantInversionFeedforward.h:136
Vectord< States > StateVector
Definition: ControlAffinePlantInversionFeedforward.h:43
ControlAffinePlantInversionFeedforward(std::function< StateVector(const StateVector &, const InputVector &)> f, units::second_t dt)
Constructs a feedforward with given model dynamics as a function of state and input.
Definition: ControlAffinePlantInversionFeedforward.h:56
void Reset(const StateVector &initialState)
Resets the feedforward with a specified initial state vector.
Definition: ControlAffinePlantInversionFeedforward.h:128
const StateVector & R() const
Returns the current reference vector r.
Definition: ControlAffinePlantInversionFeedforward.h:112
ControlAffinePlantInversionFeedforward(std::function< StateVector(const StateVector &)> f, const Matrixd< States, Inputs > &B, units::second_t dt)
Constructs a feedforward with given model dynamics as a function of state, and the plant's B matrix(c...
Definition: ControlAffinePlantInversionFeedforward.h:75
double Uff(int i) const
Returns an element of the previously calculated feedforward.
Definition: ControlAffinePlantInversionFeedforward.h:105
ControlAffinePlantInversionFeedforward(ControlAffinePlantInversionFeedforward &&)=default
ControlAffinePlantInversionFeedforward & operator=(ControlAffinePlantInversionFeedforward &&)=default
Definition: AprilTagPoseEstimator.h:15
Eigen::Matrix< double, Rows, Cols, Options, MaxRows, MaxCols > Matrixd
Definition: EigenCore.h:21
Eigen::Vector< double, Size > Vectord
Definition: EigenCore.h:12