Brick
Loading...
Searching...
No Matches
linear_plant_inversion_ff.h
Go to the documentation of this file.
1/**
2 * @file linear_plant_inversion_ff.h
3 * @brief A control system that uses inverted discrete plant dynamics to get an output value
4 *
5 * It calculates the input for a feedforward control by inverting discrete plant dynamics.
6 */
7
8#pragma once
9
11#include "core/math/eigen_interface.h"
12#include "core/math/systems/discretization.h"
13#include "core/math/systems/linear_system.h"
14#include "core/math/units.h"
15
16/**
17 * This class computes a feedforward control input by inverting the discrete
18 * plant dynamics. A continuous linear system is provided, it is then
19 * discretized on some timestep, then the feedforward control input
20 * is computed to satisfy:
21 *
22 * B_d * u_ff = next_state - A_d * current_state
23 */
24template <int STATES, int INPUTS>
25class LinearPlantInversionFeedforward : public FeedForward<EVec<STATES>, EVec<INPUTS>> {
26 public:
27 /**
28 * Constructs a feedforward given a plant and the nominal timestep.
29 *
30 * @tparam OUTPUTS The number of outputs of the plant.
31 * @param plant The linear system.
32 * @param dt The nominal timestep in seconds.
33 */
34 template <int OUTPUTS>
37
38 /**
39 * Construts a feedforward given the state and input matrices from a plant.
40 *
41 * @param A The state matrix of the linear system.
42 * @param B The input matrix of the linear system.
43 * @param dt The nominal timestep in seconds.
44 */
45 LinearPlantInversionFeedforward(const EMat<STATES, STATES>& A, const EMat<STATES, INPUTS>& B,
46 const double& dt)
47 : A_(A), B_(B) {
48 auto [Ad, Bd] = discretize_AB(A, B, dt);
49 Ad_ = Ad;
50 Bd_ = Bd;
51 }
52
53 /**
54 * Computes the feedforward control input given the current reference state
55 * and the next reference state. This also sets the current reference state
56 * to the next reference state for you.
57 *
58 * @param r The current reference state.
59 * @param next_r The next reference state.
60 */
61 EVec<INPUTS> calculate(const EVec<STATES>& r, const EVec<STATES>& next_r) {
62 /*
63 * ẋ = Ax + Bu
64 * Bu = ẋ - Ax
65 * u = B \ (ẋ - Ax)
66 * u = B \ (next_r - Ar)
67 */
68 this->output_ = Bd_.householderQr().solve(next_r - (Ad_ * r));
69 this->reference_ = next_r;
70
71 return this->output_;
72 }
73
74 /**
75 * Computes the feedforward control input given only the next reference state.
76 * This assumes that the previous reference is already set.
77 *
78 * @param next_r The next reference state.
79 */
80 EVec<INPUTS> calculate(const EVec<STATES>& next_r) override {
81 this->reference_ = next_r;
82 this->output_ = calculate(this->reference_, next_r);
83
84 return this->output_;
85 }
86
87 /**
88 * Computes the feedforward control input given the current reference state
89 * and the next reference state. This also sets the current reference state
90 * to the next reference state for you. Use this function if your timestep
91 * is not the same between each run.
92 *
93 * This is slower because it discretizes A and B on each run, requiring
94 * computing a matrix exponential. Don't use this unless you have to.
95 *
96 * @param r The current reference state.
97 * @param next_r The next reference state.
98 * @param dt The timestep for this run.
99 */
100 EVec<INPUTS> calculate(const EVec<STATES>& r, const EVec<STATES>& next_r, const units::Time& dt) {
101 auto [Ad, Bd] = discretize_AB(A_, B_, dt);
102 /*
103 * ẋ = Ax + Bu
104 * Bu = ẋ - Ax
105 * u = B \ (ẋ - Ax)
106 * u = B \ (next_r - Ar)
107 */
108 this->output_ = Bd.householderQr().solve(next_r - (Ad * r));
109 this->reference_ = next_r;
110
111 return this->output_;
112 }
113
114 /**
115 * Computes the feedforward control input given only the next reference state.
116 * This assumes that the previous reference is already set.
117 *
118 * This is slower because it discretizes A and B on each run, requiring
119 * computing a matrix exponential. Don't use this unless you have to.
120 *
121 * @param next_r The next reference state.
122 * @param dt The timestep for this run.
123 */
124 EVec<INPUTS> calculate(const EVec<STATES>& next_r, const units::Time& dt) {
125 return calculate(this->reference_, next_r, dt);
126 }
127
128 /**
129 * Resets the reference to the given state, and the feedforward to zero.
130 *
131 * @param initial_state The state to set the current reference to.
132 */
133 void reset(const EVec<STATES>& initial_state) {
134 this->reference_ = initial_state;
135 this->output_.setZero();
136 }
137
138 /// Resets the reference to all zeros, and the feedforward to zero.
139 void reset() override {
140 this->reference_.setZero();
141 this->output_.setZero();
142 }
143
144 private:
145 // The continuous system matrices
146 EMat<STATES, STATES> A_;
147 EMat<STATES, INPUTS> B_;
148
149 // The discrete system matrices discretized on the nominal timestep
150 EMat<STATES, STATES> Ad_;
151 EMat<STATES, INPUTS> Bd_;
152};
pure virtual class for generic feedforward control systems.
Definition feedforward.h:19
EVec< INPUTS > calculate(const EVec< STATES > &next_r, const units::Time &dt)
Definition linear_plant_inversion_ff.h:124
LinearPlantInversionFeedforward(LinearSystem< STATES, INPUTS, OUTPUTS > &plant, const double &dt)
Definition linear_plant_inversion_ff.h:35
EVec< INPUTS > calculate(const EVec< STATES > &r, const EVec< STATES > &next_r)
Definition linear_plant_inversion_ff.h:61
EVec< INPUTS > calculate(const EVec< STATES > &next_r) override
Definition linear_plant_inversion_ff.h:80
EVec< INPUTS > calculate(const EVec< STATES > &r, const EVec< STATES > &next_r, const units::Time &dt)
Definition linear_plant_inversion_ff.h:100
LinearPlantInversionFeedforward(const EMat< STATES, STATES > &A, const EMat< STATES, INPUTS > &B, const double &dt)
Definition linear_plant_inversion_ff.h:45
void reset() override
Resets the reference to all zeros, and the feedforward to zero.
Definition linear_plant_inversion_ff.h:139
void reset(const EVec< STATES > &initial_state)
Definition linear_plant_inversion_ff.h:133
Definition linear_system.h:16
A pure virual class to function as an interface for all feedforward control systems.