Brick
Toggle main menu visibility
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
10
#include "
core/math/controls/feedforward.h
"
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
*/
24
template
<
int
STATES,
int
INPUTS>
25
class
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>
35
LinearPlantInversionFeedforward
(
LinearSystem<STATES, INPUTS, OUTPUTS>
& plant,
const
double
& dt)
36
:
LinearPlantInversionFeedforward
(plant.A(), plant.B(), dt) {}
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
};
FeedForward
pure virtual class for generic feedforward control systems.
Definition
feedforward.h:19
LinearPlantInversionFeedforward::calculate
EVec< INPUTS > calculate(const EVec< STATES > &next_r, const units::Time &dt)
Definition
linear_plant_inversion_ff.h:124
LinearPlantInversionFeedforward::LinearPlantInversionFeedforward
LinearPlantInversionFeedforward(LinearSystem< STATES, INPUTS, OUTPUTS > &plant, const double &dt)
Definition
linear_plant_inversion_ff.h:35
LinearPlantInversionFeedforward::calculate
EVec< INPUTS > calculate(const EVec< STATES > &r, const EVec< STATES > &next_r)
Definition
linear_plant_inversion_ff.h:61
LinearPlantInversionFeedforward::calculate
EVec< INPUTS > calculate(const EVec< STATES > &next_r) override
Definition
linear_plant_inversion_ff.h:80
LinearPlantInversionFeedforward::calculate
EVec< INPUTS > calculate(const EVec< STATES > &r, const EVec< STATES > &next_r, const units::Time &dt)
Definition
linear_plant_inversion_ff.h:100
LinearPlantInversionFeedforward::LinearPlantInversionFeedforward
LinearPlantInversionFeedforward(const EMat< STATES, STATES > &A, const EMat< STATES, INPUTS > &B, const double &dt)
Definition
linear_plant_inversion_ff.h:45
LinearPlantInversionFeedforward::reset
void reset() override
Resets the reference to all zeros, and the feedforward to zero.
Definition
linear_plant_inversion_ff.h:139
LinearPlantInversionFeedforward::reset
void reset(const EVec< STATES > &initial_state)
Definition
linear_plant_inversion_ff.h:133
LinearSystem
Definition
linear_system.h:16
feedforward.h
A pure virual class to function as an interface for all feedforward control systems.
core
math
controls
linear_plant_inversion_ff.h
Generated by
1.18.0