FTC · Java · Mecanum Drive

Four Wheels That Slide Sideways

How a thumb on a controller turns into four motors that can drive, spin, and strafe — explained step by step, with stuff you can drag.

1

The big idea

When a driver moves a joystick during a match, your robot doesn't understand "go forward." It only knows how to do one thing: spin each motor at some power.

A mecanum robot has four drive motors — one at each corner. Your code's whole job during driver control is to read the controller, do a little math, and hand each of the four motors a power number. Read → math → set power, about 50 times a second.

// This loop runs over and over while the match is on
while (opModeIsActive()) {
    // 1. read the controller
    // 2. do the math (that's what this guide is about)
    // 3. tell all four motors how hard to spin
}
2

What a joystick actually gives you

A joystick reports two numbers, and each one is always between -1 and +1.

Resting in the middle, both numbers are 0. Push it part-way and you get part-way numbers like 0.5 or -0.3. Try it — drag the stick below and watch the numbers.

up down left right
drag me
left_stick_x0.00
left_stick_y0.00

Move the stick to see the values change.

⚠ The #1 gotcha every rookie hits Push the stick UP and left_stick_y goes negative, not positive! The controller measures Y upside-down. Notice it above: up = -1, down = +1.

That's backwards from how we think ("up should mean forward, forward should be positive"). The fix is one tiny minus sign — we flip it the moment we read it:

double y = -gamepad1.left_stick_y; // flip it, now up = forward = positive

From here on, y means "forward is positive," the way a human expects.

3

The secret: mecanum wheels can slide sideways

A normal wheel can only roll forward and back. A mecanum wheel is different: around its rim it has a bunch of little rollers set at a 45° angle.

Because of that angle, when the motor spins a mecanum wheel, the wheel doesn't just push straight — it also pushes diagonally, like a slanted conveyor belt.

motor spins wheel push!

Spin one wheel and it scoots the robot diagonally. That's useless alone — but put four of them at the corners, each angled in a clever pattern, and their diagonal pushes can add up or cancel out.

