Autoware.Auto
kalman_filter.hpp
Go to the documentation of this file.
1 // Copyright 2021 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Developed by Apex.AI, Inc.
16 
21 
22 #ifndef KALMAN_FILTER__KALMAN_FILTER_HPP_
23 #define KALMAN_FILTER__KALMAN_FILTER_HPP_
24 
29 
30 #include <Eigen/LU>
31 
32 #include <limits>
33 #include <vector>
34 
35 namespace autoware
36 {
37 namespace prediction
38 {
45 template<typename MotionModelT, typename NoiseModelT>
46 class KALMAN_FILTER_PUBLIC KalmanFilter
47  : public FilterInterface<KalmanFilter<MotionModelT, NoiseModelT>>
48 {
49  static_assert(
50  std::is_base_of<MotionModelInterface<MotionModelT>, MotionModelT>::value,
51  "\n\nMotion model must inherit from MotionModelInterface\n\n");
52  static_assert(
53  std::is_base_of<NoiseInterface<NoiseModelT>, NoiseModelT>::value,
54  "\n\nNoise model must inherit from NoiseInterface\n\n");
55  static_assert(
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");
58 
59 public:
60  using State = typename MotionModelT::State;
61  using StateMatrix = typename State::Matrix;
62  using MotionModel = MotionModelT;
63  using NoiseModel = NoiseModelT;
64 
73  explicit KalmanFilter(
74  MotionModelT motion_model,
75  NoiseModelT noise_model,
76  const State & initial_state,
77  const StateMatrix & initial_covariance)
78  : m_motion_model{motion_model},
79  m_noise_model{noise_model},
80  m_state{initial_state},
81  m_covariance{initial_covariance} {}
82 
90  State crtp_predict(const std::chrono::nanoseconds & dt)
91  {
92  m_state = m_motion_model.predict(m_state, dt);
93  const auto & motion_jacobian = m_motion_model.jacobian(m_state, dt);
94  m_covariance =
95  motion_jacobian * m_covariance * motion_jacobian.transpose() + m_noise_model.covariance(dt);
96  return m_state;
97  }
98 
110  template<typename MeasurementT>
111  State crtp_correct(const MeasurementT & measurement)
112  {
113  const auto expected_measurement = measurement.create_new_instance_from(m_state);
114  // TODO(#994): wrap the angles of the innovation vector. Probably as part of the 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();
121  // TODO(#944): wrap the angles of the resulting vector.
122  m_state.vector() += kalman_gain * innovation;
123  m_covariance = (State::Matrix::Identity() - kalman_gain * mapping_matrix) * m_covariance;
124  return m_state;
125  }
126 
133  void crtp_reset(const State & state, const StateMatrix & covariance)
134  {
135  m_state = state;
136  m_covariance = covariance;
137  }
138 
140  auto & crtp_state() {return m_state;}
142  const auto & crtp_state() const {return m_state;}
143 
145  auto & crtp_covariance() {return m_covariance;}
147  const auto & crtp_covariance() const {return m_covariance;}
148 
149 private:
151  MotionModelT m_motion_model{};
153  NoiseModelT m_noise_model{};
155  State m_state{};
157  StateMatrix m_covariance{StateMatrix::Zero()};
158 };
159 
176 template<typename MotionModelT, typename NoiseModelT>
178  const MotionModelT & motion_model,
179  const NoiseModelT & noise_model,
180  const typename MotionModelT::State & initial_state,
181  const typename MotionModelT::State::Matrix & initial_covariance)
182 {
184  motion_model, noise_model, initial_state, initial_covariance};
185 }
186 
203 template<typename MotionModelT, typename NoiseModelT>
205  const MotionModelT & motion_model,
206  const NoiseModelT & noise_model,
207  const typename MotionModelT::State & initial_state,
208  const std::vector<typename MotionModelT::State::Scalar> & initial_variances)
209 {
210  using State = typename MotionModelT::State;
211  if (initial_variances.size() != static_cast<std::size_t>(State::size())) {
212  std::runtime_error(
213  "Cannot create Kalman filter - dimensions mismatch. Provided " +
214  std::to_string(initial_variances.size()) + " variances, but " +
215  std::to_string(State::size()) + " required.");
216  }
217  typename State::Vector variances{State::Vector::Zero()};
218  // A small enough epsilon to compare a floating point variance with 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) {
221  if (common::helper_functions::comparisons::abs_lte(initial_variances[i], 0.0F, epsilon)) {
222  throw std::domain_error("Variances must be positive");
223  }
224  variances[static_cast<std::int32_t>(i)] = initial_variances[i] * initial_variances[i];
225  }
227  motion_model, noise_model, initial_state, variances.asDiagonal()};
228 }
229 
230 } // namespace prediction
231 } // namespace autoware
232 
233 #endif // KALMAN_FILTER__KALMAN_FILTER_HPP_
autoware::prediction::KalmanFilter::crtp_state
auto & crtp_state()
Get current state.
Definition: kalman_filter.hpp:140
filter_interface.hpp
This file defines a filter interface.
autoware::prediction::KalmanFilter::crtp_covariance
const auto & crtp_covariance() const
Get current covariance.
Definition: kalman_filter.hpp:147
autoware::common::helper_functions::comparisons::abs_lte
bool abs_lte(const T &a, const T &b, const T &eps)
Check for approximate less than or equal in absolute terms.
Definition: float_comparisons.hpp:69
autoware::prediction::MotionModelInterface
A CRTP interface for any motion model.
Definition: motion_model_interface.hpp:41
autoware::prediction::KalmanFilter::crtp_correct
State crtp_correct(const MeasurementT &measurement)
Correct the predicted state given a measurement.
Definition: kalman_filter.hpp:111
motion_model_interface.hpp
This file defines an interface for the motion model.
autoware::prediction::KalmanFilter< MotionModel, NoiseModel >::MotionModel
MotionModel MotionModel
Definition: kalman_filter.hpp:62
autoware::prediction::NoiseInterface
A CRTP interface for implementing noise models used for providing motion model noise covariance.
Definition: noise_interface.hpp:41
motion::motion_common::State
autoware_auto_msgs::msg::VehicleKinematicState State
Definition: motion_common.hpp:36
autoware::prediction::KalmanFilter::crtp_reset
void crtp_reset(const State &state, const StateMatrix &covariance)
Reset the state of the filter to a given state and covariance.
Definition: kalman_filter.hpp:133
autoware
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24
float_comparisons.hpp
noise_interface.hpp
This file contains a definition for the noise interface.
autoware::prediction::KalmanFilter< MotionModel, NoiseModel >::State
typename MotionModel ::State State
Definition: kalman_filter.hpp:60
autoware::prediction::KalmanFilter< MotionModel, NoiseModel >::NoiseModel
NoiseModel NoiseModel
Definition: kalman_filter.hpp:63
autoware::prediction::FilterInterface
Interface for a filter that can be used to track an object.
Definition: filter_interface.hpp:42
autoware::prediction::KalmanFilter::crtp_predict
State crtp_predict(const std::chrono::nanoseconds &dt)
Predict next state.
Definition: kalman_filter.hpp:90
autoware::prediction::make_kalman_filter
auto make_kalman_filter(const MotionModelT &motion_model, const NoiseModelT &noise_model, const typename MotionModelT::State &initial_state, const typename MotionModelT::State::Matrix &initial_covariance)
A utility function that creates a Kalman filter.
Definition: kalman_filter.hpp:177
autoware::prediction::KalmanFilter::crtp_state
const auto & crtp_state() const
Get current state.
Definition: kalman_filter.hpp:142
autoware::prediction::KalmanFilter
A Kalman filter implementation.
Definition: kalman_filter.hpp:46
autoware::prediction::KalmanFilter::KalmanFilter
KalmanFilter(MotionModelT motion_model, NoiseModelT noise_model, const State &initial_state, const StateMatrix &initial_covariance)
Constructs a new instance of a Kalman filter.
Definition: kalman_filter.hpp:73
autoware::prediction::KalmanFilter::crtp_covariance
auto & crtp_covariance()
Get current covariance.
Definition: kalman_filter.hpp:145
autoware::prediction::KalmanFilter< MotionModel, NoiseModel >::StateMatrix
typename State::Matrix StateMatrix
Definition: kalman_filter.hpp:61