minikalman in the browser

minikalman compiled to wasm32-unknown-unknown and loaded with plain WebAssembly.instantiateStreaming. The module exports a few extern "C" functions that take and return numbers; there is no generated JS glue.

Tracking a moving target

Radars measure range and bearing to a moving target. Range noise spreads a measurement along the line of sight; bearing noise spreads it sideways, more so the further away the target is. Together they make a crescent in x/y. Both filters approximate it with a Gaussian ellipse: the Extended filter by linearizing at its estimate, the Unscented filter by pushing sigma points through the measurement function. Both run on the same measurements. Between measurements they only predict, and the ellipse grows; each correction (a dot on the track) shrinks it again.

Behind a radar, the bearing jumps from +180° to −180° (the dashed line). With wrap bearing residuals on, both filters use angles::wrap_pi to see that as the small step it is. Turn it off and restart, and both are thrown off when the target passes behind the radar. A second radar adds a crescent from another angle, and where the two intersect, the ellipses shrink.

— true path ∙ radar 1 measurement ∙ radar 2 measurement — EKF estimate, 2σ ellipse — UKF estimate, 2σ ellipse

Extended Kalman filter

Unscented Kalman filter

Target

Pointer:

Simulation

The basics: smoothing a noisy position

A linear filter tracking position and velocity in 1D. Drag across the plot to draw your own signal; the filter reruns on it as you draw. Sudden changes show the trade-off of the process noise: low values smooth more but lag behind, high values follow quickly but let more noise through.

— true position ● noisy measurement — filtered estimate ±2σ