WarpTwin
Documentation for WarpTwin models and classes.
Loading...
Searching...
No Matches
EkfMeasurementUpdate.hpp
Go to the documentation of this file.
1/******************************************************************************
2* Copyright (c) ATTX LLC 2024. All Rights Reserved.
3*
4* This software and associated documentation (the "Software") are the
5* proprietary and confidential information of ATTX, LLC. The Software is
6* furnished under a license agreement between ATTX and the user organization
7* and may be used or copied only in accordance with the terms of the agreement.
8* Refer to 'license/attx_license.adoc' for standard license terms.
9*
10* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
11* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION
12* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or
13* transmitted in any form or by any means, for any purpose, without the express
14* written permission of ATTX, LLC.
15******************************************************************************/
16
17#ifndef GNCUTILS_EKF_EKF_MEASUREMENT_UPDATE_HPP
18#define GNCUTILS_EKF_EKF_MEASUREMENT_UPDATE_HPP
19
20#include "core/Matrix.hpp"
23
24namespace warpos {
25 const floating_point MINIMUM_COV_DIAG_EPSILON = 1e-6;
26
48 template <uint32 N, uint32 M, uint32 O>
50 public:
53
61 int16 generateResidual(floating_point time,
62 const std::array<floating_point, N> &state_minus,
63 const std::array<floating_point, O> &obs_state,
64 const std::array<floating_point, M> &measurement,
65 std::array<floating_point, M> *residual);
66
76 int16 runUpdate(floating_point time,
77 const std::array<floating_point, N> &state_minus,
78 const clockwerk::Matrix<N, N> &cov_minus,
79 const std::array<floating_point, O> &obs_state,
80 const std::array<floating_point, M> &residual,
81 std::array<floating_point, N> *state_plus,
82 clockwerk::Matrix<N, N> *cov_plus);
83
87 private:
90 Measurements<N, M, O> &measurement_ref;
91
92 // Error code for internal use
93 int16 _error;
94
95 // Identity matrix for calculation
96 clockwerk::Matrix<N, N> _identity_n_n;
97
98 // Measurement vector from estimated state for internal use
99 std::array<floating_point, M> _est_meas;
100
101 // H matrix (measurement function jacobian) for internal use
102 std::array<floating_point, M*N> _tmp_H_array;
105
106 // R matrix (measurement noise covariance) for internal use
107 std::array<floating_point, M*M> _tmp_R_array;
109
110 // W matrix (innovation covariance) for internal use
111 clockwerk::Matrix<M, M> _W, _W_inv;
112
113 // K matrix (Kalman gain) for internal use
115
116 // Covariance input
117 clockwerk::Matrix<N, N> _cov_input;
118
119 // Temporary variables for updating the state mean
121 clockwerk::Matrix<M, 1> _residual;
122
123 clockwerk::Matrix<N, N> _tmp_n_n_1;
124 clockwerk::Matrix<N, N> _tmp_n_n_2;
125 clockwerk::Matrix<N, M> _tmp_n_m_1;
126 clockwerk::Matrix<M, N> _tmp_m_n_1;
127 clockwerk::Matrix<M, M> _tmp_m_m_1;
128 };
129
130 template <uint32 N, uint32 M, uint32 O>
132 : measurement_ref(measurement_ref) {
133 for(unsigned int i = 0; i < N; i++) {
134 _identity_n_n[i][i] = 1.0;
135 }
136 }
137
138 template <uint32 N, uint32 M, uint32 O>
140 const std::array<floating_point, N> &state_minus,
141 const std::array<floating_point, O> &obs_state,
142 const std::array<floating_point, M> &measurement,
143 std::array<floating_point, M> *residual) {
144 // Verify our output pointers are set
145 if(residual == nullptr) {
146 return ERROR_NULLPTR;
147 }
148
149 // Calculate our estimated measurement
150 _error = measurement_ref.calculateMeasurements(time, state_minus, obs_state, _est_meas.data());
151 if(_error) {return _error;}
152
153 // Calculate our residual
154 for(uint32 i = 0; i < M; i++) {
155 (*residual)[i] = measurement[i] - _est_meas[i];
156 }
157
158 return NO_ERROR;
159 }
160
161 template <uint32 N, uint32 M, uint32 O>
163 const std::array<floating_point, N> &state_minus,
164 const clockwerk::Matrix<N, N> &cov_minus,
165 const std::array<floating_point, O> &obs_state,
166 const std::array<floating_point, M> &residual,
167 std::array<floating_point, N> *state_plus,
168 clockwerk::Matrix<N, N> *cov_plus) {
169 // Verify our output pointers are set
170 if(state_plus == nullptr || cov_plus == nullptr) {
171 return ERROR_NULLPTR;
172 }
173
174 // ----- First get measurement function outputs ----- //
175 // Measurement function Jacobian and transpose
176 _error = measurement_ref.calculateMeasurementsMatrix(time, state_minus, obs_state, _tmp_H_array.data());
177 if (_error) {return _error;}
178 _H.setFromArray(&_tmp_H_array[0]);
179 _H.transpose(_H_tpose);
180
181 // Copy into our input covariance
182 for(uint32 i = 0; i < N; i++) {
183 for(uint32 j = 0; j < N; j++) {
184 if(i == j) {
185 _cov_input[i][j] = cov_minus.get(i, j) < MINIMUM_COV_DIAG_EPSILON ? MINIMUM_COV_DIAG_EPSILON : cov_minus.get(i, j);
186 } else {
187 _cov_input[i][j] = cov_minus.get(i, j);
188 }
189 }
190 }
191 // And enforce symmetry
192 clockwerk::eAdd(_cov_input, _cov_input.transpose(), _cov_input);
193 clockwerk::multiply(0.5, _cov_input, _cov_input);
194
195 // Now compute the innovation covariance
196 clockwerk::multiply(_H, _cov_input, _tmp_m_n_1);
197 clockwerk::multiply(_tmp_m_n_1, _H_tpose, _tmp_m_m_1);
198 clockwerk::eAdd(_tmp_m_m_1, _R, _W);
199
200 // Now compute the Kalman gain
201 _error = _W.inverse(_W_inv);
202 if (_error) {return _error;}
203 clockwerk::multiply(_cov_input, _H_tpose, _tmp_n_m_1);
204 clockwerk::multiply(_tmp_n_m_1, _W_inv, _K);
205
206 // Calculate our update from our innovation
207 _residual.setFromArray(&residual[0]);
208 multiply(_K, _residual, _update);
209 for(uint32 i = 0; i < N; i++) {
210 (*state_plus)[i] = state_minus[i] + _update.get(i,0);
211 }
212
213 // Calculate our update covariance
214 clockwerk::multiply(_K, _H, _tmp_n_n_1);
215 clockwerk::eSubtract(_identity_n_n, _tmp_n_n_1, _tmp_n_n_1);
216 clockwerk::multiply(_tmp_n_n_1, _cov_input, _tmp_n_n_2);
217 clockwerk::multiply(_tmp_n_n_2, _tmp_n_n_1.transpose(), *cov_plus);
218 clockwerk::multiply(_K, _R, _tmp_n_m_1);
219 clockwerk::multiply(_tmp_n_m_1, _K.transpose(), _tmp_n_n_1);
220 clockwerk::eAdd(*cov_plus, _tmp_n_n_1, *cov_plus);
221
222 return NO_ERROR;
223 }
224
225}
226
227#endif
Matrix math implementation.
Definition Matrix.hpp:55
int16 get(uint32 row, uint32 col, floating_point &result) const
Function to get a single value in the matrix.
Definition Matrix.hpp:394
int16 generateResidual(floating_point time, const std::array< floating_point, N > &state_minus, const std::array< floating_point, O > &obs_state, const std::array< floating_point, M > &measurement, std::array< floating_point, M > *residual)
Function to generate the residual from the current state.
Definition EkfMeasurementUpdate.hpp:139
int16 runUpdate(floating_point time, const std::array< floating_point, N > &state_minus, const clockwerk::Matrix< N, N > &cov_minus, const std::array< floating_point, O > &obs_state, const std::array< floating_point, M > &residual, std::array< floating_point, N > *state_plus, clockwerk::Matrix< N, N > *cov_plus)
Function to perform state measurement update in EKF.
Definition EkfMeasurementUpdate.hpp:162
void setMeasurementNoiseMatrix(const clockwerk::Matrix< M, M > &R)
Set the R matrix for the measurement update.
Definition EkfMeasurementUpdate.hpp:86
EkfMeasurementUpdate(Measurements< N, M, O > &measurement_ref)
Constructor.
Definition EkfMeasurementUpdate.hpp:131
Definition Measurements.hpp:41
#define NO_ERROR
Error code in the case where matrix math executed successfully.
Definition clockwerkerrors.h:34
#define ERROR_NULLPTR
Error code in case of a null pointer.
Definition clockwerkerrors.h:60
void eSubtract(Matrix< R, C > A, Matrix< R, C > B, Matrix< R, C > &result)
Function to subtract B from A, element-wise.
Definition matrixmath.hpp:221
void eAdd(const Matrix< R, C > &A, const Matrix< R, C > &B, Matrix< R, C > &result)
Function to add two matrices element-wise.
Definition matrixmath.hpp:196
void multiply(const Matrix< R1, C1R2 > &A, const Matrix< C1R2, C2 > &B, Matrix< R1, C2 > &result)
Function to multiply two matrices.
Definition matrixmath.hpp:58
Definition DeadReckon.cpp:20
const floating_point MINIMUM_COV_DIAG_EPSILON
Definition EkfMeasurementUpdate.hpp:25