22 template <
int n_states,
int n_inputs,
int n_measurements>
27 template <
int n_states,
int n_inputs,
int n_measurements>
29 const double kappa,
const double beta)
30 : m_alpha(alpha), m_kappa(kappa), m_beta(beta), m_Wm(
W_t::Zero()), m_Wc(
W_t::Zero()), m_transition_model(transition_model),
31 m_observation_model(observation_model)
41 template <
int n_states,
int n_inputs,
int n_measurements>
46 m_lambda = m_alpha * m_alpha * (double(n) + m_kappa) -
double(n);
49 m_Wm(0) = m_lambda / (double(n) + m_lambda);
50 m_Wc(0) = m_Wm(0) + (1.0 - m_alpha * m_alpha + m_beta);
53 for (
int i = 1; i < w; i++)
55 m_Wm(i) = (1.0 - m_Wm(0)) / (w - 1.0);
64 template <
int n_states,
int n_inputs,
int n_measurements>
79 template <
int n_states,
int n_inputs,
int n_measurements>
82 m_transition_model = transition_model;
89 template <
int n_states,
int n_inputs,
int n_measurements>
92 m_observation_model = observation_model;
99 template <
int n_states,
int n_inputs,
int n_measurements>
103 const P_t Pa = (double(n) + m_lambda) * P;
106 Eigen::LLT<P_t> llt(Pa);
107 if (llt.info() != Eigen::Success)
109 P_t tmp = Pa + (double(n) + m_lambda) * 1e-9 * P_t::Identity();
111 if (llt.info() != Eigen::Success)
113 std::cout <<
"UKF: taking the square root of covariance during sigma point generation failed." << std::endl;
114 throw square_root_exception();
118 const P_t Pa_sqrt = llt.matrixL();
124 template <
int n_states,
int n_inputs,
int n_measurements>
127 Eigen::ColPivHouseholderQR<Pzz_t> qr(Pzz);
128 if (!qr.isInvertible())
131 Pzz_t tmp = Pzz + 1e-9 * Pzz_t::Identity(Pzz.rows(), Pzz.cols());
133 if (!qr.isInvertible())
136 std::cout <<
"UKF: could not compute matrix inversion!!! Fix your covariances (the measurement's is probably too low...)" << std::endl;
137 throw inverse_exception();
139 std::cout <<
"UKF: artificially inflating matrix for inverse computation! Check your covariances (the measurement's might be too low...)" << std::endl;
141 Pzz_t ret = qr.inverse();
147 template <
int n_states,
int n_inputs,
int n_measurements>
149 [[maybe_unused]]
const z_t& inn,
150 const K_t& Pxz,
const Pzz_t& Pzz)
const
152 const Pzz_t Pzz_inv = computeInverse(Pzz);
153 const K_t K = Pxz * Pzz_inv;
159 template <
int n_states,
int n_inputs,
int n_measurements>
167 const P_t P_sqrt = computePaSqrt(P);
168 const auto xrep = x.replicate(1, n);
171 S.template block<n, n>(0, 1) = xrep + P_sqrt;
174 S.template block<n, n>(0, n + 1) = xrep - P_sqrt;
185 template <
int n_states,
int n_inputs,
int n_measurements>
187 const Q_t& Q,
double dt)
const
189 const auto& x = sc.x;
190 const auto& P = sc.P;
193 const X_t S = computeSigmas(x, P);
197 for (
int i = 0; i < w; i++)
199 X.col(i) = m_transition_model(S.col(i), u, dt);
208 for (
int i = 0; i < w; i++)
211 x_t tmp = 1.0 / w * X.col(i);
218 for (
int i = 0; i < w; i++)
220 ret.P += m_Wc(i) * (X.col(i) - ret.x) * (X.col(i) - ret.x).transpose();
231 template <
int n_states,
int n_inputs,
int n_measurements>
235 const auto& x = sc.x;
236 const auto& P = sc.P;
237 const X_t S = computeSigmas(x, P);
240 Z_t Z_exp(z.rows(), w);
241 for (
int i = 0; i < w; i++)
243 Z_exp.col(i) = m_observation_model(S.col(i));
247 z_t z_exp = z_t::Zero(z.rows());
248 for (
int i = 0; i < w; i++)
250 z_exp += m_Wm(i) * Z_exp.col(i);
254 Pzz_t Pzz = Pzz_t::Zero(z.rows(), z.rows());
255 for (
int i = 0; i < w; i++)
257 Pzz += m_Wc(i) * (Z_exp.col(i) - z_exp) * (Z_exp.col(i) - z_exp).transpose();
262 K_t Pxz = K_t::Zero(n, z.rows());
263 for (
int i = 0; i < w; i++)
265 Pxz += m_Wc(i) * (S.col(i) - x) * (Z_exp.col(i) - z_exp).transpose();
269 const z_t inn = (z - z_exp);
270 const K_t K = computeKalmanGain(sc.x, inn, Pxz, Pzz);
273 if (!K.array().isFinite().all())
275 std::cout <<
"UKF: inverting of Pzz in correction update produced non-finite numbers!!! Fix your covariances (the measurement's is probably too low...)"
283 ret.P = P - K * Pzz * K.transpose();
Implementation of the Unscented Kalman filter .
Definition ukf.h:40
typename Eigen::Matrix< double, p, w > Z_t
Measurement sigma points matrix.
Definition ukf.h:51
typename Base_class::R_t R_t
measurement covariance p*p typedef
Definition ukf.h:67
typename Eigen::Matrix< double, n, w > X_t
State sigma points matrix.
Definition ukf.h:50
void setObservationModel(const observation_model_t &observation_model)
Changes the observation model function.
Definition ukf.hpp:90
virtual statecov_t predict(const statecov_t &sc, const u_t &u, const Q_t &Q, double dt) const override
Implements the state prediction step (time update).
Definition ukf.hpp:186
typename Base_class::x_t x_t
state vector n*1 typedef
Definition ukf.h:59
typename Base_class::statecov_t statecov_t
typedef of a helper struct for state and covariance
Definition ukf.h:73
void setConstants(const double alpha, const double kappa, const double beta)
Changes the Unscented Transform parameters.
Definition ukf.hpp:66
typename Base_class::u_t u_t
input vector m*1 typedef
Definition ukf.h:61
void setTransitionModel(const transition_model_t &transition_model)
Changes the transition model function.
Definition ukf.hpp:80
typename Base_class::z_t z_t
measurement vector p*1 typedef
Definition ukf.h:63
typename std::function< x_t(const x_t &, const u_t &, double)> transition_model_t
function of the state transition model typedef
Definition ukf.h:75
typename Base_class::Q_t Q_t
process covariance n*n typedef
Definition ukf.h:69
typename Base_class::P_t P_t
state covariance n*n typedef
Definition ukf.h:65
typename std::function< z_t(const x_t &)> observation_model_t
function of the observation model typedef
Definition ukf.h:77
typename Eigen::Matrix< double, w, 1 > W_t
weights vector (2n+1)*1 typedef
Definition ukf.h:71
typename Eigen::Matrix< double, n, p > K_t
Kalman gain matrix.
Definition ukf.h:53
UKF()
Convenience default constructor.
Definition ukf.hpp:23
virtual statecov_t correct(const statecov_t &sc, const z_t &z, const R_t &R) const override
Implements the state correction step (measurement update).
Definition ukf.hpp:232
typename Eigen::Matrix< double, p, p > Pzz_t
Pzz helper matrix.
Definition ukf.h:52
All mrs_lib functions, classes, variables and definitions are contained in this namespace.
Definition attitude_converter.h:24
is thrown when taking the inverse of a matrix fails during kalman gain calculation
Definition ukf.h:90
Defines UKF - a class implementing the Unscented Kalman Filter .