Organizing Your FTC Code for Debuggability and Growth
Why Code Organization Matters
Good code organization makes your programs easier to debug, maintain, and expand. In FTC, it's especially important to avoid large, monolithic files. Instead, break your code into small, focused classes and methods.
Modularizing Hardware Initialization in Your OpMode
To keep your OpMode organized and easy to debug, move hardware initialization into a separate function within your OpMode class. This keeps your main logic clean and makes it easier to update or troubleshoot hardware mapping without touching the rest of your code.
Example: Hardware Initialization Function
private DcMotor leftMotor, rightMotor;
private void initHardware() {
leftMotor = hardwareMap.get(DcMotor.class, "left_drive");
rightMotor = hardwareMap.get(DcMotor.class, "right_drive");
}Using the Hardware Initialization Function in Your OpMode
@TeleOp
public class ModularOpMode extends LinearOpMode {
private DcMotor leftMotor, rightMotor;
@Override
public void runOpMode() {
initHardware();
waitForStart();
while (opModeIsActive()) {
leftMotor.setPower(0.5);
rightMotor.setPower(0.5);
}
}
private void initHardware() {
leftMotor = hardwareMap.get(DcMotor.class, "left_drive");
rightMotor = hardwareMap.get(DcMotor.class, "right_drive");
}
}Naming Conventions and File Structure
Use clear, descriptive names for your classes, methods, and variables. Organize your files so that related code is grouped together. This helps you and your teammates find and fix bugs faster.
Tips for Good Code Organization
- Keep each file focused on one purpose (e.g., hardware, drive logic, sensors).
- Use consistent naming conventions.
- Document your code with comments and JavaDoc.
- Avoid duplicating codeāuse helper methods or classes instead.
- Review and refactor your code regularly.
Documenting Your Code
Comments and documentation help you remember your logic and make it easier for others to help debug. Use JavaDoc for methods and classes, and add inline comments for tricky logic.
JavaDoc Example
/**
* Sets the power for both drive motors.
* @param power The power level (-1.0 to 1.0)
*/
public void setDrivePower(double power) {
leftMotor.setPower(power);
rightMotor.setPower(power);
}Using Version Control for Debugging
Version control lets you track changes and revert to working code. While OnBot Java doesn't have built-in Git, you can still keep backups and use comments to mark changes. For more on version control in FTC, see FTC Docs: Programming Resources.
Practice: Refactor a Monolithic OpMode
Take a long OpMode file and break it into at least two classes (e.g., hardware and logic). Add comments and JavaDoc to your methods. Test that your code still works.
- Identify sections of code that can be moved to helper classes.
- Refactor the code and update your OpMode to use the new classes.
- Add JavaDoc and comments to explain your logic.
// Example of a monolithic OpMode (all logic and hardware in one class)
@TeleOp
public class MonolithicOpMode extends LinearOpMode {
private DcMotor leftMotor, rightMotor;
private Servo clawServo;
@Override
public void runOpMode() {
leftMotor = hardwareMap.get(DcMotor.class, "left_drive");
rightMotor = hardwareMap.get(DcMotor.class, "right_drive");
clawServo = hardwareMap.get(Servo.class, "claw_servo");
waitForStart();
while (opModeIsActive()) {
double leftPower = -gamepad1.left_stick_y;
double rightPower = -gamepad1.right_stick_y;
leftMotor.setPower(leftPower);
rightMotor.setPower(rightPower);
if (gamepad1.a) {
clawServo.setPosition(1.0);
} else if (gamepad1.b) {
clawServo.setPosition(0.0);
}
telemetry.addData("Left Power", leftPower);
telemetry.addData("Right Power", rightPower);
telemetry.addData("Claw Position", clawServo.getPosition());
telemetry.update();
}
}
}