LogoLogo
  • Introduction
  • Getting Started with Control Hub
    • Connect to the Robot Controller Console
    • Updating Wi-Fi Settings
    • Connecting Driver Station to Control Hub
    • Wiring Diagram
    • Next Steps
  • Getting Started with Driver Hub
  • Adding More Motors
    • SPARKmini Motor Controller
    • Adding an Expansion Hub
  • Troubleshooting the Control System
    • General Troubleshooting
    • Control Hub Troubleshooting
    • Driver Hub Troubleshooting
      • Driver Hub Battery Troubleshooting
    • Expansion Hub Troubleshooting
    • Status LED Blink Codes
  • System Overview
    • Control Hub Specifications
    • Expansion Hub Specifications
    • Driver Hub Specifications
    • Port Pinouts
    • Protection Features
    • Cables and Connectors
      • XT-30 - Power Cable
      • JST VH - Motor Power
      • JST PH - Sensors and RS485
    • Integrated Sensors
    • Dimensions and Important Component Locations
  • Updating and Managing
    • Managing Wi-Fi on the Control Hub
    • REV Hardware Client
    • Updating Firmware
      • Firmware Changelog
    • Updating Operating System
      • Control Hub Operating System Changelog
    • Updating Robot Controller Application
      • Updating Robot Controller Application via Android Studio
    • Updating the Driver Hub
      • Driver Hub OS - Change Log
    • Accessing Log Files
    • Android Studio - Deploying Code Wirelessly
  • Hello Robot - Intro to Blocks Programming
    • Welcome to Hello Robot!
    • Where to Program - Client vs. Browser
      • What is an OpMode?
    • Setting up a Configuration
      • Common Errors in Configuration
    • Using a Gamepad
    • Part 1: Tackling the Basics
      • Tackling the Basics Directory - Blocks
      • Creating an OpMode - Blocks
      • Programming Essentials
      • Programming Servos
        • Programming Servo Basics
        • Using a Gamepad with a Servo
        • Programming Servo Telemetry
      • Programming Motors
        • Programming Motors Basics
        • Programming a Motor with a Gamepad
        • Programming Motor Telemetry
      • Programming Touch Sensors
      • Programming Color Sensors
        • Color Sensor Telemetry
        • Detecting Color
    • Part 2: Robot Control
      • Robot Control Blocks Directory
      • Programming Drivetrain Motors
      • Arcade Style TeleOp - Blocks
        • Establishing Variables in Blocks
        • Motor Power vs. Robot Movement
        • Programming Arcade Drive
      • Arm Control - Blocks
        • Adding a Limit Switch
      • Robot Control Full Program
    • Part 3: Autonomous and Encoders
      • ElapsedTime - Blocks
        • ElapsedTime Setup
        • ElapsedTime Logic
        • ElapsedTime - Multiple Movements
      • Encoder Basics
      • Drivetrain Encoders - Blocks
        • Converting Encoder Ticks to a Distance
        • Moving to a Target Distance
        • Setting Velocity
        • Turning the Drivetrain Using RUN_TO_POSITION
      • Arm Control with Encoders - Blocks
        • Estimating the Position of the Arm
        • Calculating Target Position
        • Using Limits to Control Range of Motion
    • Part 4: Going Beyond!
      • Exploring Functions
      • Programming Mecanum - Simplified
      • Programming Mecanum - Refined
  • Hello Robot - Intro to OnBot Java Programming
    • Welcome to Hello Robot!
    • Where to Program - Client vs. Browser
      • What is an OpMode?
    • Setting up a Configuration
      • Common Errors in Configuration
    • Using a Gamepad
    • Part 1: Tackling the Basics
      • Tackling the Basics Directory - OnBot
      • Creating an OpMode - OnBot
      • Programming Essentials
      • Programming Servos
        • Programming Servo Basics
        • Using a Gamepad with a Servo
        • Programming Servo Telemetry
      • Programming Motors
        • Programming Motor Basics
        • Programming a Motor with a Gamepad
        • Programming Motor Telemetry
      • Programming Touch Sensors
    • Part 2: Robot Control
      • Robot Control OnBot Java Directory
      • Programming Drivetrain Motors
      • Arcade Style TeleOp - OnBot Java
        • Establishing Variables in OnBot Java
        • Motor Power vs. Robot Movement
        • Programming Arcade Drive
      • Arm Control - OnBot Java
        • Adding a Limit Switch
      • Robot Control Full Program
    • Part 3: Autonomous and Encoders
      • ElapsedTime - OnBot Java
        • ElapsedTime Setup
        • ElapsedTime Logic
        • ElapsedTime - Multiple Movements
      • Encoder Basics
      • Drivetrain Encoders - OnBot Java
        • Converting Encoder Ticks to a Distance
        • Moving to a Target Distance
        • Setting Velocity
        • Turning the Drivetrain Using RUN_TO_POSITION
      • Arm Control with Encoders - OnBot Java
        • Estimating the Position of the Arm
        • Calculating Target Position
        • Using Limits to Control Range of Motion
  • Sensors
    • Introduction to Sensors
    • Digital
    • Analog
    • I2C
      • IMU
        • Orientating the IMU
      • Adding an External IMU to your Hub
    • Encoders
      • REV Motor Encoders
      • Through Bore Encoder
    • Using 3rd Party Sensors
      • Sensor Compatibility Chart
  • Useful Links
    • REV DUO Build System
  • Legacy Documentation
    • Configuring Your Android Devices
    • Expansion Hub with Android Device Robot Controller
      • Driver Station and Robot Controller Pairing
      • Wiring Diagram
      • Configuration
    • REV Hub Interface Software
