33 double Wi(
int n)
const {
return 1.0 / (2 * (n +
lambda(n))); }
55Eigen::Matrix<double, N, 2 * N + 1>
57 const Eigen::Matrix<double, N, N> &P,
const UKFParams ¶ms) {
58 constexpr int num_sigma = 2 * N + 1;
59 Eigen::Matrix<double, N, num_sigma> sigma;
62 double scale = std::sqrt(N + params.
lambda(N));
65 Eigen::LLT<Eigen::Matrix<double, N, N>> llt(P);
66 Eigen::Matrix<double, N, N> L = llt.matrixL();
67 Eigen::Matrix<double, N, N> sqrtP = scale * L;
73 for (
int i = 0; i < N; ++i) {
74 sigma.col(1 + i) = x + sqrtP.col(i);
75 sigma.col(1 + N + i) = x - sqrtP.col(i);
105template <
int N,
int U,
typename DynamicsFunc>
107 const Eigen::Matrix<double, U, 1> &u,
110 constexpr int num_sigma = 2 * N + 1;
116 Eigen::Matrix<double, N, num_sigma> sigma_prop;
117 for (
int i = 0; i < num_sigma; ++i) {
118 Eigen::Matrix<double, N, 1> xi = sigma.col(i);
119 sigma_prop.col(i) = f(xi, u);
123 double Wm0 = params.Wm0(N);
124 double Wc0 = params.Wc0(N);
125 double Wi = params.Wi(N);
128 FilterState<double, N> predicted;
129 predicted.x = Wm0 * sigma_prop.col(0);
130 for (
int i = 1; i < num_sigma; ++i) {
131 predicted.x += Wi * sigma_prop.col(i);
135 Eigen::Matrix<double, N, 1> diff0 = sigma_prop.col(0) - predicted.x;
136 predicted.P = Wc0 * diff0 * diff0.transpose();
137 for (
int i = 1; i < num_sigma; ++i) {
138 Eigen::Matrix<double, N, 1> diff = sigma_prop.col(i) - predicted.x;
139 predicted.P += Wi * diff * diff.transpose();
141 predicted.P += noise.
Q;
149template <
int N,
typename DynamicsFunc>
154 auto f_wrapped = [&f](
const Eigen::Matrix<double, N, 1> &x,
155 const Eigen::Matrix<double, 1, 1> & ) {
158 Eigen::Matrix<double, 1, 1> dummy_u = Eigen::Matrix<double, 1, 1>::Zero();
185template <
int N,
int M,
typename MeasurementFunc>
188 const Eigen::Matrix<double, M, 1> &z, MeasurementFunc h,
190 constexpr int num_sigma = 2 * N + 1;
196 Eigen::Matrix<double, M, num_sigma> gamma;
197 for (
int i = 0; i < num_sigma; ++i) {
198 Eigen::Matrix<double, N, 1> xi = sigma.col(i);
199 gamma.col(i) = h(xi);
203 double Wm0 = params.Wm0(N);
204 double Wc0 = params.Wc0(N);
205 double Wi = params.Wi(N);
208 Eigen::Matrix<double, M, 1> z_pred = Wm0 * gamma.col(0);
209 for (
int i = 1; i < num_sigma; ++i) {
210 z_pred += Wi * gamma.col(i);
214 Eigen::Matrix<double, M, 1> dz0 =
gamma.col(0) - z_pred;
215 Eigen::Matrix<double, M, M> Pzz = Wc0 * dz0 * dz0.transpose();
216 for (
int i = 1; i < num_sigma; ++i) {
217 Eigen::Matrix<double, M, 1> dz =
gamma.col(i) - z_pred;
218 Pzz += Wi * dz * dz.transpose();
220 Eigen::Matrix<double, M, M> S = Pzz + noise.
R;
223 Eigen::Matrix<double, N, 1> dx0 =
sigma.col(0) -
state.x;
224 Eigen::Matrix<double, N, M> Pxz = Wc0 * dx0 * dz0.transpose();
225 for (
int i = 1; i < num_sigma; ++i) {
226 Eigen::Matrix<double, N, 1> dx =
sigma.col(i) -
state.x;
227 Eigen::Matrix<double, M, 1> dz =
gamma.col(i) - z_pred;
228 Pxz += Wi * dx * dz.transpose();
232 Eigen::Matrix<double, N, M> K = Pxz * S.inverse();
236 updated.
x =
state.x + K * (z - z_pred);
237 updated.P =
state.P - K * S * K.transpose();
249template <
int N,
int U,
int M,
typename DynamicsFunc,
typename MeasurementFunc>
252 const Eigen::Matrix<double, U, 1> &u,
253 const Eigen::Matrix<double, M, 1> &z, DynamicsFunc f,
constexpr double gamma
Ratio of specific heats for air.
Definition Constants.hpp:97
constexpr double sigma
Stefan-Boltzmann constant [W/(m^2·K^4)] (CODATA 2018).
Definition Constants.hpp:114
Definition EstimationTypes.hpp:8
FilterState< double, N > ukf_predict(const FilterState< double, N > &state, const Eigen::Matrix< double, U, 1 > &u, DynamicsFunc f, const ProcessNoise< N > &noise, const UKFParams ¶ms={})
Unscented Kalman filter predict step.
Definition UnscentedKF.hpp:106
FilterState< double, N > ukf_update(const FilterState< double, N > &state, const Eigen::Matrix< double, M, 1 > &z, MeasurementFunc h, const MeasurementNoise< M > &noise, const UKFParams ¶ms={})
Unscented Kalman filter update step.
Definition UnscentedKF.hpp:187
FilterState< double, N > ukf_step(const FilterState< double, N > &state, const Eigen::Matrix< double, U, 1 > &u, const Eigen::Matrix< double, M, 1 > &z, DynamicsFunc f, MeasurementFunc h, const ProcessNoise< N > &Q, const MeasurementNoise< M > &R, const UKFParams ¶ms={})
Combined UKF step (predict + update).
Definition UnscentedKF.hpp:251
Eigen::Matrix< double, N, 2 *N+1 > sigma_points(const Eigen::Matrix< double, N, 1 > &x, const Eigen::Matrix< double, N, N > &P, const UKFParams ¶ms)
Generate sigma points for UKF.
Definition UnscentedKF.hpp:56
AtmosphericState< Scalar > state(const Scalar &altitude, double scale_height=DEFAULT_SCALE_HEIGHT)
Exponential atmosphere - Complete atmospheric state.
Definition ExponentialAtmosphere.hpp:160
Filter state container holding estimate and covariance.
Definition EstimationTypes.hpp:20
Eigen::Matrix< Scalar, N, 1 > x
State estimate.
Definition EstimationTypes.hpp:21
Measurement noise specification.
Definition EstimationTypes.hpp:79
Eigen::Matrix< double, M, M > R
Measurement noise covariance.
Definition EstimationTypes.hpp:80
Process noise specification.
Definition EstimationTypes.hpp:46
Eigen::Matrix< double, N, N > Q
Process noise covariance.
Definition EstimationTypes.hpp:47
UKF tuning parameters.
Definition UnscentedKF.hpp:18
double Wc0(int n) const
Compute weight for covariance of zeroth sigma point.
Definition UnscentedKF.hpp:30
double Wi(int n) const
Compute weight for other sigma points (same for mean and covariance).
Definition UnscentedKF.hpp:33
double lambda(int n) const
Compute lambda scaling factor.
Definition UnscentedKF.hpp:24
double beta
Prior knowledge about distribution (2 = Gaussian).
Definition UnscentedKF.hpp:20
double alpha
Spread of sigma points around mean (1e-4 to 1).
Definition UnscentedKF.hpp:19
double Wm0(int n) const
Compute weight for mean of zeroth sigma point.
Definition UnscentedKF.hpp:27
double kappa
Secondary scaling parameter.
Definition UnscentedKF.hpp:21