There's no GPS under the field carpet. A robot that wants to know where it is must do what sailors did for centuries: know exactly where it started, then carefully add up every step since. That bookkeeping is odometry — and its arch-enemy is a wheel that lies.
Navigators call this idea dead reckoning: no outside references, just your last known position plus everything you've done since. On a robot, the "everything you've done" comes from wheel encoders and a gyro, and the bookkeeping produces a pose — the robot's full answer to "where am I":
x, y — the robot's position on the field, in meters, in a fixed field frameθ — the robot's heading ("theta"): which way it faces, measured counter-clockwisePosition alone isn't enough — a robot at the right (x, y) facing the wrong way scores exactly zero points. Pose is position plus heading, always.
And here is the whole promise and the whole problem, in one picture. This robot drives a square with its eyes closed — no camera, no beacons — while odometry counts its steps. The wheels lie a little (they always do), and every lie is added into the running total, forever:
Strip it to one wheel. An encoder counts how much the wheel shaft has turned — thousands of ticks per revolution. Multiply by the wheel's circumference and you get distance:
d — how far the wheel has rolled (m)rotations — wheel revolutions counted by the encoder (ticks ÷ ticks-per-revolution, through the gear ratio)π·D — the wheel's circumference: distance covered per revolution, from diameter DSpot the fine print: the encoder measures how much the wheel turned, then this formula assumes the wheel gripped the floor the whole time. Every time it spins without gripping — slip, scrub, getting shoved — the assumption is false and the bookkeeping quietly absorbs a lie.
Distance errors add up politely — centimeter here, centimeter there. Heading errors are different: a heading error rotates every meter you drive afterwards. Get θ wrong by a few degrees and your position error grows with every step, even if the wheels count perfectly:
miss — how far sideways you end up from where you think you are (m)d — distance driven while the heading was wrong (m)φ — the heading error ("phi"), the angle between where you think you're pointed and where you're actually pointedNumbers to feel: 5° of heading error costs 8.7 cm of position error per meter driven. Drive a 10 m auto path with 5° of error and you arrive nearly a meter off. This is why heading gets its own dedicated sensor.
Now assemble the real thing. Fifty times a second, each swerve module reports its distance rolled and its steering angle. From there it's three moves — and the first one you already own: it's the forward kinematics vote from the kinematics lesson, run on distances instead of speeds:
module Δdistances — how far each wheel rolled this tick, from its encoder(Δxr, Δyr) — the chassis's step this tick, in its own robot frame: the wheels' voted answerθ — the heading, taken from the gyro (Part 3 explained why it's never taken from the wheels)(Δx, Δy) — the same step, rotated into the fixed field frame so steps can be added across headingsThat's all odometry is: a tiny step measured in the robot's frame, rotated into the field's frame, added to the running total. Repeat forever.
Drive it. And then do what match play does — get bumped, get pinned against a wall — and watch what each one does to the bookkeeping:
So odometry is a bargain: silky-smooth, 50-times-a-second position — in exchange for error that only ever grows. During autonomous, with no contact, it's superb. In a match, every bump and pin and push moves the truth without moving the books. In WPILib the whole machine is two calls, and note the gyro angle riding along in both:
SwerveDriveOdometry — the bookkeeping object; it needs your kinematics (the vote), the gyro, and where you startedpositions — an array of SwerveModulePosition: each module's total distance rolled (m) and current angleupdate(...) — steps 1-2-3 from Part 4; call it every loop and it returns the current poseresetPosition(...) — the "Reset odometry" button: must be called whenever you reset encoders or the gyro, or learn your true pose from outsideDocs: Swerve Drive Odometry. WPILib's own accuracy note says it plainly: estimates drift over time, "especially as your robot comes into contact with other robots" — you just watched exactly that in Widget 03.
And the ending you can now see coming: a sensor that's smooth-but-drifting, plus an occasional absolute fix from a camera spotting an AprilTag — two imperfect answers begging to be fused. That is precisely the sensor-fusion story of the next lesson, and WPILib ships it ready-made as SwerveDrivePoseEstimator — a drop-in upgrade to the odometry class that accepts vision measurements and weighs them against the wheel data. Odometry counts the steps; fusion keeps the count honest. (For the mathematics under all of it, the Controls Engineering in FRC textbook is the deep end.)
1. Odometry is dead reckoning with receipts. Known start, plus every measured step since, added up 50 times a second into a pose (x, y, θ).
2. Encoders measure the wheel, not the world. The math assumes grip; every slip, scrub, and shove is a lie absorbed silently into the total.
3. Heading is sacred. Angle errors multiply by every meter you drive — 5° costs 8.7 cm per meter — so heading comes from the gyro, never from the wheels.
4. Swerve odometry is three moves. The wheels vote (forward kinematics), the step rotates into the field frame, the total accumulates. You already knew move one.
5. Drift is structural, and the fix comes from outside. Wheel bookkeeping can only accumulate; only an absolute reference — a camera, a known pose — can correct it. Fusing the two is the whole job of the next lesson.
odometry — tracking pose by accumulating measured wheel motionpose — position plus heading: (x, y, θ)dead reckoning — known start + sum of every move since, no outside referencesencoder — counts shaft rotation; distance follows only if the wheel grippedgyro — measures rotation directly; the trusted source for θslip / scrub — wheel motion that isn't robot motion; odometry's poisondrift — accumulated estimate error; grows with distance and contactpose estimator — odometry + absolute fixes, fused Kalman-style