Autoware.Auto
kalman_filter.hpp
Go to the documentation of this file.
1 // Copyright 2021 Apex.AI, Inc.
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 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
16 
17 #ifndef STATE_ESTIMATION__KALMAN_FILTER__KALMAN_FILTER_HPP_
18 #define STATE_ESTIMATION__KALMAN_FILTER__KALMAN_FILTER_HPP_
19 
26 
27 #include <Eigen/LU>
28 
29 #include <limits>
30 #include <vector>
31 
32 namespace autoware
33 {
34 namespace common
35 {
36 namespace state_estimation
37 {
44 template<typename MotionModelT, typename NoiseModelT>
45 class STATE_ESTIMATION_PUBLIC KalmanFilter
46  : public StateEstimationInterface<KalmanFilter<MotionModelT, NoiseModelT>>
47 {
48  static_assert(
49  std::is_base_of<common::motion_model::MotionModelInterface<MotionModelT>, MotionModelT>::value,
50  "\n\nMotion model must inherit from MotionModelInterface\n\n");
51  static_assert(
52  std::is_base_of<NoiseInterface<NoiseModelT>, NoiseModelT>::value,
53  "\n\nNoise model must inherit from NoiseInterface\n\n");
54  static_assert(
55  std::is_same<typename MotionModelT::State, typename NoiseModelT::State>::value,
56  "\n\nMotion model and noise model must have the same underlying state\n\n");
57 
58 public:
59  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
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  const auto innovation = wrap_all_angles(measurement.state() - expected_measurement);
115  const auto mapping_matrix = measurement.mapping_matrix_from(m_state);
116  const auto innovation_covariance =
117  mapping_matrix * m_covariance * mapping_matrix.transpose() + measurement.covariance();
118  const auto kalman_gain =
119  m_covariance * mapping_matrix.transpose() * innovation_covariance.inverse();
120  m_state += kalman_gain * innovation.vector();
121  m_state.wrap_all_angles();
122  m_covariance = (State::Matrix::Identity() - kalman_gain * mapping_matrix) * m_covariance;
123  // Todo: In case of long-term numeric stability, use the following equtaions.
124  // auto intermediate_matrix = State::Matrix::Identity() - kalman_gain * mapping_matrix;
125  // m_covariance = intermediate_matrix * m_covariance * intermediate_matrix.transpose() +
126  // kalman_gain * measurement.covariance() * kalman_gain.transpose();
127  // m_covariance = (m_covariance + m_covariance.transpose()) / 2.0;
128  return m_state;
129  }
130 
137  void crtp_reset(const State & state, const StateMatrix & covariance)
138  {
139  m_state = state;
140  m_covariance = covariance;
141  }
142 
144  auto & crtp_state() {return m_state;}
146  const auto & crtp_state() const {return m_state;}
147 
149  auto & crtp_covariance() {return m_covariance;}
151  const auto & crtp_covariance() const {return m_covariance;}
152 
153 private:
155  MotionModelT m_motion_model{};
157  NoiseModelT m_noise_model{};
159  State m_state{};
161  StateMatrix m_covariance{StateMatrix::Zero()};
162 };
163 
180 template<typename MotionModelT, typename NoiseModelT>
182  const MotionModelT & motion_model,
183  const NoiseModelT & noise_model,
184  const typename MotionModelT::State & initial_state,
185  const typename MotionModelT::State::Matrix & initial_covariance)
186 {
188  motion_model, noise_model, initial_state, initial_covariance};
189 }
190 
207 template<typename StateT>
209  const StateT & initial_state,
210  const typename StateT::Matrix & initial_covariance)
211 {
212  struct DummyNoise : public NoiseInterface<DummyNoise>
213  {
214  using State = StateT;
215  typename State::Matrix crtp_covariance(const std::chrono::nanoseconds &) const
216  {
217  throw std::runtime_error(
218  "Trying to use a correction-only Kalman filter to predict the state.");
219  }
220  };
221 
223 
224  return make_kalman_filter(
225  MotionModel{}, DummyNoise{}, initial_state, initial_covariance);
226 }
227 
244 template<typename MotionModelT, typename NoiseModelT>
246  const MotionModelT & motion_model,
247  const NoiseModelT & noise_model,
248  const typename MotionModelT::State & initial_state,
249  const std::vector<typename MotionModelT::State::Scalar> & initial_variances)
250 {
251  using State = typename MotionModelT::State;
252  if (initial_variances.size() != static_cast<std::size_t>(State::size())) {
253  std::runtime_error(
254  "Cannot create Kalman filter - dimensions mismatch. Provided " +
255  std::to_string(initial_variances.size()) + " variances, but " +
256  std::to_string(State::size()) + " required.");
257  }
258  typename State::Vector variances{State::Vector::Zero()};
259  // A small enough epsilon to compare a floating point variance with zero.
260  const auto epsilon = 5.0F * std::numeric_limits<common::types::float32_t>::epsilon();
261  for (std::uint32_t i = 0; i < initial_variances.size(); ++i) {
262  if (common::helper_functions::comparisons::abs_lte(initial_variances[i], 0.0F, epsilon)) {
263  throw std::domain_error("Variances must be positive");
264  }
265  variances[static_cast<std::int32_t>(i)] = initial_variances[i] * initial_variances[i];
266  }
268  motion_model, noise_model, initial_state, variances.asDiagonal()};
269 }
270 
271 } // namespace state_estimation
272 } // namespace common
273 } // namespace autoware
274 
275 #endif // STATE_ESTIMATION__KALMAN_FILTER__KALMAN_FILTER_HPP_
autoware::common::state_estimation::KalmanFilter< MotionModel, NoiseModel >::State
typename MotionModel ::State State
Definition: kalman_filter.hpp:60
autoware::common::state_estimation::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::common::state_estimation::NoiseInterface
A CRTP interface for implementing noise models used for providing motion model noise covariance.
Definition: noise_interface.hpp:38
autoware::common::state_estimation::KalmanFilter< MotionModel, NoiseModel >::NoiseModel
NoiseModel NoiseModel
Definition: kalman_filter.hpp:63
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::common::state_estimation::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:137
motion_model_interface.hpp
autoware::common::state_estimation::KalmanFilter::crtp_covariance
const auto & crtp_covariance() const
Get current covariance.
Definition: kalman_filter.hpp:151
motion::motion_common::State
autoware_auto_vehicle_msgs::msg::VehicleKinematicState State
Definition: motion_common.hpp:40
autoware::common::state_estimation::make_correction_only_kalman_filter
auto make_correction_only_kalman_filter(const StateT &initial_state, const typename StateT::Matrix &initial_covariance)
A utility function that creates a Kalman filter that is to be used for correction only,...
Definition: kalman_filter.hpp:208
autoware
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24
float_comparisons.hpp
autoware::common::state_estimation::StateEstimationInterface
Interface for a filter that can be used to track an object.
Definition: state_estimation_interface.hpp:41
autoware::common::state_estimation::KalmanFilter::crtp_covariance
auto & crtp_covariance()
Get current covariance.
Definition: kalman_filter.hpp:149
noise_interface.hpp
stationary_motion_model.hpp
autoware::common::state_estimation::KalmanFilter
A Kalman filter implementation.
Definition: kalman_filter.hpp:45
state_estimation_interface.hpp
autoware::common::motion_model::StationaryMotionModel
This class describes a stationary motion model, i.e., the model that does not change the state.
Definition: stationary_motion_model.hpp:39
autoware::common::state_estimation::KalmanFilter::crtp_state
auto & crtp_state()
Get current state.
Definition: kalman_filter.hpp:144
autoware::common::motion_model::MotionModelInterface
A CRTP interface for any motion model.
Definition: motion_model_interface.hpp:39
autoware::common::state_estimation::KalmanFilter< MotionModel, NoiseModel >::MotionModel
MotionModel MotionModel
Definition: kalman_filter.hpp:62
autoware::common::state_estimation::KalmanFilter< MotionModel, NoiseModel >::StateMatrix
typename State::Matrix StateMatrix
Definition: kalman_filter.hpp:61
visibility_control.hpp
autoware::common::state_estimation::KalmanFilter::crtp_predict
State crtp_predict(const std::chrono::nanoseconds &dt)
Predict next state.
Definition: kalman_filter.hpp:90
autoware::common::state_estimation::KalmanFilter::crtp_correct
State crtp_correct(const MeasurementT &measurement)
Correct the predicted state given a measurement.
Definition: kalman_filter.hpp:111
autoware::common::state_estimation::KalmanFilter::crtp_state
const auto & crtp_state() const
Get current state.
Definition: kalman_filter.hpp:146
autoware::common::state_estimation::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:181