🧭 A Design Decision

How We Track Position

A worked example of building your own drive library: the reasoning behind how SpartanDrive knows where the robot is on the field — one tracking pod and the IMU, and why that was the right call for a tank drive.

On Build Your Own Drive Library we made the engineering case for writing your own drivetrain wrapper. This page is that philosophy applied to one real subsystem — the thinking behind how our library tracks the robot's position. The idea and the trade-offs are here for any team; the code that implements them stays ours to write, and yours.

What this page is — and isn't

The odometry idea below — and why we chose what we chose — is openly shared. It's universal math any team can use. The SpartanDrive source and API that implement it stay with the team, same as everywhere on this site. The idea is the gift; the implementation is the work.

The problem a position tracker solves

"Drive 24 inches" and "turn to 90°" get the robot somewhere — but neither one knows where "there" actually is on the field. Chain a few together and small errors compound with nothing to check them against. Odometry fixes that: it keeps a live estimate of the robot's position — its x, y, and heading — updated continuously as the robot moves.

With a live position, an autonomous routine can correct itself against a known wall, branch on where it actually ended up instead of where it hoped to be, and be debugged by simply printing where the robot thinks it is. It's the difference between a routine that drives blind and one that knows where it stands.

The idea: split every step onto the field

The whole method is one small move, repeated about a hundred times a second: see how far the robot has rolled since the last check — a tiny forward step — and split that step onto the field's two axes using the direction the robot is currently facing.

The split is just trigonometry. Measure heading from the up-field direction, and each small step of length step adds:

x += step × sin(heading)   ·   y += step × cos(heading)

Facing straight up-field, all of a step lands in y. Facing sideways, all of it lands in x. In between, it splits. Because each tiny step uses the heading at that instant, the position stays correct even while the robot is turning.

Heading 0° · up-field

A 2″ step adds y +2.0, x +0.0. All of it forward.

Heading 45° · diagonal

A 2″ step adds x +1.41, y +1.41. Split evenly.

Heading 90° · sideways

A 2″ step adds x +2.0, y +0.0. All of it across.

The sum is the position

Add up a hundred of these little steps a second and you have an accurate running (x, y) — through straights and turns alike.

The decision: one pod and the IMU

Most "full" odometry setups use two tracking wheels — one to read forward motion, one to read sideways. We use one, plus the inertial sensor for heading. That was a deliberate choice, and being able to explain it is half the reason we build our own.

One pod, not two

A tank drive can't strafe — it only moves along the direction it's facing. There's no pure-sideways motion for a second pod to measure, so one forward pod plus heading already captures everything our robot actually does.

A pod, not motor encoders

The tracking pod is an unpowered wheel — it only turns when the robot truly moves, so it can't be fooled by wheel slip. Drive-motor encoders over-count the instant the wheels spin without gripping the tile.

Heading from the IMU

We don't try to compute which way we're facing from wheel motion — the inertial sensor is built for exactly that and is far steadier. Odometry just reads it and trusts it.

Built for the drivetrain we have

If a future robot could strafe, the honest move is to add a sideways pod then — not to carry hardware and math today for motion our robot never makes.

The honest trade-off: one forward pod can't see a pure-sideways slide. On a tank drive that almost never matters — it doesn't slide sideways under power — so we give up nothing we actually use. A robot that strafes would genuinely need that second pod. And odometry of any kind needs the tracking pod plus a little math; a brand-new team is often better served by accurate drive-and-turn alone, adding position tracking once a real routine needs it.

Why a decision like this is worth making yourself

When a judge asks "how does your robot know where it is on the field?", a student who reasoned through this can answer in one breath: the pod measures how far we roll, the IMU gives heading, and every loop adds that little step onto x and y. That clarity isn't something you can borrow from a black-box library — it comes from having made the call.

It's the same principle as the rest of our code, the one the design principles on the main page describe: build exactly what the robot needs, name it for the people using it, and understand every piece. Odometry is just one place that principle shows up.

EN4 reminder

The math and the reasoning here are yours to learn from. But if you build position tracking into your own robot, the code has to be code you wrote and understand — that's exactly what the notebook and the judges reward. Take the idea; write the implementation yourself.

This is one decision out of a larger philosophy. Start with Build Your Own Drive Library for the case for writing your own, or the code organization guide for structuring a project cleanly.