What Is Odometry?

Odometry is the process of estimating a robot's current position by integrating the movement it has measured so far. Think of it like counting your steps: if you know you started at point A and you've taken 50 steps north, you can estimate your current location.

On a VEX robot, the "steps" are measured by wheel encoders (how far each wheel has rotated) and an IMU (which direction the robot is facing). Each time the odometry loop runs (~1 ms), it calculates a tiny change in position (Δx, Δy) and adds it to the accumulated pose.

The Field Coordinate System

+Y (North) ↑ | −X ←───┼───→ +X (East) | ↓ −Y (South) Field walls are ≈70.4 inches from the origin in each direction. The origin (0, 0) is typically the starting position of the robot. Heading 0° = facing +Y (North). Increases clockwise.

LemLib uses inches for distance and degrees for heading. When you call chassis.setPose(0, 0, 0) in initialize(), you tell the robot "I am at the origin, facing North." All subsequent moves are relative to this starting pose.

How Dead-Reckoning Works

At every odometry update, LemLib reads the encoder(s) and IMU and computes:

Δheading = IMU_reading − previous_IMU_reading Δdistance = encoder_distance − previous_encoder_distance local_Δx = Δdistance × sin(heading + Δheading/2) local_Δy = Δdistance × cos(heading + Δheading/2) new_X = old_X + local_Δx new_Y = old_Y + local_Δy

Using the midpoint heading (heading + Δheading/2) reduces the error when the robot is curving. This is the standard arc-integration approach.

Sources of Drift

Dead-reckoning is inherently accumulative: every small error adds to the total error. In a 60-second skills run the robot can drift 1–2 inches even with a good tracking wheel. Sources include:

SourceEffect
Wheel slip (acceleration/braking)Encoder reads more/less than actual distance
Tracking wheel bouncing on seamsRandom noise in encoder readings
IMU drift (vibration, temperature)Heading slowly rotates away from true north
Incorrect wheel diameterSystematic scaling error (every move is X% off)
Incorrect track widthSystematic heading error (every turn is X% off)
⚠️
1–2 inches sounds small, but it matters. A scoring position that is 1.5 inches off can mean the robot misses the goal entirely. Over a 75-point skills run, small drift compounds into missed positions. This is exactly why distance resets exist—see the next chapter.

Sensors LemLib Uses

You configure sensors in lemlib::OdomSensors:

src/robot.cpplemlib::OdomSensors sensors(
    &verticalTracker, // Vertical tracking wheel (most important)
    nullptr,          // 2nd vertical tracker (optional)
    nullptr,          // Horizontal tracking wheel
    nullptr,          // 2nd horizontal tracker
    &inertial          // IMU (primary heading source)
);

Tracking Wheel vs. Drive Encoders

This robot uses a dedicated tracking wheel (a small unpowered wheel with a rotation sensor) rather than reading encoder values from the drive motors. Here is why:

The tracking wheel is mounted close to the center of rotation with 0" lateral offset in this config, minimizing systematic error from turning.

Measuring Your Wheel Diameter

Getting the wheel diameter right is critical. Even a 0.1" error causes every move to be slightly wrong. The best method:

  1. Place the robot at a known starting mark. Reset the encoder to zero.
  2. Push the robot exactly 48 inches (use a measuring tape on the floor).
  3. Read the raw encoder value (in degrees or ticks).
  4. Calculate:
    diameter = (2 × 48 × 360) / encoder_degrees
    (for a rotation sensor that reports in degrees)
  5. Update the value in lemlib::TrackingWheel and re-test.

Calibrating Track Width

Track width affects how accurately the robot turns. If the robot commands a 90° turn but ends up at 92°, your track width is wrong.

  1. Mark the robot's starting heading (use a ruler against the wall for precision).
  2. Command 10 × 360° turns (3600° total). Note the actual final heading with a protractor or IMU.
  3. Scale the track width:
    new_track_width = old_track_width × (3600 / actual_degrees)
Use the LemLib odometry tuning guide. LemLib's documentation has a step-by-step wheel diameter and track-width calibration procedure. Follow it in order—diameter first, then track width—because track width calibration assumes your diameter is already correct.