Powered by GitBook
On this page
  • What's Needed for the Conversion
  • Ticks per Revolution
  • Total Gear Reduction
  • Circumference of the Wheel
  • Translating the Conversion to Code
  • Setting up Variables
  • Calculating COUNTS_PER_WHEEL_REV
  • Calculating COUNTS_PER_MM

Was this helpful?

Export as PDF
  1. Hello Robot - Intro to OnBot Java Programming
  2. Part 3: Autonomous and Encoders
  3. Drivetrain Encoders - OnBot Java

Converting Encoder Ticks to a Distance

PreviousDrivetrain Encoders - OnBot JavaNextMoving to a Target Distance

Last updated 5 months ago

Was this helpful?

In the previous section, the basic structure needed to use RUN_TO_POSITIONwas created. The placement of leftmotor.setTargetPosition(1000); and rightmotor.setTargetPosition(1000); within the code, set the target position to 1000 ticks.

But how far is a tick and how can we use them to help our robot navigate an area? We could attempt to estimate the distance the robot moves per tick or we can convert the amount of ticks per revolution of the encoder into a unit like millimeters or inches! For instance, if you work through the conversion process and find out that a drivetrain takes 700 ticks to move an inch, this can be used to find the total number of ticks need to move the robot 24 inches.

Reminder that the basis for this guide is the . The REV DUO Build System is a metric system. Since part of the conversion process references the diameter of the wheels, this section will convert to ticks per mm.

What's Needed for the Conversion

This process will take a bit of math to achieve so let's break it down.

When using encoders built into motors, converting from ticks per revolution to ticks per unit of measure moved requires the following information:

Ticks per Revolution

The amount of ticks per revolution of the encoder shaft is dependent on the motor and encoder. Manufacturers of motors with built-in encoders will have information on the amount of ticks per revolution.

For HD Hex Motors the encoder counts 28 ticks per revolution of the motor shaft.

Visit the manufacturers website for your motor or encoders for more information on encoder counts. For HD Hex Motors or Core Hex Motors visit our documentation.

Total Gear Reduction

