Tracking with the Kalman filter
Follow a moving object through noisy sensor readings. Watch the Kalman filter predict, compare its prediction with each measurement and correct itself, and see when a particle filter does better.
A Kalman filter estimates the hidden state of a system that changes over time (here: the position and velocity of a moving object) from noisy measurements. It keeps a Gaussian belief about the state: a mean (the best guess) and a covariance (how unsure it is). Two steps repeat for every new measurement:
- Predict: move the belief forward with a model of the motion. The guess moves and the uncertainty grows.
- Update: compare the prediction with the measurement and correct it. The uncertainty shrinks.
In the first simulation you track a target with a position sensor and see both steps, the Kalman gain and the errors live. In the second one the sensor measures distance and angle, so the problem becomes nonlinear, and you compare the extended Kalman filter with a particle filter. At the end we connect all of this to data assimilation, the method that starts every weather forecast.
1. The tracking simulation #
Press Play and watch the two steps. The black dot (white in dark mode) is the true target, the orange dots are the noisy measurements . Violet, dashed: the prediction and its 95% ellipse. Blue: the estimate after the update and its 95% ellipse. The orange dashed arrow is the innovation (how much the measurement surprised the filter); the blue arrow is the correction . Pick slow, or press Next, to see predict and update one at a time. The charts show the last 10 seconds.
2. Try this #
- Trust the model or trust the sensor? With the circle target, set the process noise to its smallest value, then to its largest. Question: which setting gives a smooth track that falls behind the target in the turn, and which one gives a track that jumps with every measurement? What to see: with small the gain drops to about and the blue track cuts inside the circle (its RMSE becomes larger than the sensor's). With large the gain rises to about and the track copies the noise. Near the filter error is about half the sensor error.
- The gain does not look at the data. Press Next a few times. Question: after the predict step, before the measurement is used, is the gain already known? What to see: yes. depends only on and , not on the value of . After a few seconds it stops changing: the filter reaches a steady state.
- Losing the signal. Set Measurements to no-signal zone. Question: inside the grey band, what happens to the ellipse, and what does the gain do at the first measurement after the band? What to see: with no updates the ellipse only grows, and the prediction flies straight on while the target turns. At the first new measurement jumps close to : the filter trusts the sensor almost completely, because its own prediction is now very uncertain.
- A wrong noise model. Set the sensor noise to and the filter's to , so the filter believes the sensor is ten times better than it is. Question: what do the innovation chart and the readout innovations inside the 95% region show? What to see: the innovations jump far outside the violet band and the readout drops far below 95%. The filter is overconfident. Press set r = σ and watch it recover. (Try also very small with the back and forth target.)
3. How the filter works #
The model #
The state is : position and velocity. Between two measurements, seconds apart, the target moves with constant velocity plus a random acceleration. The sensor sees only the position:
Here is the identity. This is the constant-velocity model. The number (the process noise) says how strongly the velocity can change; (the measurement noise) says how noisy the sensor is. In the simulation s.
Where the matrix comes from
Assume the acceleration is white noise with spectral density . Over one step, the position changes by and the velocity by (on top of the constant-velocity motion). The covariance of integrated over is , one block for each axis.
Predict #
Push the mean and the covariance through the model:
moves and stretches the ellipse (position uncertainty grows with velocity uncertainty), and makes it larger. This is the growing violet ellipse.
Update #
Compare the measurement with the predicted measurement , then correct:
For a linear model with Gaussian noise, this gives the exact posterior: is Gaussian with mean and covariance . So is the estimate with the smallest mean squared error. (The widget computes in the equivalent "Joseph form" , which stays symmetric and positive definite with rounding errors.)
Why the gain balances model and data #
Look at one coordinate with a direct position sensor (). Then and
The update is a weighted average of the prediction and the measurement. Each one gets a weight proportional to the other's variance, so the more certain source counts more. The precisions (inverse variances) add, so the result is more certain than either source alone.
- A perfect sensor () gives : copy the measurement.
- A useless sensor () gives : keep the prediction.
- A perfect model () makes shrink step by step, so : the filter stops listening.
Multiplying , and the starting by the same number multiplies every covariance by that number and leaves unchanged. The steady state does not depend on the starting , so the steady-state gain depends only on the ratio : "how much do I trust the model compared with the sensor".
Small example. Prediction with , measurement with . Then , and . The new variance is smaller than both and .
A filter predicts with . The sensor reads with . What is the updated estimate ?
, so . The prediction is more certain (), so the estimate stays closer to it. The midpoint would be right only if .
The filter can check itself #
If the model is right, the innovations are Gaussian with mean and covariance , and they are independent over time. So about 95% of them should lie in the 95% region (the 95% quantile of with 2 degrees of freedom). The readout innovations inside the 95% region counts exactly this. Far fewer than 95% means the filter is overconfident ( or too small); 100% for a long time means it is too cautious. The same test is used to monitor real trackers and weather models.
The target enters the no-signal zone and no measurements arrive for 2 seconds. What happens to the covariance during this time?
Without measurements there is no update, so no step can make smaller. Each predict step adds , and turns velocity uncertainty into position uncertainty, so the ellipse grows faster and faster. This is why the first measurement after the gap gets a gain close to .
4. A nonlinear sensor: EKF and particle filter #
A radar does not measure and . It measures the range (distance) and the bearing (angle) of the target:
The positions that fit one measurement form a curved band: a piece of a ring. A Gaussian cannot have this shape, so the Kalman filter is no longer exact. Two standard fixes:
- The extended Kalman filter (EKF) replaces by its first-order Taylor expansion at the prediction: it uses the Jacobian at in place of , and as the predicted measurement. With ,
The angle part of the innovation must be wrapped to .
- The particle filter (bootstrap filter) represents the belief by samples with weights . Predict: move every particle with the model and its own random noise. Update: multiply each weight by the likelihood and normalize. When the effective sample size falls below , resample: draw new particles in proportion to the weights, so unlikely particles die and likely ones are copied. The particle filter can represent any shape, and it becomes exact as . The price is times more work.
Watch the particles bend into an arc, then pick other examples under Try. The yellow triangle is the radar. The orange band holds the positions that fit the current measurement (range , bearing ). Violet: the EKF estimate and its 95% ellipse. Aqua: the particles (bigger dots have larger weights) and their mean (ring). Both filters get the same measurements. The table compares their errors, how often their 95% ellipse contains the truth (for the particle filter: the ellipse of the particles' mean and covariance, not drawn), and the cost. Try wrong first guess: the EKF needs one or two seconds to find the target; the particles find it at once.
- The banana. Start with banana (selected when the page opens): the range is very precise () but the bearing is poor (). Question: what shape does the particle cloud take, and does the EKF ellipse contain the truth about 95% of the time? What to see: the particles form a thin arc around the radar. The EKF ellipse is a straight, flat approximation of that arc. In our one-minute runs it contained the truth only about 35–55% of the time, and its error was about 1.5 times the particle filter's. The particle filter stays near 90–95%. (The table uses only the last 10 s, so its numbers move up and down; watch them for a while.)
- How many particles? Pick few particles (), then move up to a few thousand. Question: what happens to the effective sample size, the error and the time per step? What to see: with few particles the cloud collapses to a handful of points after each resampling and can lose the target. More particles give a smoother cloud and a smaller error, but the error stops improving at some point (the measurements limit it), while the cost keeps growing in proportion to .
Why does the EKF ellipse often miss the truth in the banana example?
The EKF uses the right noise values and both measurements. Its only approximation is the first-order Taylor expansion of . With at a range of about 6, the band of positions that fit one measurement is several units long and clearly curved, but only about wide. A straight (Gaussian) approximation of this band is off by much more than its width, so the EKF becomes overconfident.
5. From tracking to weather forecasting #
Weather forecasting solves the same problem at a huge scale. The state is the whole atmosphere on a grid (temperature, wind, pressure and humidity at every point): hundreds of millions of numbers or more. The measurements are tens of millions of observations a day from satellites, weather stations, balloons, aircraft and ships. Combining a model forecast with observations is called data assimilation, and it uses the same words:
| Kalman filter | Data assimilation |
|---|---|
| prediction , covariance | background (first guess) , background error covariance |
| measurement , matrix | observations , observation operator |
| innovation | innovation, "observation minus background" |
| update | analysis |
| predict step | forecast with the weather model, until the next cycle (every 6 or 12 hours) |
The difficulty is size. With state variables, would have entries: it cannot be stored, let alone multiplied by . Two families of methods avoid this:
- The ensemble Kalman filter (EnKF) runs a few dozen forecasts (an ensemble) and uses their sample covariance in place of . This is a particle-like idea, but the update is still the Kalman update, not a reweighting.
- 4D-Var looks for the initial state that best fits all observations in a time window and the background, by minimizing
where is the model forecast from . The gradient comes from the adjoint model (reverse-mode differentiation of the forecast model). For a linear model with Gaussian errors and no model error, 4D-Var gives the same estimate at the end of the window as the Kalman filter.
Why not a particle filter? In high dimension the weights collapse: one particle gets almost all the weight. The number of particles needed grows exponentially with the effective dimension of the problem (Snyder and co-authors, 2008), so pure particle filters are not used for global weather models. In the widget above you can see the start of this problem with in only 4 dimensions.
A weather model has state variables. Why can the forecast centre not run the Kalman filter equations exactly?
The formulas exist (with the EKF for nonlinear models), but they need , which is . Ensembles (EnKF) approximate by a low-rank sample covariance, and 4D-Var never forms it: it minimizes a cost function with adjoint gradients. The other options are false: a forecast centre has tens of millions of observations a day, and the gain is not small in general.
6. Related lessons #
- Positive definite matrices and Cholesky: covariance matrices, ellipses, and why the posterior covariance is "smaller" than the prior one (the Loewner order).
- QR and least squares: the update as a weighted least-squares problem, and square-root filters.
- Jacobians, Hessians and Taylor: the linearization behind the EKF.
- Gaussian integrals and Laplace's method: working with Gaussians.
- State-space models: the same linear recurrence as a deep-learning layer.
- Probability and Statistics: the multivariate Gaussian, Bayesian inference, and Monte Carlo with importance sampling (the idea behind particle weights).
- ML for Science: a full lesson on data assimilation, the Kalman filter and 4D-Var.
- Generative models: diffusion models used for data assimilation.