Gamepad Tank Drive

You know how to spin a motor at a fixed power. But in a real TeleOp match, the driver needs to control the robot in real time using a gamepad. In this lesson, you will implement tank drive -- one of the most common drivetrain control schemes in FTC.

The Gamepad Object

The FTC SDK gives you access to two gamepad objects: gamepad1 and gamepad2. These are automatically updated with the latest input from the Driver Station controllers.

Here are some of the most commonly used gamepad fields:

FieldTypeDescription
left_stick_xfloatLeft stick horizontal (-1.0 left to 1.0 right)
left_stick_yfloatLeft stick vertical (-1.0 up to 1.0 down)
right_stick_xfloatRight stick horizontal
right_stick_yfloatRight stick vertical
a, b, x, ybooleanFace buttons
left_trigger, right_triggerfloatTriggers (0.0 to 1.0)
left_bumper, right_bumperbooleanBumpers
You access them directly as fields -- no method calls needed:
double leftY = gamepad1.left_stick_y;
boolean aButton = gamepad1.a;

What is Tank Drive?

Tank drive is a control scheme where:

  • The left joystick controls the left side motors.
  • The right joystick controls the right side motors.
Push both sticks forward and the robot drives straight. Push them in opposite directions and the robot spins in place. Push one forward and leave the other centered and the robot turns in an arc.

It is called "tank drive" because it works exactly like the two-lever controls on a tank or bulldozer.

The Y-Axis Inversion Gotcha

Here is something that trips up almost every new FTC programmer:

On a gamepad, pushing the joystick forward gives a negative Y value.

This is a standard convention in game controllers (inherited from flight simulators where pushing forward means "nose down"), but it is the opposite of what you would expect. If the driver pushes the left stick forward, gamepad1.left_stick_y will be something like -0.8, not +0.8.

Since we want "forward on the stick" to mean "forward on the motor" (positive power), we need to negate the Y value:

double leftPower = -gamepad1.left_stick_y;   // Negate to fix direction
double rightPower = -gamepad1.right_stick_y;  // Negate to fix direction

This is one of the most common bugs in FTC code. If your robot drives backwards when you push forward, you probably forgot the negation!

Putting It Together

Here is what a complete tank drive looks like:

@TeleOp(name = "Tank Drive")
public class TankDrive extends LinearOpMode {
    @Override
    public void runOpMode() {
        DcMotor leftMotor = hardwareMap.get(DcMotor.class, "leftMotor");
        DcMotor rightMotor = hardwareMap.get(DcMotor.class, "rightMotor");

waitForStart();

while (opModeIsActive()) {
double leftPower = -gamepad1.left_stick_y;
double rightPower = -gamepad1.right_stick_y;

leftMotor.setPower(leftPower);
rightMotor.setPower(rightPower);

telemetry.addData("Left Power", leftPower);
telemetry.addData("Right Power", rightPower);
telemetry.update();
}
}
}

Notice the while (opModeIsActive()) loop. In a real TeleOp, you need to continuously read the gamepad and update the motors. The opModeIsActive() method returns true as long as the OpMode has not been stopped.

Your Exercise

For this exercise, you will implement the core of tank drive. The simulated gamepad has:

  • left_stick_y set to -0.8 (as if the driver is pushing forward)
  • right_stick_y set to -0.6 (as if the driver is pushing forward, but less)
Your task:
  1. Read the gamepad stick values and negate them (to fix the Y-axis inversion).
  2. Set leftMotor power to the corrected left stick value.
  3. Set rightMotor power to the corrected right stick value.
After your code runs, leftMotor should be at power 0.8 and rightMotor at 0.6.

Give it a try!

Hints
Sign in to Run
Loading editor...

Output

Click Run to execute your code