For the Class Bot V2 there are two UltraPlanetary Cartridges, 4:1 and 5:1, and an additional gear reduction from the UltraPlanetary Output to the wheels, 72T:45T ratio.

Using the compound gearing formula for the Class Bot V2 the total gear reduction is:

3.611∗5.231∗7245=30.21\frac{3.61}{1} * \frac{5.23}{1} * \frac{72}{45} = 30.2113.61​∗15.23​∗4572​=30.21

Unlike the the spur gears used to transfer motion to the wheels, the UltraPlanetary Gearbox Cartridges are planetary gear systems. To make calculations easier the gear ratios for the Cartridges are already reduced.

Circumference of the Wheel

The Class Bot V2 uses the 90mm Traction Wheels. 90mm is the diameter of the wheel. To get the appropriate circumference use the following formula

circumference=diameter∗πcircumference = diameter * \pi circumference=diameter∗π

You can calculate this by hand, but for the purpose of this guide, this can be calculated within the code.

Due to wear and manufacturing tolerances, the diameter of some wheels may be nominally different. For the most accurate results consider measuring your wheel to confirm that the diameter is accurate.

To summarize, for the Class Bot V2 the following information is true:

Ticks per revolution

28 ticks

Total gear reduction

30.21

Circumference of the wheel

Translating the Conversion to Code

Setting up Variables

Each of these pieces of information will be used to find the number of encoder ticks (or counts) per mm that the wheel moves. Rather than worry about calculating this information by hand, these values can be added to the code as constant variables. To do this create three variables:

  • COUNTS_PER_MOTOR_REV

  • DRIVE_GEAR_REDUCTION

  • WHEEL_CIRCUMFERENCE_MM

The common naming convention for constant variables is known as CONSTANT_CASE, where the variable name is in all caps and words are separated by and underscore.

To ensure variables are referenceable they are set as static final double variables. Static allows references to the variables anywhere within the class. Final dictates that these variables are constant and unchanged elsewhere within the code.

Since these variables are not integers they are classified as double variables.

public class HelloRobot_EncoderAuton extends LinearOpMode {
    private DcMotor leftmotor;
    private DcMotor rightmotor;
    
    static final double     COUNTS_PER_MOTOR_REV    = 28.0; 
    static final double     DRIVE_GEAR_REDUCTION    = 30.21;   
    static final double     WHEEL_CIRCUMFERENCE_MM  = 90.0 * Math.PI;

Now that these three variables have been defined, we can use them to calculate two other variables: the amount of encoder counts per rotation of the wheel and the number of counts per mm that the wheel moves.

public class HelloRobot_EncoderAuton extends LinearOpMode {
    private DcMotor leftmotor;
    private DcMotor rightmotor;
    
    static final double     COUNTS_PER_MOTOR_REV    = 28.0; 
    static final double     DRIVE_GEAR_REDUCTION    = 30.24;   
    static final double     WHEEL_CIRCUMFERENCE_MM  = 90.0 * 3.14;
    
    static final double     COUNTS_PER_WHEEL_REV    =
    static final double     COUNTS_PER_MM =

Calculating COUNTS_PER_WHEEL_REV

To calculate counts per wheel revolution multiple COUNTS_PER_MOTOR_REV by DRIVE_GEAR_REDUCTION Use the following formula:

y=a∗by = a *by=a∗b

Where:

  • aa a = COUNTS_PER_MOTOR_REV

  • bbb = DRIVE_GEAR_REDUCTION

  • yyy = COUNTS_PER_WHEEL_REV

public class HelloRobot_EncoderAuton extends LinearOpMode {
    private DcMotor leftmotor;
    private DcMotor rightmotor;
    
    static final double     COUNTS_PER_MOTOR_REV    = 28.0; 
    static final double     DRIVE_GEAR_REDUCTION    = 30.24;   
    static final double     WHEEL_CIRCUMFERENCE_MM  = 90.0 * 3.14;
    
