Blog · 2026-07-05 · Odometry

Wheel Odometry Explained: From Encoder Ticks to Robot Position

Odometry is the art of knowing where your robot is by counting how much its wheels have turned. The math is short, the error sources are sneaky, and the difference between the two is what separates robots that navigate from robots that wander.

Ask a robot "where are you?" and, without cameras, GPS or beacons, it has exactly one honest source of information: its own wheels. Every encoder tick says "I turned this much," and if you know the wheel size, geometry and starting point, you can integrate those ticks into a position estimate. That's odometry — dead reckoning on wheels — and it's the foundation layer under nearly every mobile-robot navigation stack, from line-following toys to warehouse AGVs. Even robots with fancy sensors (lidar, visual SLAM) still run odometry underneath, because it's fast, cheap, always available, and wrong in ways that are at least predictable.

Step one: ticks to millimetres

Everything starts with the conversion constant. One wheel revolution moves the robot one circumference forward, and one wheel revolution corresponds to a known number of encoder counts:

counts per wheel rev = encoder PPR × decoding factor × gear ratio
distance per count = (π × wheel diameter) ÷ counts per wheel rev

Take a common hobby setup: a motor with a 11 PPR magnetic encoder on its shaft, a 30:1 gearbox, 4× quadrature decoding, 65 mm wheels. Counts per wheel revolution = 11 × 4 × 30 = 1,320. Circumference = π × 65 ≈ 204.2 mm. Distance per count ≈ 0.155 mm. Your code accumulates counts; multiplying by 0.155 turns the accumulator into millimetres travelled. (The Wheel Speed & Odometry Calculator does this chain for any combination, and also checks whether the resulting tick rate will drown your microcontroller.)

Three factors in that chain hide the three classic bugs. The decoding factor: a quadrature encoder has two channels 90° apart, and depending on whether your code counts rising edges of one channel (1×), both edges of one channel (2×), or every edge of both channels (4×), the same physical encoder yields one, two or four times the counts. Datasheets quote PPR and CPR interchangeably and inconsistently, so if your robot drives exactly twice or four times too far, this is the culprit — not your wheel measurement. The gear ratio: encoder on the motor shaft means counts get multiplied by the ratio; encoder on the wheel shaft means they don't. The wheel diameter: printed sizes lie. A "65 mm" rubber wheel measures 64 under robot weight and 63.5 after a month of wear. Measure, don't trust.

Step two: two wheels to a pose

A single wheel gives distance; two wheels on a differential drive give distance and heading. Each control cycle, read the left and right distance increments (ΔsL, ΔsR) and update:

Δs = (Δs_R + Δs_L) ÷ 2 (forward motion)
Δθ = (Δs_R − Δs_L) ÷ track width (rotation, radians)
x += Δs × cos(θ + Δθ/2)
y += Δs × sin(θ + Δθ/2)
θ += Δθ

Read the second line twice, because it contains the whole personality of differential-drive odometry: heading comes from the difference between the wheels. Drive straight and the difference is (ideally) zero; spin in place and the wheels move oppositely; arc and one wheel outruns the other in proportion to the curve. The "track width" is the distance between the two wheel contact patches — and note that it appears in a division, which will matter enormously in the error section below.

The θ + Δθ/2 detail (using the midpoint heading for the position update) is the cheap version of proper arc integration, and at typical control rates of 50–100 Hz it's accurate to a rounding error. What kills odometry is never the integration method; it's the inputs.

Where the error actually comes from

Odometry error divides into two families with very different behaviour. Systematic errors are repeatable: wrong wheel diameter, unequal left/right diameters, wrong track width. They produce the same drift every run — a robot that always curves gently left, or always comes up 3% short. Systematic error is good news, because anything repeatable is calibratable. Non-systematic errors are the random ones: wheel slip during acceleration, skidding in turns, carpet fibres, bumps, dust. They accumulate as a random walk and no constant can remove them; they can only be minimized by mechanical design and driving style, then corrected by external sensing.

Error sourceTypeSymptomFix
Wheel diameter wrongSystematicDistances scaled by a constantCalibrate on a measured run
Left/right diameters unequalSystematicCurves when commanded straightPer-wheel scale factors
Track width wrongSystematicTurns over/under-rotateCalibrate with spin test
Wheel slipRandomPosition jumps, worst on launchGentler acceleration ramps
Skid in turnsRandomHeading drift after fast turnsSlower turns, better tyres
Tyre squish under loadSystematic-ishDistance changes with payloadHarder wheels, recalibrate loaded

