Controlpp
Loading...
Searching...
No Matches
KalmanFilter.hpp
Go to the documentation of this file.
1#pragma once
2
3// std
4#include <concepts>
5
6// Eigen
7#include <Eigen/Core>
8#include <Eigen/Dense>
9
10namespace controlpp
11{
12
99 template<class T, int NStates, int NMeasurements=1, int NInputs = 0>
101 private:
102
103 Eigen::Matrix<T, NStates, NStates> _A;
104 Eigen::Matrix<T, NMeasurements, NStates> _H;
105 Eigen::Matrix<T, NStates, NInputs> _B;
106 Eigen::Matrix<T, NStates, NStates> _P;
107 Eigen::Matrix<T, NMeasurements, NMeasurements> _R;
108 Eigen::Matrix<T, NStates, NStates> _Q;
109
110 Eigen::Vector<T, NStates> _x;
111
112 public:
113
125 template<
126 int AOptions_ = 0, int AMaxRows_ = NStates, int AMaxCols_ = NStates,
127 int HOptions_ = 0, int HMaxRows_ = NMeasurements, int HMaxCols_ = NStates,
128 int BOptions_ = 0, int BMaxRows_ = NStates, int BMaxCols_ = NInputs,
129 int ROptions_ = 0, int RMaxRows_ = NMeasurements, int RMaxCols_ = NMeasurements,
130 int POptions_ = 0, int PMaxRows_ = NStates, int PMaxCols_ = NStates,
131 int QOptions_ = 0, int QMaxRows_ = NStates, int QMaxCols_ = NStates
132 >
134 const Eigen::Matrix<T, NStates, NStates, AOptions_, AMaxRows_, AMaxCols_>& A,
135 const Eigen::Matrix<T, NMeasurements, NStates, HOptions_, HMaxRows_, HMaxCols_>& H,
136 const Eigen::Matrix<T, NStates, NInputs, BOptions_, BMaxRows_, BMaxCols_>& B = Eigen::Matrix<T, NStates, NInputs>::Zero(),
137 const Eigen::Matrix<T, NMeasurements, NMeasurements, ROptions_, RMaxRows_, RMaxCols_>& R = Eigen::Matrix<T, NMeasurements, NMeasurements>::Identity(),
138 const Eigen::Matrix<T, NStates, NStates, POptions_, PMaxRows_, PMaxCols_>& P_0 = Eigen::Matrix<T, NStates, NStates>::Identity()*static_cast<T>(1e+3),
139 const Eigen::Matrix<T, NStates, NStates, QOptions_, QMaxRows_, QMaxCols_>& Q = Eigen::Matrix<T, NStates, NStates>::Identity()*static_cast<T>(1e-2),
140 const Eigen::Vector<T, NStates>& x_0 = Eigen::Vector<T, NStates>::Zero()
141 )
142 : _A(A)
143 , _H(H)
144 , _B(B)
145 , _P(P_0)
146 , _R(R)
147 , _Q(Q)
148 , _x(x_0){}
149
153 template<int AOptions_ = 0, int AMaxRows_ = NStates, int AMaxCols_ = NStates>
154 KalmanFilter& setA(const Eigen::Matrix<T, NStates, NStates, AOptions_, AMaxRows_, AMaxCols_>& new_A){this->_A = new_A; return *this;}
155
159 template<int AOptions_ = 0, int AMaxRows_ = NStates, int AMaxCols_ = NStates>
160 KalmanFilter& setSystemMatrix(const Eigen::Matrix<T, NStates, NStates, AOptions_, AMaxRows_, AMaxCols_>& new_A){this->_A = new_A; return *this;}
161
165 template<int HOptions_ = 0, int HMaxRows_ = NMeasurements, int HMaxCols_ = NStates>
166 KalmanFilter& setH(const Eigen::Matrix<T, NMeasurements, NStates, HOptions_, HMaxRows_, HMaxCols_>& new_H){this->_H = new_H; return *this;}
167
171 template<int HOptions_ = 0, int HMaxRows_ = NMeasurements, int HMaxCols_ = NStates>
172 KalmanFilter& setObservationMatrix(const Eigen::Matrix<T, NMeasurements, NStates, HOptions_, HMaxRows_, HMaxCols_>& new_H){this->_H = new_H; return *this;}
173
177 template<int BOptions_ = 0, int BMaxRows_ = NStates, int BMaxCols_ = NInputs>
178 KalmanFilter& setB(const Eigen::Matrix<T, NStates, NInputs, BOptions_, BMaxRows_, BMaxCols_>& new_B){this->_B = new_B; return *this;}
179
183 template<int BOptions_ = 0, int BMaxRows_ = NStates, int BMaxCols_ = NInputs>
184 KalmanFilter& setControlInputMatrix(const Eigen::Matrix<T, NStates, NInputs, BOptions_, BMaxRows_, BMaxCols_>& new_B){this->_B = new_B; return *this;}
185
189 template<int ROptions_ = 0, int RMaxRows_ = NMeasurements, int RMaxCols_ = NMeasurements>
190 KalmanFilter& setR(const Eigen::Matrix<T, NMeasurements, NMeasurements, ROptions_, RMaxRows_, RMaxCols_>& new_R){this->_R = new_R; return *this;}
191
195 template<int ROptions_ = 0, int RMaxRows_ = NMeasurements, int RMaxCols_ = NMeasurements>
196 KalmanFilter& setMeasurementCovMatrix(const Eigen::Matrix<T, NMeasurements, NMeasurements, ROptions_, RMaxRows_, RMaxCols_>& new_R){this->_R = new_R; return *this;}
197
201 template<int POptions_ = 0, int PMaxRows_ = NStates, int PMaxCols_ = NStates>
202 KalmanFilter& setP(const Eigen::Matrix<T, NStates, NStates, POptions_, PMaxRows_, PMaxCols_>& new_P){this->_P = new_P; return *this;}
203
207 template<int POptions_ = 0, int PMaxRows_ = NStates, int PMaxCols_ = NStates>
208 KalmanFilter& setErrorCovMatrix(const Eigen::Matrix<T, NStates, NStates, POptions_, PMaxRows_, PMaxCols_>& new_P){this->_P = new_P; return *this;}
209
213 template<int QOptions_ = 0, int QMaxRows_ = NStates, int QMaxCols_ = NStates>
214 KalmanFilter& setQ(const Eigen::Matrix<T, NStates, NStates, QOptions_, QMaxRows_, QMaxCols_>& new_Q){this->_Q = new_Q; return *this;}
215
219 template<int QOptions_ = 0, int QMaxRows_ = NStates, int QMaxCols_ = NStates>
220 KalmanFilter& setProcessNoiseCovMatrix(const Eigen::Matrix<T, NStates, NStates, QOptions_, QMaxRows_, QMaxCols_>& new_Q){this->_Q = new_Q; return *this;}
221
225 template<int POptions_ = 0, int PMaxRows_ = NStates, int PMaxCols_ = NStates>
226 KalmanFilter& setx(const Eigen::Vector<T, NStates>& new_x){this->_x = new_x; return *this;}
227
231 template<int POptions_ = 0, int PMaxRows_ = NStates, int PMaxCols_ = NStates>
232 KalmanFilter& setStateVector(const Eigen::Vector<T, NStates>& new_x){this->_x = new_x; return *this;}
233
242 Eigen::Vector<T, NStates> makePrediction(const Eigen::Vector<T, NInputs>& u) const {
243 const Eigen::Vector<T, NStates> x_p = _A * _x + _B * u;
244 return x_p;
245 }
246
247 void add(const Eigen::Vector<T, NMeasurements>& z, const Eigen::Vector<T, NInputs>& u = Eigen::Vector<T, NInputs>::Zero()){
248 // 1. Prediction
249 const Eigen::Vector<T, NStates> x_p = makePrediction(u);
250 const Eigen::Matrix<T, NStates, NStates> P_p = _A * _P * _A.transpose() + _Q;
251
252 // 2. Update
253 // Kalman factor: K = P_p * _H.transpose() * (H * P_p * H.transpose() + R).inverse();
254 // U = P_p * _H.transpose()
255 // S = H * P_p * H.transpose() + R
256 // K = U * S.inverse();
257 // K = (S.transpose().inverse() * U.transpose()).transpose()
258 //
259 // > note S is already symetric, so no need to transpose
260 //
261 // K = (S.inverse() * U.transpose()).transpose()
262 const auto U = (P_p * _H.transpose()).eval();
263 const auto S1 = _H * P_p * _H.transpose() + _R;
264 const auto S = ((S1 + S1.transpose()) / 2).eval();
265 const Eigen::Matrix<T, NStates, NMeasurements> K = (S.llt().solve(U.transpose())).transpose();
266
267 _x = x_p + K * (z - _H * x_p);
268
269 const auto I = Eigen::Matrix<T, NStates, NStates>::Identity();
270 _P = (I - K * _H) * P_p;
271 }
272
274 template<std::same_as<T> U>
275 requires (NMeasurements == 1 && NInputs != 1)
276 void add(const U& z, const Eigen::Vector<U, NInputs>& u = Eigen::Vector<U, NInputs>::Zero()){
277 const Eigen::Vector<double, 1> v_z(z);
278 this->add(v_z, u);
279 }
280
282 template<std::same_as<T> U>
283 requires (NMeasurements != 1 && NInputs == 1)
284 void add(const Eigen::Vector<U, NMeasurements>& z, const U& u = static_cast<T>(0)){
285 const Eigen::Vector<double, 1> v_u(u);
286 this->add(z, v_u);
287 }
288
290 template<std::same_as<T> U>
291 requires (NMeasurements == 1 && NInputs == 1)
292 void add(const U& z, const U& u = static_cast<T>(0)){
293 const Eigen::Vector<double, 1> v_z(z);
294 const Eigen::Vector<double, 1> v_u(u);
295 this->add(v_z, v_u);
296 }
297
302 const Eigen::Vector<T, NStates>& estimate() const {
303 return this->_x;
304 }
305
310 const Eigen::Matrix<T, NStates, NStates>& errorCovariance() const {
311 return this->_P;
312 }
313
317 void reset(
318 const Eigen::Vector<T, NStates>& x_0 = Eigen::Vector<T, NStates>::Zero(),
319 const Eigen::Matrix<T, NStates, NStates>& P_0 = Eigen::Matrix<T, NStates, NStates>::Identity()*static_cast<T>(1e+3))
320 {
321 this->_P = P_0;
322 this->_x = x_0;
323 }
324
325 };
326
327} // namespace controlpp
Kalman filter.
Definition KalmanFilter.hpp:100
KalmanFilter(const Eigen::Matrix< T, NStates, NStates, AOptions_, AMaxRows_, AMaxCols_ > &A, const Eigen::Matrix< T, NMeasurements, NStates, HOptions_, HMaxRows_, HMaxCols_ > &H, const Eigen::Matrix< T, NStates, NInputs, BOptions_, BMaxRows_, BMaxCols_ > &B=Eigen::Matrix< T, NStates, NInputs >::Zero(), const Eigen::Matrix< T, NMeasurements, NMeasurements, ROptions_, RMaxRows_, RMaxCols_ > &R=Eigen::Matrix< T, NMeasurements, NMeasurements >::Identity(), const Eigen::Matrix< T, NStates, NStates, POptions_, PMaxRows_, PMaxCols_ > &P_0=Eigen::Matrix< T, NStates, NStates >::Identity() *static_cast< T >(1e+3), const Eigen::Matrix< T, NStates, NStates, QOptions_, QMaxRows_, QMaxCols_ > &Q=Eigen::Matrix< T, NStates, NStates >::Identity() *static_cast< T >(1e-2), const Eigen::Vector< T, NStates > &x_0=Eigen::Vector< T, NStates >::Zero())
Initialises a Kalman filter.
Definition KalmanFilter.hpp:133
KalmanFilter & setR(const Eigen::Matrix< T, NMeasurements, NMeasurements, ROptions_, RMaxRows_, RMaxCols_ > &new_R)
Sets the measurement covariance matrix.
Definition KalmanFilter.hpp:190
KalmanFilter & setStateVector(const Eigen::Vector< T, NStates > &new_x)
Sets the state vector.
Definition KalmanFilter.hpp:232
KalmanFilter & setProcessNoiseCovMatrix(const Eigen::Matrix< T, NStates, NStates, QOptions_, QMaxRows_, QMaxCols_ > &new_Q)
Sets the process noise covariance matrix.
Definition KalmanFilter.hpp:220
KalmanFilter & setQ(const Eigen::Matrix< T, NStates, NStates, QOptions_, QMaxRows_, QMaxCols_ > &new_Q)
Sets the process noise covariance matrix.
Definition KalmanFilter.hpp:214
void add(const Eigen::Vector< U, NMeasurements > &z, const U &u=static_cast< T >(0))
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition KalmanFilter.hpp:284
KalmanFilter & setB(const Eigen::Matrix< T, NStates, NInputs, BOptions_, BMaxRows_, BMaxCols_ > &new_B)
Sets the control input matrix.
Definition KalmanFilter.hpp:178
KalmanFilter & setx(const Eigen::Vector< T, NStates > &new_x)
Sets the state vector.
Definition KalmanFilter.hpp:226
KalmanFilter & setMeasurementCovMatrix(const Eigen::Matrix< T, NMeasurements, NMeasurements, ROptions_, RMaxRows_, RMaxCols_ > &new_R)
Sets the measurement covariance matrix.
Definition KalmanFilter.hpp:196
void add(const U &z, const Eigen::Vector< U, NInputs > &u=Eigen::Vector< U, NInputs >::Zero())
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition KalmanFilter.hpp:276
void reset(const Eigen::Vector< T, NStates > &x_0=Eigen::Vector< T, NStates >::Zero(), const Eigen::Matrix< T, NStates, NStates > &P_0=Eigen::Matrix< T, NStates, NStates >::Identity() *static_cast< T >(1e+3))
Resets the state vector and error covariance matrix.
Definition KalmanFilter.hpp:317
const Eigen::Matrix< T, NStates, NStates > & errorCovariance() const
returns the error covariance matrix
Definition KalmanFilter.hpp:310
const Eigen::Vector< T, NStates > & estimate() const
returns the current best estimate of the system states
Definition KalmanFilter.hpp:302
void add(const Eigen::Vector< T, NMeasurements > &z, const Eigen::Vector< T, NInputs > &u=Eigen::Vector< T, NInputs >::Zero())
Definition KalmanFilter.hpp:247
KalmanFilter & setErrorCovMatrix(const Eigen::Matrix< T, NStates, NStates, POptions_, PMaxRows_, PMaxCols_ > &new_P)
Sets the error covariance matrix.
Definition KalmanFilter.hpp:208
KalmanFilter & setSystemMatrix(const Eigen::Matrix< T, NStates, NStates, AOptions_, AMaxRows_, AMaxCols_ > &new_A)
Set the system matrix.
Definition KalmanFilter.hpp:160
KalmanFilter & setP(const Eigen::Matrix< T, NStates, NStates, POptions_, PMaxRows_, PMaxCols_ > &new_P)
Sets the error covariance matrix.
Definition KalmanFilter.hpp:202
KalmanFilter & setObservationMatrix(const Eigen::Matrix< T, NMeasurements, NStates, HOptions_, HMaxRows_, HMaxCols_ > &new_H)
Sets the observation matrix.
Definition KalmanFilter.hpp:172
KalmanFilter & setControlInputMatrix(const Eigen::Matrix< T, NStates, NInputs, BOptions_, BMaxRows_, BMaxCols_ > &new_B)
Sets the control input matrix.
Definition KalmanFilter.hpp:184
KalmanFilter & setH(const Eigen::Matrix< T, NMeasurements, NStates, HOptions_, HMaxRows_, HMaxCols_ > &new_H)
Sets the observation matrix.
Definition KalmanFilter.hpp:166
KalmanFilter & setA(const Eigen::Matrix< T, NStates, NStates, AOptions_, AMaxRows_, AMaxCols_ > &new_A)
Set the system matrix.
Definition KalmanFilter.hpp:154
void add(const U &z, const U &u=static_cast< T >(0))
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition KalmanFilter.hpp:292
Eigen::Vector< T, NStates > makePrediction(const Eigen::Vector< T, NInputs > &u) const
predicts the next system state
Definition KalmanFilter.hpp:242
The main namespace for the Control++ library.
Definition Bode.cpp:3