My Project
ekf.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2024 robinAZERTY [https://github.com/robinAZERTY]
3  *
4  * This file is part of ESP32AlgebraFilters library.
5  *
6  * ESP32AlgebraFilters library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * ESP32AlgebraFilters library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with ESP32AlgebraFilters library. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef EKF_HPP
21 #define EKF_HPP
22 
23 #include "matrix.hpp"
24 #include "symMatrix.hpp"
25 using namespace operators;
26 
55 template <size_t x_dim, size_t u_dim, size_t c_dim = 1, size_t z_num = 1, typename T = float>
56 class Ekf
57 {
58 private:
59 
61  Vector_f3<T> f = nullptr;
62 
64  size_t z_dim[z_num] = {0};
65 
67  Vector_f2<T> h[z_num] = {nullptr};
68 
70  Matrix_f3<T> Fx = nullptr;
71  Matrix_f3<T> Fu = nullptr;
72  Matrix_f3<T> Fc = nullptr;
73 
75  Matrix_f2<T> H[z_num] = {nullptr};
76 
78  Vector<T> y[z_num];
79 
81  Matrix<T> H_val[z_num];
82 
84  symMatrix<T> pre_S[z_num];
85 
87  ldl_matrix<T> S_inv[z_num];
88 
90  Vector<T> h_val[z_num];
91 
93  Vector<T> prev_X = Vector<T>(x_dim);
94 
96  Matrix<T> Fx_val_T = Matrix<T>(x_dim, x_dim);
97  Matrix<T> Fu_val_T = Matrix<T>(u_dim, x_dim);
98  Matrix<T> Fc_val_T = Matrix<T>(c_dim, x_dim);
99 
101  rowMajorMatrix<T> K;
102 
104  Matrix<T> H_P[z_num];
105 
106  inline void finite_diff_Fx(const size_t i);
107  inline void finite_diff_Fu(const size_t i);
108 
116  void finite_diff_Fx()
117  {
118  for (size_t i = 0; i < x_dim; i++)
119  finite_diff_Fx(i);
120  };
121 
129  void finite_diff_Fu()
130  {
131  for (size_t i = 0; i < u_dim; i++)
132  finite_diff_Fu(i);
133  };
134 
143  void finite_diff_H(const size_t z_idx, const size_t i);
144 
146  void finite_diff_H(const size_t z_idx)
147  {
148  for (size_t i = 0; i < x_dim; i++)
149  finite_diff_H(z_idx, i);
150  };
151 
153  bool initted = false;
154 
155 public:
157  Vector<T> X = Vector<T>(x_dim);
158 
160  Vector<T> dx = Vector<T>(x_dim);
161 
163  symMatrix<T> P = symMatrix<T>(x_dim, x_dim);
164 
166  Vector<T> U = Vector<T>(u_dim);
167 
169  Vector<T> du = Vector<T>(u_dim);
170 
172  symMatrix<T> Cov_U = symMatrix<T>(u_dim);
173 
175  Vector<T> C = Vector<T>(c_dim);
176 
178  Vector<T> dc = Vector<T>(c_dim);
179 
186  Ekf();
187 
189  Ekf(Vector_f3<T> f) : Ekf() { setPredictionFunction(f); }
190 
192  ~Ekf() {};
193 
195  void setPredictionFunction(Vector_f3<T> f) { this->f = f; }
196 
198  void setJacobianFunction_Fx(Matrix_f3<T> Fx) { this->Fx = Fx; }
199 
201  void setJacobianFunction_Fu(Matrix_f3<T> Fu) { this->Fu = Fu; }
202 
213  void setMeasurementFunction(Vector_f2<T> h, size_t z_dim, size_t z_idx = 0);
214 
216  void setJacobianFunction_H(Matrix_f2<T> H, size_t z_idx = 0) { this->H[z_idx] = H; }
217 
226  inline void predict();
227 
235  inline void compute_H_P(const size_t z_idx = 0);
236 
246  inline void computeResidualPrecision(const symMatrix<T> &R, const size_t z_idx = 0);
247 
256  inline void computeResidual(const Vector<T> &Z, const size_t z_idx = 0);
257 
266  inline void updateStateCovariance(const size_t z_idx = 0);
267 
279  inline T mahalanobisDistance(const size_t z_idx = 0) { return y[z_idx].dot(*(S_inv[z_idx] * y[z_idx]).release()); }
280 
300  inline void update(const Vector<T> &Z, const symMatrix<T> &R, const size_t z_idx = 0);
301 };
302 
303 #ifndef EKF_CPP
304 #include "ekf.cpp"
305 #endif
306 
307 #endif // EKF_HPP
A generic implementation of an Extended Kalman Filter (EKF).