Trailblazer Robotics
Unit 3 · Week 6

Encoders & Dead Reckoning

Why "drive for 1 second" is the wrong way, and what to do instead.

You'll learn

What's an encoder?

From the VEX Library: every VEX IQ Smart Motor has a quadrature encoder inside that reports the direction, position, and speed of the motor shaft. This is the same data the built-in spinFor and driveFor commands use behind the scenes.

double turns = LeftMotor.position(turns);     // 1.5 = one and a half full rotations
double deg   = LeftMotor.position(degrees);   // 540 for 1.5 turns
double rpm   = LeftMotor.velocity(rpm);       // current speed

Why time-based driving fails

If your code says "drive forward for 2 seconds at 50%", how far does the robot actually go?

So your autonomous routine works perfectly in practice and then fails at the competition because the battery is at 70% instead of 100%. That's why we use encoders.

Inches to motor degrees

The robot needs to know how many motor degrees correspond to one inch. Formula:

// Wheel circumference = pi * diameter
// For a 200 mm (about 7.87 in) wheel: circumference ≈ 24.75 inches per full motor turn
// degrees per inch = 360 / circumference_in_inches

const double WHEEL_DIAMETER_IN = 7.87;
const double WHEEL_CIRC_IN     = 3.14159 * WHEEL_DIAMETER_IN;
const double DEG_PER_INCH      = 360.0 / WHEEL_CIRC_IN;

void driveInches(double inches, int speedPct) {
  double targetDeg = inches * DEG_PER_INCH;
  LeftMotor.spinFor(forward,  targetDeg, deg, false);
  RightMotor.spinFor(forward, targetDeg, deg, true);
}

int main() {
  driveInches(24, 50);   // drive 24 inches at 50% speed
}
Reality check: even with encoders, the robot won't go exactly 24 inches, wheel slip and weight shifts mess things up. Distance-based is much better than time-based, but still not perfect. Next week we'll fix the precision problem with proportional control.

What "dead reckoning" actually means

Dead reckoning = estimating your current position using only how far you've moved, with no outside reference. Sailors used it before GPS. VEX teams use it for simple autonomous routines: drive 24 inches, turn 90, drive 12 inches. It accumulates error every turn, by the end of a long routine, the robot can be way off.

Try it

Find the diameter of your wheels (look it up by part number, common IQ wheels are 200 mm and 100 mm). Write a driveInches() function and test it. Measure the actual distance with a tape measure across 5 runs. How much variation is there?

Curated references

Coding Challenge

Drive an exact 36-inch line

Write a function that drives the robot forward exactly 36 inches, measured by encoder, with no overshoot, even with a low battery.

No solution is given for this challenge. Compare results with a teammate to learn.

Find the Bug

Two programs with intentional errors. Spot the bug.

Problem 6A
This function is supposed to drive 24 inches. Instead the robot crawls forward less than 1 inch and stops. What's wrong?
const double WHEEL_DIAM_IN = 7.87;
const double WHEEL_CIRC_IN = 3.14159 * WHEEL_DIAM_IN;
const double DEG_PER_INCH  = WHEEL_CIRC_IN / 360.0;

void driveInches(double inches) {
  double targetDeg = inches * DEG_PER_INCH;
  LeftMotor.spinFor(forward,  targetDeg, deg, false);
  RightMotor.spinFor(forward, targetDeg, deg, true);
}

int main() {
  driveInches(24);
}
Problem 6B
This program calls driveInches twice in a row. The first call works. The second call doesn't move the robot at all. What's missing?
void driveInches(double inches) {
  double targetDeg = inches * DEG_PER_INCH;
  while (LeftMotor.position(degrees) < targetDeg) {
    LeftMotor.spin(forward, 50, percent);
    RightMotor.spin(forward, 50, percent);
    wait(20, msec);
  }
  LeftMotor.stop();
  RightMotor.stop();
}

int main() {
  driveInches(12);
  driveInches(12);
}
← Week 5 Next: Proportional Control →