Unscented Kalman Filter (gnc-autonomy/estimation-filtering/unscented-kalman-filter)
Use when the task is nonlinear state estimation with an unscented
Kalman filter: sigma-point generation through the scaled unscented
transform, propagation of the points through nonlinear dynamics, the
weighted predict, the innovation covariance and Kalman gain from a
nonlinear measurement, and the NEES consistency check.
The UKF is the sigma-point cousin of the linear Kalman filter
(navigation/kalman-filter-design) and of the alpha-beta tracker
(estimation-filtering/alpha-beta-filter): it keeps the predict-update
loop but replaces analytic Jacobians with a deterministic sample of
points, so it works for strongly nonlinear dynamics and measurement
models with no differentiation.
Domain quick reference
- State model: x in R^n with mean x and covariance P. The process is
x_(k+1) = f(x_k) + w_k with dynamics noise w ~ N(0, Q); the
measurement is z_k = h(x_k) + v_k with sensor noise v ~ N(0, R).
Both f and h may be nonlinear.
- Sigma points: 2n + 1 points X_i sampled deterministically from the
current (x, P). X_0 = x; X_i = x + gamma * col_i(L) for i = 1..n;
X_(n+i) = x - gamma * col_i(L), where L is the lower Cholesky
factor of P (L L^T = P) and gamma = sqrt(n + lambda).
- Scaled unscented transform (Van der Merwe): lambda = alpha^2 * (n +
kappa) - n with spread alpha in (0, 1], secondary scale kappa, and
prior knowledge beta (beta = 2 is optimal for Gaussian states).
- Weights: wm_0 = lambda / (n + lambda); wc_0 = wm_0 + (1 - alpha^2
- beta); wm_i = wc_i = 1 / (2 * (n + lambda)) for i = 1..2n. The
mean weights sum to 1; the covariance weights carry the beta term.
- Predict: propagate every point through f, then x_pred = sum_i wm_i
f(X_i) and P_pred = sum_i wc_i (f(X_i) - x_pred)(...)^T + Q. For a
linear f this reproduces the Kalman predict exactly.
- Update: propagate through h to get the predicted measurements Z_i,
form the innovation covariance S = sum_i wc_i (Z_i - z_mean)(...)^T
- R and the cross covariance P_xz = sum_i wc_i (X_i - x)(Z_i -
z_mean)^T, then K = P_xz S^-1, x_new = x_pred + K (z - z_mean) and
P_new = P_pred - K S K^T.
- NEES: normalized estimation error squared, (x_est - x_true)^T
P_est^-1 (x_est - x_true). Its expected value is n for a consistent
filter; averaged over many Monte Carlo runs NEES should sit near n
(well above n means overconfident, far below means pessimistic).
- Units: state and measurement in consistent SI units; covariances
P, Q, R in the unit squared; angles in radians.
- ARP4754A (reference-only) frames development assurance for aircraft
systems; the unscented transform is common estimation-theory
knowledge (Julier and Uhlmann; Wan and Van der Merwe).
Workflow
- Write the model: dynamics f(point), measurement h(point), the
dynamics noise covariance Q, the sensor noise covariance R, and
the initial mean x0 and covariance P0.
- Choose the transform parameters: alpha near 1e-3 for Gaussian
states (larger alpha spreads the points), beta = 2, kappa = 0.
- Generate the sigma points with generate_sigma_points(x, P, alpha,
beta, kappa) and confirm the weighted mean and covariance of the
points reproduce x and P with weighted_moments.
- Predict with predict(x, P, f, Q, alpha, beta, kappa); confirm the
covariance grew by Q and the mean advanced through f.
- Update with update(x, P, z, h, R, alpha, beta, kappa); the call
returns the corrected state, corrected covariance, predicted
measurement mean, innovation covariance S, and gain K.
- For a measurement batch, keep a UKFFilter instance and call
step(z) per measurement; the filter holds x, P, the last
innovation, S, and K.
- Assess consistency with nees(x_est, P_est, x_true) against the
true state; compare the mean NEES to the state dimension n.
Sigma-point math
The scaled unscented transform replaces the Jacobian of the extended
Kalman filter with a deterministic sample. Given (x, P):
- lambda = alpha^2 * (n + kappa) - n and gamma = sqrt(n + lambda).
- L = chol(P) with L L^T = P; the sigma points are x plus and minus
gamma times each column of L.
- Each point is pushed through the nonlinear function (f or h); the
weighted mean and weighted covariance of the transformed points
approximate the true mean and covariance of the transformed random
variable to third order for Gaussian inputs, with the beta term
tuning the fourth-order moment error.
The same machinery serves both steps: the predict uses f on the state
points, the update uses h on the same state points to form the
predicted measurements and the cross covariance that builds the gain.
Tuning guidance
- alpha controls the spread of the points around the mean. Very small
alpha (1e-3) keeps the points close and is standard for Gaussian
states; larger alpha covers heavy-tailed states but loses accuracy.
- beta = 2 minimizes the fourth-order error for Gaussian states; use
beta = 0 for other distributions (the beta term only touches wc_0).
- kappa is a secondary scaling that guards against a non-positive
definite (n + lambda) when alpha is small; kappa = 0 or 3 - n is
common. A zero or negative (n + lambda) raises ValueError.
- Q and R are the honest uncertainty budgets: too small a Q makes the
filter overconfident (NEES well above n) and slow to react; too
large a Q makes it noisy and pessimistic (NEES far below n).
- For strongly nonlinear measurement models, prefer small alpha with
the exact nonlinear h over an extended-Kalman linearization; the
UKF carries the full nonlinearity in the sampled points.
- If the innovation covariance S comes out non-positive definite, the
state covariance P has likely collapsed; re-inflate P or raise Q.
Pitfalls
- Confusing the UKF with the linear Kalman filter: the UKF needs no
Jacobians, but it does need the exact nonlinear f and h callables
and the noise covariances Q and R in the same state units.
- Using an indefinite or negative covariance P; the Cholesky factor
raises ValueError, and the sigma points are undefined for such P.
- Forgetting the beta term in wc_0; the covariance reconstruction
then mis-states the spread and NEES drifts.
- Expecting the mean of transformed points to equal f(mean); for
nonlinear f the unscented mean is the weighted point mean, not the
function of the mean.
- Feeding measurement noise R that is too small relative to the true
sensor noise; the gain over-trusts the measurement and the
corrected covariance understates the error.
- Treating NEES from a single run as proof of consistency; NEES is a
random quantity and only its Monte Carlo average near n is
meaningful.
Behavior contract (gate 3)
The sigma-point generation, weight computation, predict, update,
innovation covariance, gain, NEES, and the stateful UKFFilter are
exercised by the gate 3 contract test:
scripts/test_unscented_kalman_filter.py against
scripts/unscented_kalman_filter_logic.py (stdlib unittest, offline,
deterministic). The test covers moment reconstruction of the sigma
points, symmetry about the mean, exact agreement with the linear
Kalman filter for linear models, and convergence of a full
bearing/range tracking run on a constant-velocity target.
Run:
python3 scripts/test_unscented_kalman_filter.py
Compliance
- ARP4754A is proprietary (SAE); name and paraphrase only per
standards-map.yaml, reference-only: true.
- compliance: STANDARDS-REF, gated: false.
1---2name: unscented-kalman-filter3description: Use when you must estimate the state of a nonlinear system with an unscented Kalman filter: generate sigma points from the state mean and covariance with the scaled unscented transform, propagate each point through the nonlinear dynamics, compute the weighted predicted mean and covariance, form the innovation covariance and the cross covariance, calculate the Kalman gain, and correct the state and covariance from a nonlinear measurement. Produces the predicted and corrected states, the state covariance, the innovation covariance, the Kalman gain, and the NEES consistency metric that gate a nonlinear estimation assessment. Trigger: unscented kalman filter, sigma points, scaled unscented transform, innovation covariance, kalman gain, nonlinear state estimation, nees.4license: Apache-2.05---67# Unscented Kalman Filter (gnc-autonomy/estimation-filtering/unscented-kalman-filter)89Use when the task is nonlinear state estimation with an unscented10Kalman filter: sigma-point generation through the scaled unscented11transform, propagation of the points through nonlinear dynamics, the12weighted predict, the innovation covariance and Kalman gain from a13nonlinear measurement, and the NEES consistency check.1415The UKF is the sigma-point cousin of the linear Kalman filter16(navigation/kalman-filter-design) and of the alpha-beta tracker17(estimation-filtering/alpha-beta-filter): it keeps the predict-update18loop but replaces analytic Jacobians with a deterministic sample of19points, so it works for strongly nonlinear dynamics and measurement20models with no differentiation.2122## Domain quick reference2324- State model: x in R^n with mean x and covariance P. The process is25 x_(k+1) = f(x_k) + w_k with dynamics noise w ~ N(0, Q); the26 measurement is z_k = h(x_k) + v_k with sensor noise v ~ N(0, R).27 Both f and h may be nonlinear.28- Sigma points: 2n + 1 points X_i sampled deterministically from the29 current (x, P). X_0 = x; X_i = x + gamma * col_i(L) for i = 1..n;30 X_(n+i) = x - gamma * col_i(L), where L is the lower Cholesky31 factor of P (L L^T = P) and gamma = sqrt(n + lambda).32- Scaled unscented transform (Van der Merwe): lambda = alpha^2 * (n +33 kappa) - n with spread alpha in (0, 1], secondary scale kappa, and34 prior knowledge beta (beta = 2 is optimal for Gaussian states).35- Weights: wm_0 = lambda / (n + lambda); wc_0 = wm_0 + (1 - alpha^236 + beta); wm_i = wc_i = 1 / (2 * (n + lambda)) for i = 1..2n. The37 mean weights sum to 1; the covariance weights carry the beta term.38- Predict: propagate every point through f, then x_pred = sum_i wm_i39 f(X_i) and P_pred = sum_i wc_i (f(X_i) - x_pred)(...)^T + Q. For a40 linear f this reproduces the Kalman predict exactly.41- Update: propagate through h to get the predicted measurements Z_i,42 form the innovation covariance S = sum_i wc_i (Z_i - z_mean)(...)^T43 + R and the cross covariance P_xz = sum_i wc_i (X_i - x)(Z_i -44 z_mean)^T, then K = P_xz S^-1, x_new = x_pred + K (z - z_mean) and45 P_new = P_pred - K S K^T.46- NEES: normalized estimation error squared, (x_est - x_true)^T47 P_est^-1 (x_est - x_true). Its expected value is n for a consistent48 filter; averaged over many Monte Carlo runs NEES should sit near n49 (well above n means overconfident, far below means pessimistic).50- Units: state and measurement in consistent SI units; covariances51 P, Q, R in the unit squared; angles in radians.52- ARP4754A (reference-only) frames development assurance for aircraft53 systems; the unscented transform is common estimation-theory54 knowledge (Julier and Uhlmann; Wan and Van der Merwe).5556## Workflow57581. Write the model: dynamics f(point), measurement h(point), the59 dynamics noise covariance Q, the sensor noise covariance R, and60 the initial mean x0 and covariance P0.612. Choose the transform parameters: alpha near 1e-3 for Gaussian62 states (larger alpha spreads the points), beta = 2, kappa = 0.633. Generate the sigma points with generate_sigma_points(x, P, alpha,64 beta, kappa) and confirm the weighted mean and covariance of the65 points reproduce x and P with weighted_moments.664. Predict with predict(x, P, f, Q, alpha, beta, kappa); confirm the67 covariance grew by Q and the mean advanced through f.685. Update with update(x, P, z, h, R, alpha, beta, kappa); the call69 returns the corrected state, corrected covariance, predicted70 measurement mean, innovation covariance S, and gain K.716. For a measurement batch, keep a UKFFilter instance and call72 step(z) per measurement; the filter holds x, P, the last73 innovation, S, and K.747. Assess consistency with nees(x_est, P_est, x_true) against the75 true state; compare the mean NEES to the state dimension n.7677## Sigma-point math7879The scaled unscented transform replaces the Jacobian of the extended80Kalman filter with a deterministic sample. Given (x, P):81821. lambda = alpha^2 * (n + kappa) - n and gamma = sqrt(n + lambda).832. L = chol(P) with L L^T = P; the sigma points are x plus and minus84 gamma times each column of L.853. Each point is pushed through the nonlinear function (f or h); the86 weighted mean and weighted covariance of the transformed points87 approximate the true mean and covariance of the transformed random88 variable to third order for Gaussian inputs, with the beta term89 tuning the fourth-order moment error.9091The same machinery serves both steps: the predict uses f on the state92points, the update uses h on the same state points to form the93predicted measurements and the cross covariance that builds the gain.9495## Tuning guidance9697- alpha controls the spread of the points around the mean. Very small98 alpha (1e-3) keeps the points close and is standard for Gaussian99 states; larger alpha covers heavy-tailed states but loses accuracy.100- beta = 2 minimizes the fourth-order error for Gaussian states; use101 beta = 0 for other distributions (the beta term only touches wc_0).102- kappa is a secondary scaling that guards against a non-positive103 definite (n + lambda) when alpha is small; kappa = 0 or 3 - n is104 common. A zero or negative (n + lambda) raises ValueError.105- Q and R are the honest uncertainty budgets: too small a Q makes the106 filter overconfident (NEES well above n) and slow to react; too107 large a Q makes it noisy and pessimistic (NEES far below n).108- For strongly nonlinear measurement models, prefer small alpha with109 the exact nonlinear h over an extended-Kalman linearization; the110 UKF carries the full nonlinearity in the sampled points.111- If the innovation covariance S comes out non-positive definite, the112 state covariance P has likely collapsed; re-inflate P or raise Q.113114## Pitfalls115116- Confusing the UKF with the linear Kalman filter: the UKF needs no117 Jacobians, but it does need the exact nonlinear f and h callables118 and the noise covariances Q and R in the same state units.119- Using an indefinite or negative covariance P; the Cholesky factor120 raises ValueError, and the sigma points are undefined for such P.121- Forgetting the beta term in wc_0; the covariance reconstruction122 then mis-states the spread and NEES drifts.123- Expecting the mean of transformed points to equal f(mean); for124 nonlinear f the unscented mean is the weighted point mean, not the125 function of the mean.126- Feeding measurement noise R that is too small relative to the true127 sensor noise; the gain over-trusts the measurement and the128 corrected covariance understates the error.129- Treating NEES from a single run as proof of consistency; NEES is a130 random quantity and only its Monte Carlo average near n is131 meaningful.132133## Behavior contract (gate 3)134135The sigma-point generation, weight computation, predict, update,136innovation covariance, gain, NEES, and the stateful UKFFilter are137exercised by the gate 3 contract test:138scripts/test_unscented_kalman_filter.py against139scripts/unscented_kalman_filter_logic.py (stdlib unittest, offline,140deterministic). The test covers moment reconstruction of the sigma141points, symmetry about the mean, exact agreement with the linear142Kalman filter for linear models, and convergence of a full143bearing/range tracking run on a constant-velocity target.144Run:145python3 scripts/test_unscented_kalman_filter.py146147## Compliance148149- ARP4754A is proprietary (SAE); name and paraphrase only per150 standards-map.yaml, reference-only: true.151- compliance: STANDARDS-REF, gated: false.