AnyLearn
All lessons
Roboticsadvanced

The Kalman Filter

Fuse noisy sensors over time with provably optimal estimates. Covers the state and noise model, predict and update equations with the Kalman gain, why it's optimal for linear-Gaussian systems, and the Extended KF for nonlinear robots.

Updated · AI-authored, review-gated · how lessons are made

Not signed in: your progress and quiz score won't be saved.
Progress1 / 9

Why we need to filter sensor data

Every robot sensor lies — a little. GPS has 3 m noise. An IMU accumulates drift. Wheel odometry slips. No single reading is trustworthy in isolation, but a sequence of noisy readings, combined with a model of how the robot moves, yields an estimate far better than any individual measurement.

The Kalman filter (Rudolf Kálmán, 1960) solves exactly this: given a linear dynamical system driven by Gaussian noise and observed through a linear measurement model corrupted by Gaussian noise, it computes the minimum-variance unbiased estimate of the state at each timestep. It is not a heuristic — it is provably optimal under these assumptions. Outside linear-Gaussian systems, it becomes an approximation, but a remarkably robust one. The Apollo Guidance Computer used a Kalman filter for lunar navigation in 1969; your phone uses a variant for GPS-IMU fusion today.

Full lesson text

All 9 steps on one page, for reading, reference, and search.

Show

1. Why we need to filter sensor data

Every robot sensor lies — a little. GPS has 3 m noise. An IMU accumulates drift. Wheel odometry slips. No single reading is trustworthy in isolation, but a sequence of noisy readings, combined with a model of how the robot moves, yields an estimate far better than any individual measurement.

The Kalman filter (Rudolf Kálmán, 1960) solves exactly this: given a linear dynamical system driven by Gaussian noise and observed through a linear measurement model corrupted by Gaussian noise, it computes the minimum-variance unbiased estimate of the state at each timestep. It is not a heuristic — it is provably optimal under these assumptions. Outside linear-Gaussian systems, it becomes an approximation, but a remarkably robust one. The Apollo Guidance Computer used a Kalman filter for lunar navigation in 1969; your phone uses a variant for GPS-IMU fusion today.

2. State, process model, and noise

Define the state vector xtRn\mathbf{x}_t \in \mathbb{R}^n — whatever you want to estimate (position, velocity, orientation, bias). The process model says how the state evolves:

xt=Ftxt1+Btut+wt,wtN(0,Qt)\mathbf{x}_t = F_t \mathbf{x}_{t-1} + B_t \mathbf{u}_t + \mathbf{w}_t, \qquad \mathbf{w}_t \sim \mathcal{N}(\mathbf{0}, Q_t)

where FtF_t is the state transition matrix, BtutB_t \mathbf{u}_t is the effect of control input ut\mathbf{u}_t (e.g. motor commands), and wt\mathbf{w}_t is process noise with covariance QtQ_t.

The measurement model relates observations to the state:

zt=Htxt+vt,vtN(0,Rt)\mathbf{z}_t = H_t \mathbf{x}_t + \mathbf{v}_t, \qquad \mathbf{v}_t \sim \mathcal{N}(\mathbf{0}, R_t)

where HtH_t is the measurement matrix and RtR_t is measurement noise covariance. Tuning QQ and RR is the engineering art of the KF: QQ too small \Rightarrow the filter is overconfident in its model; RR too small \Rightarrow the filter over-trusts noisy sensors.

3. The predict step

The Kalman filter maintains a Gaussian belief over the state: a mean x^t\hat{\mathbf{x}}_t and a covariance Σt\Sigma_t (also written PtP_t in many texts). The filter alternates between predict and update.

Predict (propagate the prior through the process model):

x^tt1=Ftx^t1t1+Btut\hat{\mathbf{x}}_{t|t-1} = F_t \hat{\mathbf{x}}_{t-1|t-1} + B_t \mathbf{u}_t

Σtt1=FtΣt1t1Ft+Qt\Sigma_{t|t-1} = F_t \Sigma_{t-1|t-1} F_t^\top + Q_t

The mean propagates linearly. The covariance grows: FtΣFtF_t \Sigma F_t^\top rotates and scales the uncertainty ellipsoid; +Qt+ Q_t inflates it with process noise. Uncertainty only grows in the predict step — you can never become more certain without a measurement. This is why a robot navigating without sensors quickly becomes lost: each prediction inflates Σ\Sigma.

4. The update step and Kalman gain

When a measurement zt\mathbf{z}_t arrives, compute the innovation (surprise):