Mix them one way → the diagonals combine into straight forward. Mix them another way → they combine into a pure sideways slide (that's strafing). Mix them a third way → the robot spins in place.

The four wheels are mounted in an X pattern — notice the roller stripes on the robot below tilt opposite ways on each diagonal.
4

Three ideas: drive, strafe, and turn

Arcade drive had two ideas. Mecanum has three, because now we can slide sideways too:

double y  = -gamepad1.left_stick_y;  // forward / back
double x  =  gamepad1.left_stick_x;  // strafe
double rx =  gamepad1.right_stick_x; // turn

Each of the four wheels gets its own recipe of pluses and minuses. Don't memorize them — just notice every wheel uses the same three numbers, only the signs change:

frontLeft  = y + x + rx;
backLeft   = y - x + rx;
frontRight = y - x - rx;
backRight  = y + x - rx;
Spot the pattern y is plus on every wheel (forward moves them all the same way). x flips sign on a diagonal (that's what makes it strafe — the X pattern). rx is plus on the left wheels and minus on the right (so the left side and right side fight each other, which spins the robot).

Worked example. Drive forward a bit while strafing right: y = 0.5, x = 0.5, rx = 0.

frontLeft  = 0.5 + 0.5 + 0 = 1.0
backLeft   = 0.5 - 0.5 + 0 = 0.0
frontRight = 0.5 - 0.5 - 0 = 0.0
backRight  = 0.5 + 0.5 - 0 = 1.0

Only two wheels spin — and they're the ones on one diagonal. That diagonal push sends the robot gliding forward-and-to-the-right.

Play with it. Left stick drives and strafes, right stick turns. Watch the four motors and the robot's movement arrow update live.

fwd back
LEFT stick
drive + strafe
RIGHT stick
turn (left/right only)
▲ FRONT ▲
frontLeft
0
frontRight
0
backLeft
0
backRight
0
spins forward spins backward
y (drive)0.00
x (strafe)0.00
rx (turn)0.00
frontLeft = y + x + rx = 0.00
backLeft = y - x + rx = 0.00
frontRight = y - x - rx = 0.00
backRight = y + x - rx = 0.00
↑ push left stick straight up → all 4 spin forward → push left stick straight right → strafe (the X lights up) ⟳ push right stick → spin in place
5

One last problem: motors can't go past 100%

A motor's power has to stay between -1 and +1. But add three numbers together and you can easily blow past that.

Example: drive forward full (y = 1) and strafe full (x = 1): the front-left wheel wants 1 + 1 = 2.0. A motor can't do 2.0 — it just maxes out at 1.0, and now the four wheels are out of balance, so the robot drifts off in the wrong direction.

The fix is called normalizing: if the biggest wheel value is over 1, we shrink all four by the same amount. They keep their proportions, so the robot still glides the right direction — just safely under the limit.

// Find the biggest power we're asking for (but never less than 1)
double max = Math.max(Math.abs(y) + Math.abs(x) + Math.abs(rx), 1.0);

double frontLeftPower  = (y + x + rx) / max;
double backLeftPower   = (y - x + rx) / max;
double frontRightPower = (y - x - rx) / max;
double backRightPower  = (y + x - rx) / max;
In plain English Dividing by max is like splitting a pizza: no matter how much everyone wants, you share the same whole pizza fairly so nobody gets more than 100%. The slices stay in the same ratio.

The robot above already does this — that's why pushing both sticks all the way never makes a wheel read past 1.00.


The whole thing — copy/paste cheat sheet

Here's a complete, working mecanum driver-control loop. This is real FTC Java you can drop into a TeleOp OpMode for a four-motor robot:

while (opModeIsActive()) {
    // --- 1. read the sticks (note the minus sign on y!) ---
    double y  = -gamepad1.left_stick_y;  // forward / back
    double x  =  gamepad1.left_stick_x;  // strafe
    double rx =  gamepad1.right_stick_x; // turn

    // --- 2. mix them into four wheel powers ---
    double max = Math.max(Math.abs(y) + Math.abs(x) + Math.abs(rx), 1.0);
    double frontLeftPower  = (y + x + rx) / max;
    double backLeftPower   = (y - x + rx) / max;
    double frontRightPower = (y - x - rx) / max;
    double backRightPower  = (y + x - rx) / max;

    // --- 3. send the power to the four motors ---
    frontLeft.setPower(frontLeftPower);
    backLeft.setPower(backLeftPower);
    frontRight.setPower(frontRightPower);
    backRight.setPower(backRightPower);
}

Things to remember:

  • Always flip Y. -gamepad1.left_stick_y, or up will drive you backward.
  • Always normalize (divide by max) so no motor is asked for more than it can give.
  • Motor directions matter. The two left motors usually need reversing in setup: frontLeft.setDirection(DcMotorSimple.Direction.REVERSE). If forward makes the robot spin or strafe, a motor direction is wrong — fix it here, not in the math.
  • Wheel/roller pattern matters too. Mecanum wheels must be mounted in the X pattern (rollers form an X when you look down at the robot). Mount them wrong and strafing won't work no matter how perfect the code is.
  • Pro tip — strafing is weaker. Robots strafe a little weaker than they drive. Many teams nudge it with double x = gamepad1.left_stick_x * 1.1; to even it out.
  • Deadzone. Sticks rarely sit at a perfect 0, so the SDK ignores tiny wiggles for you. Widen it with gamepad1.setJoystickDeadzone(0.05f) if the robot creeps while idle.

This same loop is the heart of every mecanum driver-control program. Fancier features — slow mode, button-controlled arms, even field-centric driving (where "forward" always means away from the driver, no matter which way the robot faces) — are just more bits of math added on top of these three numbers.

// happy strafing — go team 🐝