gwordal

Lesson 1 of 5 · 20 min

Why sensors lie

A robot never sees the world. It sees numbers: a count of encoder ticks, a time of flight in microseconds, a voltage from an accelerometer. Every one of those numbers is a slightly wrong report about something real. State estimation is the craft of turning a stream of wrong reports into the best possible guess of what is actually happening, and the Kalman filter is the most famous tool for it. Before we build one, we need to be precise about how sensors go wrong, because a filter is only as good as its model of the errors.

Three ways a sensor is wrong

Most errors fall into three families, and they behave very differently over time.

ErrorWhat it looks likeDoes averaging fix it?
NoiseEach reading jumps randomly around the true valueYes, it shrinks
BiasEvery reading is off by the same constant amountNo, it stays
DriftThe offset itself creeps slowly with time or temperatureNo, it grows

Noise comes from thermal effects in the electronics, from quantisation in the analog-to-digital converter, and from the physics of the measurement itself. Bias comes from manufacturing tolerance and mounting: a distance sensor fixed 1.5 cm behind the bumper reads 1.5 cm long forever. Drift is bias that moves. A gyroscope's zero point wanders as the chip warms up, and that wandering is the reason pure gyro dead reckoning always fails eventually.

A sensor model

To reason about errors we write them down as an equation. For a sensor that measures a quantity x directly, the standard model is:

z = x + b + v

Here z is the reading you get, x is the true value, b is the bias, and v is the noise. We assume v is random with an average of zero, so noise alone never pushes the readings in one direction. How big is the randomness? We measure it with the variance, the average of the squared deviations from the mean:

variance = (1 / (n - 1)) * sum of (z_i - mean)^2

The square root of the variance is the standard deviation, written as sigma, which has the same units as the reading and is what datasheets usually quote. Filters prefer variance to standard deviation for a practical reason: variances of independent errors simply add, while standard deviations do not. You will see variance everywhere from lesson 3 onward, and it will be called R for the sensor and Q for the process.

Simulate a noisy distance sensor

Let us build a fake ultrasonic sensor. The true distance to a wall is 100 cm, the sensor has a bias of 1.5 cm and noise with a standard deviation of 2 cm. We take 1000 readings and compute the statistics just as you would on real logged data.

noisy_sensor.py

Look at the first block. The standard deviation comes out at about 2.04 cm, close to the 2.00 we put in, so the statistics recovered the noise. The mean is about 101.46 cm, not 100: even with a thousand readings the answer is wrong by about 1.46 cm. That leftover error is the bias, and no amount of extra data will remove it.

Why averaging works on noise and only on noise

The second block of output shows the benefit. If the errors in different readings are independent, the variance of an average of n readings is the single-reading variance divided by n, so the standard deviation shrinks by the square root of n:

sigma_avg = sigma / sqrt(n)

Averaging 4 readings halves the spread (2.00 down to 1.00 cm), 16 readings quarter it (0.50 cm), and 100 readings cut it by a factor of ten (0.20 cm). The reason is cancellation: positive and negative errors partly offset each other. A bias has the same sign in every reading, so there is nothing to cancel.

The square-root law also tells you the price of precision. To halve the noise you need four times as many readings, which means four times as long if the sensor is slow. A robot moving at speed cannot wait that long, which is the first hint that plain averaging will not be enough.

Drift: the error that grows

Drift is more dangerous than bias because it is not constant. The classic case is integrating a gyroscope. A gyro reports angular rate in degrees per second, and to get the angle you add up rate times the time step. Any small constant offset in the rate is then accumulated forever. Suppose the robot is standing perfectly still, the gyro has a bias of only 0.05 deg/s and noise of 0.3 deg/s. Watch what happens to the integrated angle.

gyro_drift.py

The robot never moved, yet after one minute the integrated angle reads about 3 degrees, and it keeps climbing at roughly 0.05 degrees every second. The tiny bias times the elapsed time gives 0.05 * 60 = 3 degrees, and the noise adds only a small random wobble on top because it averages out while the bias does not. That is exactly why gyro-only attitude estimates fall apart.

What can you do about it?

You could calibrate: hold the robot still, measure the average gyro output, and subtract it. That helps, but the bias changes with temperature and age, so a calibration done on your bench is stale by the time the robot is running in the sun. The better idea is to let the robot continuously estimate the bias and the true state together, using a second sensor with different weaknesses. An accelerometer measures tilt with no drift, but it is noisy and confused by vibration. The gyro is smooth and fast, but it drifts. Each sensor's weakness is the other's strength, and the next lessons show how to combine them using the variances we just learned to compute.

Check yourself

You average 10000 readings from a distance sensor that has a constant 3 cm bias and 2 cm of random noise. The average is closest to which value?

Check yourself

A sensor has noise with a standard deviation of 5 units. You average 25 independent readings. What is the standard deviation of the average?