y~t=ztHtx^tt1\tilde{\mathbf{y}}_t = \mathbf{z}_t - H_t \hat{\mathbf{x}}_{t|t-1}

The Kalman gain KtK_t determines how much to trust the measurement vs the prediction:

Kt=Σtt1Ht(HtΣtt1Ht+Rt)1K_t = \Sigma_{t|t-1} H_t^\top \left( H_t \Sigma_{t|t-1} H_t^\top + R_t \right)^{-1}

Then update:

x^tt=x^tt1+Kty~t\hat{\mathbf{x}}_{t|t} = \hat{\mathbf{x}}_{t|t-1} + K_t \tilde{\mathbf{y}}_t

Σtt=(IKtHt)Σtt1\Sigma_{t|t} = (I - K_t H_t) \Sigma_{t|t-1}

Intuition: if Rt0R_t \to 0 (perfect sensor), KtHt1K_t \to H_t^{-1} and the update fully trusts the measurement. If RtR_t \to \infty (useless sensor), Kt0K_t \to 0 and the state is unchanged. The filter interpolates between these extremes based on the relative magnitudes of predicted uncertainty and sensor noise.

5. Python Kalman update step

A clean implementation of one predict-update cycle:

import numpy as np

def kalman_predict(x, P, F, B, u, Q):
    """Predict step. Returns (x_pred, P_pred)."""
    x_pred = F @ x + B @ u
    P_pred = F @ P @ F.T + Q
    return x_pred, P_pred

def kalman_update(x_pred, P_pred, z, H, R):
    """Update step. Returns (x_upd, P_upd, innovation)."""
    y = z - H @ x_pred                         # innovation
    S = H @ P_pred @ H.T + R                   # innovation covariance
    K = P_pred @ H.T @ np.linalg.inv(S)        # Kalman gain
    x_upd = x_pred + K @ y
    P_upd = (np.eye(len(x_pred)) - K @ H) @ P_pred
    return x_upd, P_upd, y

# 1-D constant-velocity example
dt = 0.1
F = np.array([[1, dt], [0, 1]])   # [pos, vel] transition
H = np.array([[1, 0]])            # observe position only
Q = np.diag([0.01, 0.1])
R = np.array([[1.0]])
B = np.zeros((2, 1))
u = np.zeros((1,))

x = np.array([0.0, 1.0])          # initial state
P = np.eye(2) * 1.0               # initial covariance

For numerical stability on embedded systems, use the Joseph form for the covariance update: P=(IKH)P(IKH)+KRKP = (I - KH)P(I - KH)^\top + KRK^\top, which remains positive-semidefinite even with floating-point rounding.

6. Optimality and the linear-Gaussian assumptions

The Kalman filter is the BLUE — Best Linear Unbiased Estimator. Formally, it minimises the trace of the posterior covariance Σtt\Sigma_{t|t} over all linear estimators, without assuming Gaussianity. Under the additional Gaussian assumptions, it is the MAP (maximum a posteriori) and minimum mean-squared-error estimator over all estimators — not just linear ones.

What breaks this optimality?

  • Non-Gaussian noise: heavy tails (outlier measurements) can yank the mean far off. Robust variants (Huber loss, particle filters) handle this.
  • Nonlinearity: a robot turning in a circle has a nonlinear motion model. Applying FF from a linearised system accumulates error.
  • Unmodelled correlations: if two sensors share a common error source (e.g. both use the same clock), treating them as independent inflates confidence.

Knowing these failure modes is as important as knowing the equations.

7. Kalman predict-update cycle

The two-step recursion that runs at every timestep.

flowchart LR
  P["Prior belief x and Sigma"]
  PR["PREDICT: propagate via F and Q"]
  PP["Predicted belief x pred and Sigma pred"]
  Z["New measurement z"]
  IN["Innovation y = z minus H x pred"]
  KG["Kalman gain K"]
  UP["UPDATE: correct mean and covariance"]
  PO["Posterior belief x upd and Sigma upd"]
  P --> PR
  PR --> PP
  PP --> IN
  Z --> IN
  PP --> KG
  IN --> UP
  KG --> UP
  UP --> PO
  PO --> P

8. The Extended Kalman Filter (EKF)

Most real robots have nonlinear process and measurement models. The EKF linearises them at the current estimate using first-order Taylor expansion:

xt=f(xt1,ut)+wtFtfxx^t1t1\mathbf{x}_t = f(\mathbf{x}_{t-1}, \mathbf{u}_t) + \mathbf{w}_t \qquad \Rightarrow \qquad F_t \approx \left.\frac{\partial f}{\partial \mathbf{x}}\right|_{\hat{\mathbf{x}}_{t-1|t-1}}

