Probability for Robotics · Theory · M7
M7-T1 — The Kalman Filter in One Dimension
Prediction adds a little variance. The correction mixes in the reading with a weight set by how much each side is trusted.
The Kalman filter is the Bayes filter for the case where everything is Gaussian and linear, and in one dimension it fits on a line of code per step. This lesson derives it from the two tools of module 4 (the variance of a sum and the fusion of two Gaussians), runs it on a robot with a noisy position sensor, and finds the number that makes it work: the gain, the fraction of each new surprise that the filter lets into its estimate.
Learning objectives
After this lesson, you should be able to:
- Write the scalar Kalman filter (prediction and correction) and explain each line in terms of means and variances.
- Derive it from the Bayes filter with Gaussian beliefs, using the variance of a sum and the fusion of Gaussians.
- Interpret the Kalman gain as a ratio of variances, and compute the steady-state gain and variance.
- Compare the filter with dead reckoning and with the raw sensor on a simulated run.
The intuition
A robot on a rail is commanded to move 0.5 m per step. Its motion is noisy (a standard deviation of 10 cm per step), so after the command it knows where it is a little less well. A position sensor then gives a reading with a standard deviation of 20 cm. What should the robot believe?
- If it relied on the commands alone (dead reckoning), its uncertainty would grow without limit: after 30 steps the standard deviation is 1.14 m.
- If it relied on the sensor alone, the error would stay at 20 cm, however many readings it takes: it throws the previous ones away.
- The Kalman filter keeps both: it predicts with the command, then moves its estimate towards the reading by a fraction K of the disagreement. After a few steps its standard deviation is 12.5 cm, better than the sensor and than the motion alone.
The two panels show what the filter does. At the first step the prior is poor (a standard deviation of 1 m) so the gain is 0.96: the filter nearly copies the reading. As the estimate becomes good, the gain falls to 0.39 and the filter increasingly trusts its prediction, nudging towards each reading rather than jumping to it. The gain settles because the two sources of uncertainty balance: each prediction adds 0.01 m² of variance, each correction removes some, and the filter reaches a state where the two cancel.
The gain is the whole story. It is large when the filter is unsure and the sensor is good, small when the filter is confident or the sensor is poor. In one line:
K = (my uncertainty) / (my uncertainty + the sensor’s uncertainty). The new estimate is the prediction plus K times the surprise.
Definitions
- Belief
- The Kalman filter holds the belief as a Gaussian: a mean (the estimate) and a variance (its uncertainty).
- Motion model
- , with : the commanded displacement plus noise of variance (the process noise).
- Measurement model
- , with : the position plus noise of variance (the measurement noise).
- Innovation
- : the surprise, the reading minus what the filter predicted.
- Kalman gain
- The fraction of the innovation that is added to the estimate. Between 0 and 1.
- Prior / posterior
- (after the prediction) and (after the correction).
Derivation: from the Bayes filter with Gaussians
Assume the belief at time is . The Bayes filter has two steps; each can be done exactly because the Gaussian is closed under the operations involved.
Prediction: a sum of independent Gaussians
The new position is the old position plus the (known) command plus noise. (the belief) and (the noise) are independent.
Means add, and variances of independent quantities add (the variance lesson). A constant shifts the mean and has no variance.
A sum of independent Gaussians is Gaussian (the convolution derivation of the variance lesson), so the predicted belief is again a Gaussian. This is the law of total probability evaluated exactly.
Correction: fusion of two Gaussians
As a function of , the likelihood of the reading is , which is a Gaussian in centred at with variance . Bayes' rule multiplies it by the predicted belief.
Bayes’ rule (correction step of the Bayes filter): predicted belief times likelihood.
The product of two Gaussians is a Gaussian, found by completing the square (the fusion lesson). Precisions add.
The gain form of the same formulas: the estimate moves towards the reading by a fraction of the difference.
The steady state
Let be the predicted variance. After a correction the variance is , and the next prediction adds . In steady state the predicted variance reproduces itself:
The variance after correction plus the process noise gives the next predicted variance. A fixed point of the recursion.
Multiply out and solve the quadratic (the positive root). This is the scalar algebraic Riccati equation.
The numbers of the example. The variance after correction is , a standard deviation of 0.125 m.
The Kalman gain is the prediction’s share of the total variance. If the sensor is perfect (r → 0) K → 1 and the filter copies it; if the sensor is useless (r → ∞) K → 0 and the filter ignores it.
A worked example
The robot of the figure: command m per step, m² (10 cm) of motion noise, m² (20 cm) of sensor noise, and a poor initial belief . One simulated run of 30 steps, then 500 runs.
- Step 1. Prediction: , . Gain: . The reading is 1.238 (truth 0.620), so the estimate jumps to with a standard deviation of 0.196 m: the filter has taken nearly all of the reading, because its own prior was nearly worthless.
- Steps 2 and 3. The gain falls to 0.548 and 0.444, and the standard deviation to 0.148 and 0.133 m.
- From step 5 on. The gain is 0.397, then 0.390 from step 10: the steady-state value . The standard deviation settles at 0.125 m, below the sensor's 0.2 m and far below the 1.14 m that dead reckoning would have reached after 30 steps.
- Is the claim true? Over 500 runs the root-mean-square error of the filter at step 30 is 0.126 m, while it claims 0.125 m. The raw readings have an error of 0.199 m. The filter is both better than the sensor and honest about it.
import math
from robotprob import Rng, kalman1d_predict, kalman1d_update, mean
q, r = 0.01, 0.04 # process noise and measurement noise (variances, m^2)
u = 0.5 # the commanded step
def run(seed, steps=30):
rng = Rng(seed)
x = 0.0 # the true position
mu, var = 0.0, 1.0 # the belief: a poor initial guess
rows = []
for t in range(1, steps + 1):
x += u + rng.gauss(0.0, math.sqrt(q)) # the robot moves, with noise
z = x + rng.gauss(0.0, math.sqrt(r)) # the sensor reads, with noise
mu, var = kalman1d_predict(mu, var, u, q)
mu, var, k = kalman1d_update(mu, var, z, r)
rows.append((t, x, z, mu, var, k))
return rows
rows = run(11)
print('step truth reading estimate std gain')
for t, x, z, mu, var, k in rows:
if t in (1, 2, 3, 5, 10, 20, 30):
print(str(t).rjust(4), str(round(x, 3)).rjust(7), str(round(z, 3)).rjust(7), str(round(mu, 3)).rjust(8), str(round(math.sqrt(var), 3)).rjust(6), str(round(k, 3)).rjust(6))
p_bar = (q + math.sqrt(q * q + 4 * q * r)) / 2 # the steady state
k_inf = p_bar / (p_bar + r)
print('steady state: gain', round(k_inf, 4), ' std after the update', round(math.sqrt((1 - k_inf) * p_bar), 4), ' reading std', math.sqrt(r), ' dead reckoning after 30 steps', round(math.sqrt(1 + 30 * q), 3))
errs, errs_raw = [], []
for seed in range(1, 501): # is the filter's own claim about its accuracy true?
t, x, z, mu, var, k = run(seed)[-1]
errs.append(mu - x)
errs_raw.append(z - x)
print('500 runs, step 30: rms error of the filter', round(math.sqrt(mean([e * e for e in errs])), 4), ' filter std claims', round(math.sqrt(rows[-1][4]), 4), ' rms error of the raw reading', round(math.sqrt(mean([e * e for e in errs_raw])), 4))step truth reading estimate std gain 1 0.62 1.238 1.21 0.196 0.962 2 1.293 1.581 1.639 0.148 0.548 3 1.91 1.935 2.049 0.133 0.444 5 3.045 2.844 2.916 0.126 0.397 10 5.284 4.959 5.253 0.125 0.39 20 10.657 10.719 10.66 0.125 0.39 30 15.142 15.241 15.356 0.125 0.39 steady state: gain 0.3904 std after the update 0.125 reading std 0.2 dead reckoning after 30 steps 1.14 500 runs, step 30: rms error of the filter 0.1261 filter std claims 0.125 rms error of the raw reading 0.1988
kalman1d_predict(mean, var, u, q) and kalman1d_update(mean, var, z, r) are the two steps. The robot is simulated, so its true position is known and the filter’s claim can be tested.In robotics
Everywhere a quantity is tracked with a model and a sensor
The scalar filter is the template for fusing a model with a measurement: a battery's state of charge (current integration plus voltage), a motor's temperature, the altitude of a drone from a barometer and an integrated acceleration, the temperature of a heater. In each, a model predicts and a sensor corrects, and the filter weighs them by their variances. The UAV course derives the same filter from a different starting point in Kalman Filter and implements it in Implement a Kalman Filter in Python, and the Perception course shows the intuition for tracking in Simple Filtering and Kalman Filter Intuition.
Two knobs: q and r
Only the ratio of the process noise q to the measurement noise r matters for the steady-state gain: depends on . A large ratio means “the model is unreliable, trust the sensor” and gives a gain near 1 and a fast, noisy filter. A small ratio means “trust the model” and gives a small gain and a smooth, slow one. M7-T3: Innovation, Gain and Tuning Q and R shows how to choose them from data.
A free uncertainty estimate
The variance the filter carries is a prediction of its own error, and it needs no ground truth to be computed. It tells downstream software how much to trust the estimate, widens when readings stop arriving, and can drive decisions: a robot that waits for cm before docking, for example. Whether it can be believed is the subject of the last lesson of this module.
The gain schedule is not tuned
Unlike the fixed gain of a complementary filter, the Kalman gain is computed from the variances at every step and changes as information accumulates: large at the start, small later, and large again after a gap in the readings (since the variance grows during the gap). That adaptivity is the reason to use the filter instead of a constant-gain blend.
One dimension is the basis for more
Every ingredient generalises: variances become covariance matrices, the gain a matrix, and the ratio a matrix inverse. The structure, predict then correct with a gain, is unchanged.
Common misconceptions
“The Kalman filter averages the readings.”
It averages the prediction and the reading with weights set by their variances, and the weights change from step to step. A plain average of readings treats all of them equally and has no model: it could not follow a moving robot.
“A small gain means the filter is ignoring the sensor.”
It means the filter trusts its prediction more than the next reading, because the prediction is accurate. The sensor is still used at every step; it just corrects less each time. The gain rises again whenever the filter’s uncertainty rises.
“The filter’s variance is the error of the estimate.”
It is the filter’s claim about the error, computed from q and r. If q or r is wrong, the claim is wrong. Compare it with real errors (as in the 500-run check) before trusting it.
“The estimate can never be worse than the sensor.”
With correct models it is better. With a mis-specified model (a q that is too small for a robot that really slips, say) the filter trusts its prediction too much, lags behind the truth and can be worse than the raw sensor. Module 7 ends with how to tell.
Key takeaways
- Prediction adds the command to the mean and the process variance q to the variance. The belief spreads at every step.
- Correction: K = σ̄²/(σ̄² + r), μ = μ̄ + K(z − μ̄), σ² = (1 − K)σ̄². The gain is the prediction’s share of the total variance.
- Both steps are exact for Gaussians because sums and products of Gaussians stay Gaussian. The filter is the Bayes filter solved in closed form.
- The variance and gain converge to a steady state set by q and r: p = (q + √(q² + 4qr))/2. The estimate beats both dead reckoning and the raw sensor.
- The filter’s variance is its own claim about its accuracy, correct only if q and r are. Check it against real errors.
References and further reading
Each source is marked free or paid. Free to read does not mean free to reuse: the course resources page lists every source with its licence.
- A. Becker, kalmanfilter.net (online tutorial) , whose first chapters work one-dimensional examples with numbers. Free to read; all rights reserved.
- C. Stachniss, “Kalman Filter & EKF” (video lecture) . Free to watch.
- S. Thrun, W. Burgard and D. Fox, Probabilistic Robotics, MIT Press, 2005, section 3.2 (the Kalman filter). Paid book.
- T. D. Barfoot, State Estimation for Robotics, 2nd edition, Cambridge University Press, 2024 , chapter “Linear-Gaussian Estimation”. Free to read as the author’s PDF; the book is copyrighted.
- R. E. Kalman, “A New Approach to Linear Filtering and Prediction Problems”, Journal of Basic Engineering 82 (1), 1960 , the original paper. Paid journal article.
Knowledge check
Three questions. Write an answer, then reveal the explanation. Your answers stay in your browser.
Question 1
A scalar filter has a predicted variance of 0.09 m² and a measurement variance of 0.01 m². What is the gain, and what are the posterior variance and the new estimate if the prediction is 5.00 m and the reading is 5.30 m?
Explanation
K = 0.09 / (0.09 + 0.01) = 0.9, so the filter takes 90% of the innovation. Estimate = 5.00 + 0.9 × 0.30 = 5.27 m. Posterior variance = (1 − 0.9) × 0.09 = 0.009 m², a standard deviation of 0.095 m, slightly better than the sensor’s 0.1 m. The sensor is nine times more precise than the prediction, so it dominates.
Question 2
Compute the steady-state gain and the steady-state posterior variance for q = 0.0004 m² and r = 0.01 m². Compare with q = 0.01 and r = 0.01 and say how the filter behaves differently.
Explanation
For q = 0.0004, r = 0.01: p = (0.0004 + √(1.6e-7 + 1.6e-5)) / 2 = (0.0004 + 0.004024) / 2 = 0.002212, K = 0.002212 / 0.012212 = 0.181, posterior variance (1 − 0.181) × 0.002212 = 0.00181 (σ = 0.043 m). For q = r = 0.01: p = (0.01 + √(1e-4 + 4e-4)) / 2 = (0.01 + 0.02236) / 2 = 0.01618, K = 0.618, posterior variance 0.00618 (σ = 0.079 m). With the smaller process noise the filter trusts its model, uses a small gain (0.18) and is smoother and more accurate (4.3 cm against 7.9 cm); with equal noises it leans on the readings (K = 0.62) and follows quickly but is noisier.
Question 3
A teammate sets the measurement variance r far too small (they trust the sensor 10 times more than they should). Describe what happens to the gain, the filter’s claimed variance and its real error.
Explanation
A too-small r makes the gain larger than it should be: the filter chases every reading, so its estimate inherits most of the sensor noise and is noisier than a correctly tuned filter. Its claimed variance, which is computed from r, is too small: the filter says it is more accurate than it is. The real error is larger than claimed (the filter is overconfident), which a comparison of the real error with the claimed standard deviation or the consistency tests of the last lesson of this module would reveal. The reverse mistake (r too large) gives a sluggish filter that lags behind the truth.
What’s next
The scalar filter showed the idea. The next lesson derives the filter for a state with several components, where the variances become a covariance matrix and the gain a matrix.
Related content
Nothing below is required to finish this lesson.
- LabM7-L1: 1D Kalman Filter
Rover drives along a rail with a noisy range sensor and slipping wheels. Implement predict and update, tune Q and R, and prove with the innovation that the filter is consistent.
Other courses on this site treat neighbouring topics from their own angle:
Get notified when the next lesson and new labs are released.
One email per new lesson or lab.