Mecanum Drive and Debugging with Telemetry
Write a robot-centric mecanum drive with normalised motor powers, then use telemetry and a clear process to find and fix common errors.
In this lesson you will
- Explain how mecanum wheel forces combine to drive forward, strafe and turn.
- Write a robot-centric mecanum TeleOp that normalises motor powers.
- Use telemetry to show live values on the Driver Station.
- Diagnose and fix common FTC programming errors using a step-by-step process.
Lesson
Mecanum wheels have angled rollers, so each wheel pushes the robot both forward and sideways. By spinning the four wheels in different combinations, the robot can drive forward, strafe sideways, turn, or do all three at once. In a robot-centric drive, the sticks are relative to the front of the robot: pushing the stick forward always moves the robot toward its own front, wherever it is facing.
| Motion | Left front | Right front | Left back | Right back |
|---|---|---|---|---|
| Forward | + | + | + | + |
| Strafe right | + | - | - | + |
| Turn right (clockwise) | + | - | + | - |
To combine motions, add the three parts for each wheel. If the driver pushes forward and right at the same time, some wheels get a sum larger than 1.0. Motors cannot go above full power, so large values would be cut off and the robot would drift in the wrong direction. The fix is normalisation: find the largest absolute power, and if it is above 1.0, divide all four powers by it. The wheels keep the same proportions, so the robot moves in the direction the driver intended.
1@TeleOp(name = "Mecanum Drive", group = "Drive")
2public class MecanumDrive extends LinearOpMode {
3 @Override
4 public void runOpMode() {
5 DcMotor leftFront = hardwareMap.get(DcMotor.class, "left_front");
6 DcMotor rightFront = hardwareMap.get(DcMotor.class, "right_front");
7 DcMotor leftBack = hardwareMap.get(DcMotor.class, "left_back");
8 DcMotor rightBack = hardwareMap.get(DcMotor.class, "right_back");
9 leftFront.setDirection(DcMotor.Direction.REVERSE); // test on your robot
10 leftBack.setDirection(DcMotor.Direction.REVERSE);
11
12 waitForStart();
13
14 while (opModeIsActive()) {
15 double axial = -gamepad1.left_stick_y; // forward is negative, so flip it
16 double lateral = gamepad1.left_stick_x; // strafe
17 double yaw = gamepad1.right_stick_x; // turn
18
19 double lf = axial + lateral + yaw;
20 double rf = axial - lateral - yaw;
21 double lb = axial - lateral + yaw;
22 double rb = axial + lateral - yaw;
23
24 double max = Math.max(Math.max(Math.abs(lf), Math.abs(rf)),
25 Math.max(Math.abs(lb), Math.abs(rb)));
26 if (max > 1.0) {
27 lf /= max; rf /= max; lb /= max; rb /= max;
28 }
29
30 leftFront.setPower(lf);
31 rightFront.setPower(rf);
32 leftBack.setPower(lb);
33 rightBack.setPower(rb);
34
35 telemetry.addData("Front L/R", "%.2f / %.2f", lf, rf);
36 telemetry.addData("Back L/R", "%.2f / %.2f", lb, rb);
37 telemetry.update();
38 }
39 }
40}
Telemetry: your robot's voice
Telemetry sends text from the robot to the Driver Station screen. telemetry.addData(caption, value) adds a line, and telemetry.update() sends all the lines added since the last update. Without update(), nothing appears. Use telemetry to check what the program believes: the joystick values it reads, the powers it calculates, the servo position it commands. When the robot behaves strangely, the numbers usually show you why.
1// import com.qualcomm.robotcore.util.ElapsedTime;
2ElapsedTime runtime = new ElapsedTime();
3
4waitForStart();
5runtime.reset();
6
7while (opModeIsActive()) {
8 // ... drive code ...
9 telemetry.addData("Run time", "%.1f s", runtime.seconds());
10 telemetry.addData("Left stick", "x=%.2f y=%.2f",
11 gamepad1.left_stick_x, gamepad1.left_stick_y);
12 telemetry.addData("Claw target", claw.getPosition());
13 telemetry.update(); // nothing is shown without this line
14}
Common errors and how to fix them
| Symptom | Likely cause | Fix |
|---|---|---|
| OpMode is not in the Driver Station list | Missing @TeleOp, an @Disabled annotation, or the build failed | Add the annotation, remove @Disabled, rebuild and read build errors |
| Error during INIT: unable to find a hardware device | Name or device type in code does not match the active configuration | Compare names character by character and check the active configuration |
| Robot drives backward when the stick is pushed forward | Missing minus sign on left_stick_y or wrong motor directions | Use -gamepad1.left_stick_y and retest each motor |
| Telemetry shows nothing new | telemetry.update() is never called | Call telemetry.update() once at the end of each loop |
| Robot does not stop properly when STOP is pressed | A loop that does not check opModeIsActive(), or long sleep calls | Use while (opModeIsActive()) and avoid long sleeps in TeleOp |
NullPointerException | A device variable was used before hardwareMap.get gave it a value | Make sure every device is assigned in INIT before it is used |
| Build error: cannot find symbol | Typo, wrong capital letter, or missing import | Check spelling and add the import the error points to |
- 1Read the messageRead the whole error on the Driver Station or in the build output. It often names the file, the line and the problem.
- 2Reproduce itMake the problem happen again on purpose so you know exactly what triggers it.
- 3Look at the numbersAdd telemetry for the values involved and compare what the program believes with what the robot does.
- 4Change one thingMake a single change, rebuild and test. If you change five things at once, you will not know which one helped.
- 5Write it downRecord the symptom, the cause and the fix in your debugging log for the engineering portfolio.
You now have everything for this week's assignment: a configured robot, motors and servos in code, a TeleOp structure, gamepad controls and a debugging process. Build your driver-controlled program step by step, test each addition, and keep your debugging log up to date.
Key terms
- Strafe
- Moving sideways without turning, possible with mecanum or omni wheels.
- Robot-centric drive
- A drive mode where stick directions are relative to the front of the robot, not to the field.
- Normalisation
- Dividing all motor powers by the largest absolute value when it exceeds 1.0, so the powers stay in range and keep their proportions.
- Telemetry
- Text the robot sends to the Driver Station using
telemetry.addDataandtelemetry.update. - Debugging
- The process of finding the cause of a problem in a program and fixing it.
Practical exercise
Drive, break, fix
- 1Type in the mecanum OpMode with your configuration names and add the needed imports.
- 2Test with the wheels off the ground: push forward, strafe right and turn right, and compare each wheel with the table in this lesson.
- 3Fix motor directions until all three motions are correct, then drive on the field tiles.
- 4Add telemetry for stick values and all four powers, and a slow mode on the right bumper.
- 5Have a teammate secretly add one bug (such as a wrong name or a missing
telemetry.update()), then find and fix it using the five debugging steps.
Knowledge check
Answer every question, then check your answers.