Kalman Filter Simulator: Optimal Estimation & Sensor Fusion

simulator advanced ~15 min
Loading simulation...
P_ss ≈ 2.24 m² — steady-state position uncertainty ≈ 1.5 m

With Q=0.5 m²/s⁴ and R=10 m², the Kalman filter converges to a steady-state uncertainty of √(Q·R) ≈ 2.24 m², corresponding to ~1.5 m RMS position error — better than either the model or measurements alone.

Formula

x̂⁻ = F·x̂ + B·u;  P⁻ = F·P·F' + Q  (predict)
K = P⁻·H' / (H·P⁻·H' + R)  (Kalman gain)
x̂ = x̂⁻ + K·(z - H·x̂⁻);  P = (I - K·H)·P⁻  (update)

The Optimal Estimator

Published by Rudolf Kalman in 1960, the Kalman filter solved one of engineering's fundamental problems: how to optimally combine noisy measurements with an imperfect model to estimate the true state of a system. It was immediately adopted by NASA for Apollo navigation and has since become the workhorse algorithm in navigation, control, robotics, economics, and signal processing. Every smartphone's GPS uses a Kalman filter.

Predict-Update Cycle

The filter operates in two alternating steps. In the prediction step, it projects the state forward using the system dynamics model: x̂⁻ = F·x̂ + B·u. The uncertainty grows because the model is imperfect (process noise Q). In the update step, a new measurement z arrives and the filter corrects the prediction: x̂ = x̂⁻ + K·(z - H·x̂⁻). The Kalman gain K determines the correction weight. The simulation visualizes both steps, showing the predicted and updated state distributions.

The Kalman Gain Intuition

The Kalman gain K is the filter's core intelligence. It answers: how much should I trust this measurement? When prediction uncertainty is high (P⁻ is large), K is large and the measurement strongly corrects the estimate. When measurement noise is high (R is large), K is small and the filter mostly trusts its model. As the filter runs, P converges to a steady state where prediction uncertainty growth (from Q) exactly balances measurement information (from R).

Sensor Fusion in Practice

The Kalman filter's real power emerges in multi-sensor fusion. A navigation system might combine GPS (accurate, low-rate, occasional dropouts), INS (smooth, high-rate, drifting), barometer (altitude), magnetometer (heading), and visual odometry (relative motion). The Kalman filter weighs each sensor according to its current reliability, automatically downweighting a degraded sensor. This simulation demonstrates the fusion concept with configurable noise parameters.

FAQ

What is a Kalman filter?

The Kalman filter is an optimal recursive algorithm that estimates the state of a dynamic system from noisy measurements. It maintains a state estimate and uncertainty covariance, alternating between prediction steps (projecting forward using a system model) and update steps (correcting with measurements). It is provably optimal for linear systems with Gaussian noise.

What is the Kalman gain?

The Kalman gain K determines how much to trust a new measurement versus the model prediction. K = P⁻H'/(H·P⁻·H' + R) balances prediction uncertainty P⁻ against measurement noise R. When P⁻ >> R (uncertain model), K → 1 and measurements dominate. When R >> P⁻ (noisy measurements), K → 0 and the model dominates.

How does the Kalman filter fuse GPS and INS?

GPS provides accurate but noisy absolute position at low rate (~1 Hz). INS provides smooth relative motion at high rate (~100 Hz) but drifts over time. The Kalman filter combines both optimally: INS drives the prediction step (smooth high-rate output) while GPS drives the update step (correcting drift). The result is better than either sensor alone.

What is the Extended Kalman Filter (EKF)?

The standard Kalman filter handles only linear systems. The Extended Kalman Filter (EKF) linearizes nonlinear models about the current estimate using Jacobians, enabling application to the inherently nonlinear problems of navigation (rotation, coordinate transforms). Most practical navigation filters are EKFs or the newer Unscented Kalman Filters (UKF).

Sources

Embed

<iframe src="https://homo-deus.com/lab/navigation/kalman-filter/embed" width="100%" height="400" frameborder="0"></iframe>
View source on GitHub