Skip to content
Week 5 · Lesson 2 50 min

Driving Precise Distances with Encoders

Turn inches into encoder ticks with a worked example, learn the encoder run modes, and write a `driveInches()` helper that uses `RUN_TO_POSITION`.

In this lesson you will

  • Explain what an encoder tick is and where to find ticks per revolution for a motor
  • Calculate ticks per inch from ticks per revolution and wheel diameter
  • Choose the correct run mode: STOP_AND_RESET_ENCODER, RUN_USING_ENCODER or RUN_TO_POSITION
  • Write a driveInches() helper with a timeout and calibrate it with a tape measure

Lesson

An encoder is a sensor built into most FTC motors that counts how far the motor shaft has turned. It reports this as a number of ticks. If the count goes from 0 to 1000, the shaft turned a known amount, so the wheel moved a known distance. That is how a robot can measure distance instead of guessing from time.

Every motor has a fixed number of ticks per revolution of its output shaft. It depends on the motor and its gearbox, so look it up on the manufacturer's spec sheet. For example, one common goBILDA 312 RPM motor lists about 537.7 ticks per output revolution. Your motor may be different.

From ticks to inches

dWheelCircumferenceC = π × dTicks per revolutionTPR × gearTicks per inchTPI = (TPR × gear) / (π × d)Example only — use your motor's datasheet
One wheel revolution moves the robot one wheel circumference, and that revolution equals a known number of ticks.

When a wheel makes one full revolution, the robot rolls forward by the wheel's circumference, which is pi times the diameter. Divide ticks per revolution by the circumference and you get ticks per inch. Here is a worked example with example numbers:

  1. 1
    Ticks per revolution
    From the spec sheet: 537.7 ticks per output revolution (example motor).
  2. 2
    Wheel diameter
    A 96 mm wheel. Convert to inches: 96 / 25.4 = 3.78 inches.
  3. 3
    Circumference
    pi x 3.78 = about 11.87 inches travelled per wheel revolution.
  4. 4
    Ticks per inch
    537.7 / 11.87 = about 45.3 ticks per inch.
  5. 5
    Target for 24 inches
    24 x 45.3 = about 1087 ticks. One field tile is 24 inches, so this drives one tile.

Encoder run modes

Run modeWhat it doesWhen to use it
STOP_AND_RESET_ENCODERStops the motor and sets the tick count to 0At the start of each move, so you measure from zero
RUN_USING_ENCODERUses the encoder to hold a steady speed for the power you giveNormal driving and IMU turns
RUN_WITHOUT_ENCODERSends power directly, no speed control (the count can still be read)Simple mechanisms, or when you do your own control
RUN_TO_POSITIONDrives the motor to a target tick count and holds it thereDriving set distances, moving arms or lifts to positions

Order matters with RUN_TO_POSITION. First reset the encoder, then call setTargetPosition(), then switch to RUN_TO_POSITION, and only then set the power. If you switch to RUN_TO_POSITION before setting a target, the SDK reports an error. The power you set acts as the maximum speed on the way to the target.

JAVA
1static final double TICKS_PER_INCH = 45.3; // replace with your calibrated value
2
3private void driveInches(double inches, double power, double timeoutS) {
4    int target = (int) Math.round(inches * TICKS_PER_INCH);
5
6    leftDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
7    rightDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
8    leftDrive.setTargetPosition(target);
9    rightDrive.setTargetPosition(target);
10    leftDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
11    rightDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
12
13    ElapsedTime timer = new ElapsedTime();
14    leftDrive.setPower(Math.abs(power));
15    rightDrive.setPower(Math.abs(power));
16
17    while (opModeIsActive() && timer.seconds() < timeoutS
18            && leftDrive.isBusy() && rightDrive.isBusy()) {
19        telemetry.addData("Target", target);
20        telemetry.addData("Left / Right", "%d / %d",
21                leftDrive.getCurrentPosition(), rightDrive.getCurrentPosition());
22        telemetry.update();
23    }
24
25    leftDrive.setPower(0);
26    rightDrive.setPower(0);
27    leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
28    rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
29}
A drive helper for a two-motor drivetrain. The same idea works for four motors.

isBusy() returns true while a motor is still moving toward its target. The loop stops as soon as either motor finishes, the timeout runs out, or the OpMode is stopped. The timeout is your safety net: if an encoder cable is unplugged, the count never changes and the robot would otherwise drive forever. For a negative distance, the target becomes negative and the robot drives backward.

Calibrate with a tape measure

The calculated value is a starting point. Real wheels compress slightly and roll a little differently from the spec. To calibrate, drive 48 inches with your helper, measure the real distance and correct the value: new ticks per inch = ticks driven / inches actually travelled. Repeat until the robot lands within about half an inch, and write the final number in your engineering notebook.

Key terms

Encoder
A sensor on a motor that counts how far the shaft has rotated.
Tick
One unit of encoder count; a fixed number of ticks makes one full revolution.
Ticks per inch
How many encoder ticks the drive motors count while the robot moves one inch.
`RUN_TO_POSITION`
A motor run mode that drives the motor to a target tick count and holds it there.
`isBusy()`
A motor method that returns true while the motor is still moving toward its target position.
Timeout
A time limit that ends a move even if the target was not reached, so the robot never gets stuck.

Practical exercise

Calculate and calibrate ticks per inch

  1. 1Find the ticks per revolution for your drive motors on the spec sheet and measure your wheel diameter.
  2. 2Calculate ticks per inch on paper, showing every step like the worked example.
  3. 3Add the driveInches() helper to an autonomous OpMode and drive 48 inches at power 0.4.
  4. 4Measure the real distance with a tape measure, correct TICKS_PER_INCH, and repeat until the error is under half an inch.
  5. 5Test a backward move of 24 inches to confirm negative distances work.
Deliverable: Your written calculation, a table of calibration runs (target, measured, corrected value), and the final TICKS_PER_INCH in your code.

Knowledge check

Answer every question, then check your answers.

  1. Q1A motor has 560 ticks per revolution and the wheel circumference is 14 inches. About how many ticks per inch is that?
  2. Q2Which run mode sets the encoder count back to 0?
  3. Q3What must you do before switching a motor to RUN_TO_POSITION?
  4. Q4Why does driveInches() include a timeout?

Further resources

Mark lesson complete