Chris Collins

Tools · math

Kalman filter playground

Tune a Kalman filter live and watch it work — a 1-D value, 2-D tracking with constant-velocity and constant-acceleration models, an extended Kalman filter for a range–bearing sensor, GPS + accelerometer fusion, and complementary filter against Kalman for tilt (with your phone's sensors) — stepping through predict and update with every matrix shown, covariance ellipses, innovations and NIS/NEES consistency against chi-square bounds.

Added

How to use it

A Kalman filter keeps an estimate of a state and of how unsure it is about it (the covariance P). Each step it predicts with a model of how the state moves, growing P by the process noise Q, then updates with a measurement, trusting it in proportion to its noise R. Everything here is a simulation with a known truth, so you can see when the filter is right, when it is wrong, and whether it knows which. Each scenario has its own tab and address — /tools/kalman/#2d, #ekf, #fusion, #tilt.

How to use it

  • Step ▸ moves through the filter half a step at a time: first the prediction (x̂⁻, P⁻, a dashed ellipse), then the update (y, S, K, x̂, P, a solid ellipse). The This step panel shows every matrix with its numbers; open The model for F, Q, H, R (and B where there is a control input). ▶ Run plays the whole run, the slider jumps to any step.

  • Drag the Q and R sliders: the same truth and the same noisy measurements are filtered again at once, so you see only what the tuning changes. New noise draws a fresh run.

  • Innovation plots show y = z − H x̂⁻ against ±2√S: about 95 % of points should sit inside. NIS (normalised innovation squared, yᵀS⁻¹y) should average the measurement’s dimension; the dashed lines are its 95 % chi-square bounds and the shaded band the bounds for a 20-step mean. NEES does the same for the estimation error, which needs the truth. A mean above the band means the filter is overconfident (Q or R too small); below means it is too timid.

The tabs

  • 1-D — a constant value or a random walk measured with noise. With Q = 0 the gain falls as 1/k (the running mean); with Q > 0 it settles at the steady-state gain K∞, shown for comparison.

  • 2-D tracking — a target that drives straight and then turns, or drifts at random. Choose a constant-velocity or constant-acceleration model; Q comes from white acceleration (or jerk) noise of the density you set. Turn Q down and watch the estimate overshoot the corners and NIS explode; turn it up and the estimate gets as noisy as the measurements.

  • Range–bearing EKF — a radar measures range and bearing. The extended Kalman filter linearises the measurement about each prediction (the Jacobian H is shown each step) and wraps the bearing innovation to ±180°. The shaded arc is the true shape of one measurement’s uncertainty; when it is long and curved — big bearing noise, distant target — the Gaussian ellipse fits it badly and the filter becomes inconsistent.

  • GPS + accelerometer — 50 Hz accelerometer readings drive the prediction as a control input; GPS fixes arrive once a second. Between fixes the uncertainty grows, at each fix it drops. Put the accelerometer bias in the state and the fixes teach the filter to subtract it; take it out and see the track lean.

  • Tilt — a gyro (smooth, biased) and an accelerometer (noisy, upset by knocks). A complementary filter blends them with a fixed time constant; a two-state Kalman filter (angle and gyro bias) works out the blend and the bias. On a phone, Use this phone’s sensors runs both filters on your phone’s own gyro and accelerometer — tilt it forwards and back. iPhones ask for permission first. For a level and an inclinometer see compass and level.

How it works

The engine, kalman-core.js, is plain JavaScript with no libraries: small dense matrices (Gauss–Jordan inverse, Cholesky), a seeded random generator, and the filter. The covariance update uses the Joseph form, P = (I − KH)P⁻(I − KH)ᵀ + KRKᵀ, which stays symmetric and positive definite for any gain. Chi-square bounds come from the regularised incomplete gamma function. Its tests check that the scalar filter reaches the analytic steady-state gain, that P stays positive definite over long runs, that a correctly tuned filter’s mean NIS and NEES match their degrees of freedom, that the EKF’s Jacobian matches finite differences, and that the bearing wraps across ±180°.

Browser support

Works in any current browser. The live tilt input needs a phone or tablet with a gyroscope: Chrome on Android and Safari on iPhone (which asks for permission) both work; desktop browsers have no motion sensors, so they run the simulation only.

Privacy

Everything runs in your browser. The motion sensor readings, when you turn them on, are used on the page and never sent anywhere. Your settings are kept in this browser, and a share link carries them in the address.

Runs entirely in your browser; nothing you type leaves this page.