Skip to content

State Estimation

Conceptual

State Estimation is the family of techniques that recover a robot’s best guess of its true internal state — quantities like position, velocity, and orientation — from sensor data that is always noisy, incomplete, and biased. It matters because a robot can never measure its true state directly: every controller acts on an estimate, not the truth, so bad estimation means bad control.

The fundamental problem is that sensors lie in three ways at once. They are noisy (random jitter on every reading), partial (a wheel encoder tells you distance but not orientation), and biased (a gyro drifts, a GPS sits a meter off). You need one clean, coherent state to act on — so you must combine many imperfect signals over time.

Prerequisites

The Predict–Correct Loop

Nearly every estimator runs the same two-step engine. Predict uses a motion model to project the state forward (“I commanded the wheels forward, so I should now be ~10 cm ahead”). Correct waits for a measurement, then pulls the prediction toward it — weighted by how much you trust the model versus the sensor.

┌──────────────────────────────────────────┐
│ │
▼ │
┌───────────┐ motion model ┌───────────┐ │
│ PREDICT │ ────────────────► │ belief │ │
│ (advance) │ + control input │ (estimate)│ │
└───────────┘ └─────┬─────┘ │
│ │
measurement z ──────────────────►┌───▼─────┐ │
│ CORRECT │ ───┘
│ (nudge) │
└─────────┘

This is the idea of an observer: a model of the system that runs alongside the real robot, driven by the error between what it predicted the output would be and what was actually measured. The Luenberger observer is the deterministic version (a fixed gain on that error); the Kalman filter is the probabilistic version (the gain is computed from how uncertain the model and sensor are).

Worked Example: 1D Inverse-Variance Fusion

This is the heart of the Kalman correction step without the full machinery. Suppose your motion model predicts position = 10.0 m with variance 4 (fairly uncertain), and a range sensor measures 11.0 m with variance 1 (more trustworthy). Lower variance means more trust, so we weight each estimate by its inverse variance (1/4 and 1/1):

fused = (10.0/4 + 11.0/1) / (1/4 + 1/1)
= (2.5 + 11.0) / (0.25 + 1.0)
= 13.5 / 1.25
= 10.8 m
fused variance = 1 / (1/4 + 1/1)
= 1 / 1.25
= 0.8
def fuse(pred, pred_var, meas, meas_var):
inv = 1/pred_var + 1/meas_var
return (pred/pred_var + meas/meas_var) / inv, 1/inv
print(fuse(10.0, 4.0, 11.0, 1.0)) # (10.8, 0.8)

Two things to notice. The fused estimate (10.8) sits closer to the measurement, because the sensor was more trusted. And the fused variance (0.8) is smaller than either input — combining two imperfect sources leaves you more certain than you were with either alone.

Route to the Specific Tools

State estimation is the umbrella; pick the tool to fit the problem:

  • Kalman filter — the Gaussian workhorse; full predict-correct with matrices for linear systems (EKF/UKF for nonlinear).
  • Complementary filter — a lightweight, gain-based blend, common for fusing gyro and accelerometer on small embedded targets.
  • Particle filters / SLAM — for localization and mapping where the belief is non-Gaussian or multi-modal.

Sources