Heading error deserves special fear. A distance error of 1% after 10 m is 10 cm — annoying. A heading error of 1° sustained over 10 m throws the position off by 17 cm, and it compounds: every metre driven with a wrong heading converts heading error into position error at full exchange rate. This is why serious builds add a gyro (any IMU's yaw rate, integrated) and fuse it with wheel heading — gyros drift slowly with time, wheels drift with distance and slip, and blending the two covers each one's weakness.

Calibration: the honest ritual

Every competitive team performs some version of this, because it converts systematic error into a constant. Distance: command the robot 2,000 mm along a tape measure on the real competition surface; if it travels 1,940, multiply your mm-per-count constant by 2000/1940 and repeat until it lands within a few millimetres. Straightness: drive the same run and measure sideways deviation; a consistent curve means unequal effective wheel diameters — introduce per-side scale factors (typically within ±1% of each other) until it tracks true. Track width: command ten full in-place rotations and measure the actual heading error with a mark on the floor; adjust the track-width constant until ten commanded rotations produce ten real ones. The effective track width usually comes out slightly larger than the measured one, because tyre contact patches scrub outward during turns.

Calibrate on the real floor. Effective wheel diameter changes measurably between hard flooring, foam tiles and carpet — the tyre sinks in and the contact geometry shifts. A robot calibrated on a workbench and deployed on competition foam starts life with a built-in half-percent error it didn't need to have.

Resolution: how many ticks are enough?

More counts per revolution is better, but with steeply diminishing returns. For dead reckoning, once distance-per-count is below about 0.5 mm the encoder is no longer your accuracy limit — slip and diameter uncertainty dominate. Velocity control has a stricter requirement: a PID loop running at 100 Hz needs enough counts per loop period to compute a meaningful speed. At 0.2 m/s with 0.155 mm/count you get ~129 counts per 10 ms period — lovely. With a coarse 20-counts-per-wheel-rev encoder the same speed yields 0.2 counts per period, and your "measured speed" becomes a jittery guess that makes derivative terms useless (a problem you can visualize by feeding noisy feedback intuition into the PID Tuning Visualizer). If your resolution is fixed and low, measure speed over longer windows or use the encoder-period method (time between ticks) instead of counting ticks per period.

Beyond two wheels

The same machinery generalizes. Four-wheel skid-steer uses the identical differential equations with averaged left and right sides — but skid-steering, by definition, drags wheels sideways in every turn, so its heading estimate is poor and a gyro is effectively mandatory. Mecanum and omni drives extend the math to three degrees of freedom (x, y, θ simultaneously) with a matrix mapping four wheel speeds to body motion; slip is higher still, and many omni builds add dedicated unpowered tracking wheels — free-spinning encoder wheels that touch the ground only to measure, immune to drive-wheel slip. Tracking wheels are the single biggest odometry upgrade available to a competition robot, and they're just this article's math applied to wheels that never receive torque.

Quick answers

How accurate can wheel odometry get?

A well-calibrated differential drive on clean flooring holds roughly 0.5–1% of distance travelled and a few degrees of heading over a short run. With a fused gyro and tracking wheels, competition robots hold a few millimetres over a match. Unaided over long distances, everything drifts — that's not failure, it's the definition of dead reckoning.

Do I need interrupts to count encoder ticks?

At low rates, pin-change interrupts are fine. Past tens of kilohertz of edges, use a microcontroller with hardware quadrature counters (ESP32, RP2040 PIO, STM32 timers) — the counting then costs zero CPU and never misses an edge.

Encoder odometry vs IMU-only?

An IMU alone must double-integrate acceleration to get position, and accelerometer noise makes that estimate diverge within seconds. Wheels give you distance directly. The classic fusion — wheel distance plus gyro heading — beats either alone by a wide margin.

The conversion chain, the pose update, the calibration ritual: that's the whole discipline. Get your constants from the Wheel Speed & Odometry Calculator, and if you're now curious what's actually generating those ticks, the companion piece Rotary Encoders Explained opens the little black disc up.