RIT VEXU Core API
Loading...
Searching...
No Matches
kalman_filter.h
1#pragma once
2
3#include "core/math/eigen_interface.h"
4
5#include "core/math/systems/linear_system.h"
6
24template <int STATES, int INPUTS, int OUTPUTS> class KalmanFilter {
25 public:
26 using StateVector = EVec<STATES>;
27 using InputVector = EVec<INPUTS>;
28 using OutputVector = EVec<OUTPUTS>;
29
30 using StateMatrix = EMat<STATES, STATES>;
31 using InputMatrix = EMat<STATES, INPUTS>;
32
41 LinearSystem<STATES, INPUTS, OUTPUTS> &plant, const StateVector &state_stddevs,
42 const OutputVector &measurement_stddevs
43 )
44 : KalmanFilter(plant.A(), plant.B(), plant.C(), plant.D(), state_stddevs, measurement_stddevs) {}
45
57 const StateMatrix &A, const InputMatrix &B, const EMat<OUTPUTS, STATES> &C, const EMat<OUTPUTS, INPUTS> &D,
58 const StateVector &state_stddevs, const OutputVector &measurement_stddevs
59 ) {
60 A_ = A;
61 B_ = B;
62 C_ = C;
63 D_ = D;
64
65 Q_ = state_stddevs.asDiagonal();
66 Q_ = Q_ * Q_.transpose();
67 R_ = measurement_stddevs.asDiagonal();
68 R_ = R_ * R_.transpose();
69
70 reset();
71 }
72
74 StateMatrix P() const { return P_; }
75
81 void set_P(const StateMatrix &P) { P_ = P; }
82
84 const StateVector &xhat() const { return xhat_; }
85
91 double xhat(int i) const { return xhat_(i); }
92
94 void set_xhat(const StateVector &xhat) { xhat_ = xhat; }
95
101 void set_xhat(int i, double value) { xhat_(i) = value; }
102
104 void reset() {
105 xhat_.setZero();
106 P_.setZero();
107 }
108
115 void predict(const InputVector &u, const double &dt) {
116 // Q is discrete sqrt(process noise)
117 EMat<STATES, STATES> Q = Q_ * dt;
118 auto [A, B] = discretize_AB(A_, B_, dt);
119
120 // Compute prior mean
121 xhat_ = A * xhat_ + B * u;
122
123 // Compute prior covariance
124 P_ = A * P_ * A.transpose() + Q;
125 }
126
133 void correct(const OutputVector &y, const InputVector &u) { correct<OUTPUTS>(y, u, C_, D_, R_); }
134
144 void correct(const OutputVector &y, const InputVector &u, const EMat<OUTPUTS, OUTPUTS> &R) {
145 correct<OUTPUTS>(y, u, C_, D_, R);
146 }
147
160 template <int ROWS>
162 const EVec<ROWS> &y, const InputVector &u, const EMat<ROWS, STATES> &C, const EMat<ROWS, INPUTS> &D,
163 const EMat<ROWS, ROWS> &R
164 ) {
165 /*
166 * Compute the innovation covariance
167 *
168 * Py = CPCᵀ + R
169 *
170 */
171 EMat<ROWS, ROWS> Py = C * P_ * C.transpose() + R;
172 /*
173 * Compute the optimal Kalamn gain
174 *
175 * K = (Py \ CPᵀ)ᵀ
176 *
177 */
178 EMat<STATES, ROWS> K = Py.transpose().ldlt().solve(C * P_.transpose()).transpose();
179 /*
180 * Compute the posterior mean
181 *
182 * x̂ = x̂ + K(y - (Cx̂ + Du))
183 *
184 */
185 xhat_ += K * (y - (C * xhat_ + D * u));
186 /*
187 * Compute the posterior covariance using the Joseph form update equation
188 *
189 * P = (I - KC)P(I - KC)ᵀ + KRKᵀ
190 *
191 */
192 P_ = (EMat<STATES, STATES>::Identity() - K * C) * P_ * (EMat<STATES, STATES>::Identity() - K * C).transpose() +
193 K * R * K.transpose();
194 }
195
196 private:
197 StateVector xhat_;
198 StateMatrix P_;
199
200 StateMatrix Q_;
201 EMat<OUTPUTS, OUTPUTS> R_;
202
203 StateMatrix A_;
204 EMat<STATES, INPUTS> B_;
205 EMat<OUTPUTS, STATES> C_;
206 EMat<OUTPUTS, INPUTS> D_;
207
208 double dt_;
209};
210
211// allow using both names
212template <int STATES, int INPUTS, int OUTPUTS> using KF = KalmanFilter<STATES, INPUTS, OUTPUTS>;
Definition kalman_filter.h:24
StateMatrix P() const
Returns the covariance matrix P.
Definition kalman_filter.h:74
void set_P(const StateMatrix &P)
Definition kalman_filter.h:81
const StateVector & xhat() const
Returns the current state estimate x-hat.
Definition kalman_filter.h:84
void correct(const OutputVector &y, const InputVector &u)
Definition kalman_filter.h:133
double xhat(int i) const
Definition kalman_filter.h:91
void reset()
Resets the filter.
Definition kalman_filter.h:104
KalmanFilter(const StateMatrix &A, const InputMatrix &B, const EMat< OUTPUTS, STATES > &C, const EMat< OUTPUTS, INPUTS > &D, const StateVector &state_stddevs, const OutputVector &measurement_stddevs)
Definition kalman_filter.h:56
void set_xhat(int i, double value)
Definition kalman_filter.h:101
void set_xhat(const StateVector &xhat)
Set the current state estimate x-hat.
Definition kalman_filter.h:94
KalmanFilter(LinearSystem< STATES, INPUTS, OUTPUTS > &plant, const StateVector &state_stddevs, const OutputVector &measurement_stddevs)
Definition kalman_filter.h:40
void correct(const EVec< ROWS > &y, const InputVector &u, const EMat< ROWS, STATES > &C, const EMat< ROWS, INPUTS > &D, const EMat< ROWS, ROWS > &R)
Definition kalman_filter.h:161
void correct(const OutputVector &y, const InputVector &u, const EMat< OUTPUTS, OUTPUTS > &R)
Definition kalman_filter.h:144
void predict(const InputVector &u, const double &dt)
Definition kalman_filter.h:115
Definition linear_system.h:16