30% off your first 3 months

Get the deal

Sensor noise and how to smooth it

by DuckyHelperNov 12, 20266 min read
Robotics

TL;DR:

  • Every real sensor reading is the true value plus noise. Averaging several readings shrinks random noise.

  • A moving average of N readings cuts random noise by about √N, but delays a sudden change by (N − 1) / 2 samples.

  • A median filter removes single-sample spikes that an average would smear into the result.

Your robot drives toward a wall and watches a distance sensor. The wall is not moving, yet the readout says 102 cm, then 97, then 101, then 104. If you tell the robot to stop at 100 cm, it will sometimes stop early, sometimes late, and sometimes jerk back and forth. The sensor is not broken. It is noisy, and every sensor you will ever wire up is noisy.

What noise does on a robot

A reading is never the true value. It is reading = true value + noise. The true value is the signal: the part you care about. The noise is the part that changes from one reading to the next for reasons you cannot see, such as electrical hum in the wires, the way light or sound bounces off a surface, or the rounding of a converter that turns a voltage into a number.

Noise matters because robots act on numbers. A controller that reacts to every flicker will make its motors twitch, wear out gears and waste battery. A threshold such as "stop if closer than 30 cm" can fire on a single bad reading. Cleaning up the signal before you use it is one of the first jobs in any robot program.

The idea behind averaging

If the noise is random, with no preferred direction, then some readings are too high and some too low. Add several together and the highs and lows partly cancel, while the true value, which is the same in every reading, adds up fully. Divide by the count and you are left with an estimate that wanders less.

There is a standard result for this. If each reading has random, independent noise with typical size σ (the standard deviation), the average of N readings has typical noise σ / √N. Averaging 4 readings halves the noise. Averaging 100 readings makes it ten times smaller. Notice the price: to halve the noise again you need four times as many readings.

A moving average does this continuously. Keep the last N readings, average them, and every time a new one arrives, drop the oldest. You get one smoothed value per new reading.

Worked example: a moving average over noisy distance readings

A sensor faces a wall exactly 100 cm away. The robot takes ten readings, in centimeters (made-up but typical numbers):

102, 97, 101, 104, 96, 99, 103, 98, 100, 101

The raw readings range from 96 to 104, a spread of 8 cm. Now take a moving average with a window of N = 5. Each output is the sum of five consecutive readings divided by 5.

  1. Readings 1 to 5: 102 + 97 + 101 + 104 + 96 = 500, and 500 / 5 = 100.0.

  2. Readings 2 to 6: 97 + 101 + 104 + 96 + 99 = 497, so 99.4.

  3. Readings 3 to 7: 101 + 104 + 96 + 99 + 103 = 503, so 100.6.

  4. Readings 4 to 8: 104 + 96 + 99 + 103 + 98 = 500, so 100.0.

  5. Readings 5 to 9: 96 + 99 + 103 + 98 + 100 = 496, so 99.2.

  6. Readings 6 to 10: 99 + 103 + 98 + 100 + 101 = 501, so 100.2.

The smoothed values run from 99.2 to 100.6, a spread of 1.4 cm instead of 8 cm. A trick that makes this cheap to compute: when the window slides by one, the new sum is the old sum plus the newest reading minus the oldest. From step 1 to step 2, 500 + 99 − 102 = 497. Check: that matches.

The lag tradeoff

Smoothing is not free. A moving average of N readings is centered on the middle of its window, so it reports what the world looked like about (N − 1) / 2 samples ago. For N = 5 that is 2 samples.

Say the sensor delivers 20 readings per second, so one sample is 0.05 s. A 2-sample delay is 0.1 s. If the robot is driving at 0.5 m/s, in 0.1 s it travels 0.5 × 0.1 = 0.05 m, which is 5 cm. The filtered distance says the wall is 5 cm farther than it really is. If your stopping rule is tight, that is a crash.

So you pick a window by balancing two things: a bigger N gives a calmer signal, a smaller N gives a faster one. A good rule is to use the smallest window that makes the signal quiet enough for the job. A robot that slowly sorts objects can use a long window. A balancing robot cannot afford much delay at all.

Where it goes wrong

  • Spikes. If one reading is wildly wrong, say 400 cm because the beam hit a shiny edge, a moving average of 5 pulls the output up by 60 cm for five samples. A median filter sorts the window and takes the middle value, so a single spike is simply ignored. Median filters are the standard fix for outliers, and you can chain one in front of an average.

  • Systematic error. Averaging cannot fix a sensor that is consistently 3 cm off. That is bias, not noise, and it needs calibration against a known distance.

  • Start-up. For the first N − 1 readings the window is not full. Decide whether to output nothing, or average what you have.

  • Real change looks like noise. If the true value moves quickly, an average blurs it. You may need a smarter filter that knows how the robot moves, which is where the ideas in SLAM and state estimation come in.

A lighter alternative: exponential smoothing

If you do not want to store N values, use smoothed = α × new + (1 − α) × smoothed, with α between 0 and 1. A small α such as 0.2 smooths heavily and lags more; α near 1 follows the raw data. It needs one variable of memory and one line of code, which is why it is everywhere on small microcontrollers.

How real robots use it

Robot vacuums, drones and arms all filter their sensors before using them. A drone fuses a gyroscope, which is smooth but drifts, with an accelerometer, which is noisy but does not drift. Cameras average several frames in dim light. Motor current and wheel encoders get low-pass filtered before they feed a controller. The details differ, but the logic is the same as your five-reading window: trade a little delay for a lot less jitter. The motor article, how DC motors turn electricity into motion, shows another place where noisy current readings matter.

Try it yourself

Print 50 readings from a distance sensor pointed at a fixed wall. Compute the range of the raw data, then the range after a window of 3, 5 and 10. Plot all four. You should see the range shrink as the window grows, and if you move the wall suddenly, you should see the bigger windows react later. That picture is the whole tradeoff.

Safety: When you test a robot against a wall, lift the drive wheels off the table or keep the speed very low until you trust your filter. A filter with too much lag can let a moving robot drive into a wall, a table edge or your fingers.

Frequently asked questions

How many readings should I average?

Start with 5 and look at the plot. Increase the window until the jitter is small enough for your task, and stop there, because every extra sample adds delay.

Does averaging remove all noise?

No. It reduces random noise, roughly by √N. It does nothing for a constant offset (bias) and it blurs real changes.

Get started

DuckyHelper can
do more

It sees your screen and works in any app you use. Try it for 10 minutes, no card.

Get it for Mac, Windows or Linux

Share

Questions and jobs

Do anything

Ask it a question or hand it a job, in any app.

Doing jobs for you is in early access on Mac. Asking works on Mac, Windows and Linux.