zt=h(xt)+vtHthxx^tt1\mathbf{z}_t = h(\mathbf{x}_t) + \mathbf{v}_t \qquad \Rightarrow \qquad H_t \approx \left.\frac{\partial h}{\partial \mathbf{x}}\right|_{\hat{\mathbf{x}}_{t|t-1}}

The predict and update equations are otherwise identical, but using the Jacobians FtF_t and HtH_t. For a ground robot with state [x,y,θ,v][x, y, \theta, v], the motion Jacobian f/x\partial f / \partial \mathbf{x} is straightforward but tedious to derive by hand — tools like autodiff (JAX, PyTorch) or symbolic differentiation (SymPy) automate this. The EKF works well when the nonlinearity is mild over one timestep; for large steps or sharp turns it loses accuracy. The Unscented KF (UKF) uses deterministic sigma points to capture second-order statistics without computing Jacobians at all — better accuracy at similar cost.

9. Sensor fusion in practice: GPS-IMU example

A classic fusion task: combine a 1 Hz GPS (high noise, low rate, absolute) with a 200 Hz IMU (low noise, high rate, drifts).

State: x=[px,py,pz,vx,vy,vz,bax,bay,baz]\mathbf{x} = [p_x, p_y, p_z, v_x, v_y, v_z, b_{ax}, b_{ay}, b_{az}]^\top — position, velocity, and accelerometer bias.

Process model: integrate IMU at 200 Hz, including bias as a random walk: b˙a=nb\dot{\mathbf{b}}_a = \mathbf{n}_b. The predict step runs 200× per second.

Measurement model: GPS provides [px,py,pz][p_x, p_y, p_z]^\top. H=[I303×6]H = [I_3 | \mathbf{0}_{3 \times 6}], R=diag(σGPS2)R = \text{diag}(\sigma_{\text{GPS}}^2). Update runs only when a GPS fix arrives.

Result: the IMU gives smooth, high-rate pose between GPS fixes; GPS corrects the drift. The covariance blooms when GPS is lost (tunnels, urban canyons) and collapses after a good fix — exactly what the filter equations predict. This architecture, called loosely coupled GPS-IMU fusion, is the default in commercial autopilots.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. In the Kalman predict step, the posterior covariance $\Sigma_{t|t-1} = F_t \Sigma_{t-1|t-1} F_t^\top + Q_t$. What does the $+ Q_t$ term represent?
    • The measurement noise from the sensor used in the previous update step.
    • The process noise added because the motion model is imperfect, inflating uncertainty over time.
    • The Kalman gain that will be applied in the next update step.
    • The innovation covariance needed to weight the new measurement.
  2. The Kalman gain $K_t = \Sigma_{t|t-1} H_t^\top (H_t \Sigma_{t|t-1} H_t^\top + R_t)^{-1}$. If $R_t \to 0$, what happens to the state update?
    • The update is skipped because the sensor is considered faulty.
    • The state fully adopts the measurement — the prediction is ignored.
    • The Kalman gain goes to zero and the state is unchanged.
    • The covariance resets to the identity matrix.
  3. The Extended Kalman Filter handles nonlinear models by:
    • Running the standard Kalman filter multiple times and averaging the results.
    • Linearising $f$ and $h$ via their Jacobians evaluated at the current estimate.
    • Propagating a set of deterministic sigma points through the nonlinear functions.
    • Replacing the covariance matrix with a particle-based sample approximation.
  4. In loosely coupled GPS-IMU fusion, the predict step runs at 200 Hz and the update step at 1 Hz. Why does covariance bloom during a GPS outage?
    • The IMU measurement noise $R$ increases when GPS is unavailable.
    • Without GPS updates, repeated predict steps accumulate process noise $Q$ in the covariance with no measurement to shrink it.
    • The state transition matrix $F$ becomes singular without GPS observations.
    • The Kalman gain becomes negative, causing the covariance to grow rather than shrink.
  5. Which assumption is required for the Kalman filter to be the minimum-variance estimator over ALL estimators (not just linear ones)?
    • The state transition matrix $F$ must be invertible.
    • Both the process noise $\mathbf{w}_t$ and measurement noise $\mathbf{v}_t$ must be Gaussian.
    • The measurement matrix $H$ must have full row rank.
    • The sampling rate must be at least twice the highest frequency in the state.

Related lessons