22 #ifndef KALMAN_FILTER__KALMAN_FILTER_HPP_
23 #define KALMAN_FILTER__KALMAN_FILTER_HPP_
45 template<
typename MotionModelT,
typename NoiseModelT>
51 "\n\nMotion model must inherit from MotionModelInterface\n\n");
54 "\n\nNoise model must inherit from NoiseInterface\n\n");
56 std::is_same<typename MotionModelT::State, typename NoiseModelT::State>::value,
57 "\n\nMotion model and noise model must have the same underlying state\n\n");
74 MotionModelT motion_model,
75 NoiseModelT noise_model,
76 const State & initial_state,
78 : m_motion_model{motion_model},
79 m_noise_model{noise_model},
80 m_state{initial_state},
81 m_covariance{initial_covariance} {}
92 m_state = m_motion_model.predict(m_state, dt);
93 const auto & motion_jacobian = m_motion_model.jacobian(m_state, dt);
95 motion_jacobian * m_covariance * motion_jacobian.transpose() + m_noise_model.covariance(dt);
110 template<
typename MeasurementT>
113 const auto expected_measurement = measurement.create_new_instance_from(m_state);
115 const auto innovation = measurement.state().vector() - expected_measurement.vector();
116 const auto mapping_matrix = measurement.mapping_matrix_from(m_state);
117 const auto innovation_covariance =
118 mapping_matrix * m_covariance * mapping_matrix.transpose() + measurement.covariance();
119 const auto kalman_gain =
120 m_covariance * mapping_matrix.transpose() * innovation_covariance.inverse();
122 m_state.vector() += kalman_gain * innovation;
123 m_covariance = (State::Matrix::Identity() - kalman_gain * mapping_matrix) * m_covariance;
136 m_covariance = covariance;
151 MotionModelT m_motion_model{};
153 NoiseModelT m_noise_model{};
157 StateMatrix m_covariance{StateMatrix::Zero()};
176 template<
typename MotionModelT,
typename NoiseModelT>
178 const MotionModelT & motion_model,
179 const NoiseModelT & noise_model,
181 const typename MotionModelT::State::Matrix & initial_covariance)
184 motion_model, noise_model, initial_state, initial_covariance};
203 template<
typename MotionModelT,
typename NoiseModelT>
205 const MotionModelT & motion_model,
206 const NoiseModelT & noise_model,
208 const std::vector<typename MotionModelT::State::Scalar> & initial_variances)
211 if (initial_variances.size() !=
static_cast<std::size_t
>(State::size())) {
213 "Cannot create Kalman filter - dimensions mismatch. Provided " +
214 std::to_string(initial_variances.size()) +
" variances, but " +
215 std::to_string(State::size()) +
" required.");
217 typename State::Vector variances{State::Vector::Zero()};
219 const auto epsilon = 5.0F * std::numeric_limits<common::types::float32_t>::epsilon();
220 for (std::uint32_t i = 0; i < initial_variances.size(); ++i) {
222 throw std::domain_error(
"Variances must be positive");
224 variances[
static_cast<std::int32_t
>(i)] = initial_variances[i] * initial_variances[i];
227 motion_model, noise_model, initial_state, variances.asDiagonal()};
233 #endif // KALMAN_FILTER__KALMAN_FILTER_HPP_