    static final double     COUNTS_PER_WHEEL_REV    = COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION
    static final double     COUNTS_PER_MM = 

Calculating COUNTS_PER_MM

Once COUNTS_PER_WHEEL_REV is calculated, use it to calculate the counts per mm that the wheel moves. To do this divide the COUNTS_PER_WHEEL_REV by the WHEEL_CIRCUMFERENCE_MM. Use the following formula.

x=(a∗b)c=ycx = \frac{(a*b)}{c} = \frac{y}{c}x=c(a∗b)​=cy​

Where,

  • aa a = COUNTS_PER_MOTOR_REV

  • bbb = DRIVE_GEAR_REDUCTION

  • ccc = WHEEL_CIRCUMFERENCE_MM

  • yyy = COUNTS_PER_WHEEL_REV

  • xxx = COUNTS_PER_MM

public class HelloRobot_EncoderAuton extends LinearOpMode {
    private DcMotor leftmotor;
    private DcMotor rightmotor;
    
    static final double     COUNTS_PER_MOTOR_REV    = 28.0; 
    static final double     DRIVE_GEAR_REDUCTION    = 30.24;   
    static final double     WHEEL_CIRCUMFERENCE_MM  = 90.0 * 3.14;
    
    static final double     COUNTS_PER_WHEEL_REV    = COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION;
    static final double     COUNTS_PER_MM           = COUNTS_PER_WHEEL_REV / WHEEL_CIRCUMFERENCE_MM;

COUNTS_PER_WHEEL_REVwill be created as a separate variable fromCOUNTS_PER_MM as it is used in calculating a target velocity.

Program thus far:

package org.firstinspires.ftc.teamcode;

import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.DcMotorSimple;

@Autonomous //sets the op mode as an autonomous op mode 

public class HelloWorld_Encoder extends LinearOpMode {
    private DcMotor leftmotor;
    private DcMotor rightmotor;
    
    static final double     COUNTS_PER_MOTOR_REV    = 28.0; 
    static final double     DRIVE_GEAR_REDUCTION    = 30.24;   
    static final double     WHEEL_CIRCUMFERENCE_MM  = 90.0 * 3.14;
    
    static final double     COUNTS_PER_WHEEL_REV    = COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION;
    static final double     COUNTS_PER_MM           = COUNTS_PER_WHEEL_REV / WHEEL_CIRCUMFERENCE_MM;
   
     @Override
    public void runOpMode() {
        leftmotor = hardwareMap.get(DcMotor.class, "leftmotor");
        rightmotor = hardwareMap.get(DcMotor.class, "rightmotor");
        
        rightmotor.setDirection(DcMotor.Direction.REVERSE);
        
        leftmotor.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
        rightmotor.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
        
        // Wait for the game to start (driver presses PLAY)
        waitForStart();
        
        leftmotor.setTargetPosition(1000);
        rightmotor.setTargetPosition(1000);
        
        leftmotor.setMode(DcMotor.RunMode.RUN_TO_POSITION);
        rightmotor.setMode(DcMotor.RunMode.RUN_TO_POSITION);
        
        leftmotor.setPower(0.8);
        rightmotor.setPower(0.8);

        // run until the end of the match (driver presses STOP)
        while (opModeIsActive() && (leftmotor.isBusy() && rightmotor.isBusy())) {

}
    }
}

Since ticks per revolution of the encoder shaft is before any gear reduction calculating the total gear reduction is needed. This includes the gearbox and any addition reduction from motion transmission components. To find the total gear reduction use the .

The UltraPlanetary Cartridges use the nominal gear ratio as a descriptor. The actual gear ratios can be found in the .

We'll add the to the initialization section of the OpMode:

90mm∗π90mm * \pi90mm∗π
Class Bot V2
Motor
Compound Gearing formula
UltraPlanetary Users Manual's Cartridge Details
variables