Programming
Command Based Programming Overview
Contributors:
Austin Benedicto
Austin Benedicto
This is going to be a basic introduction to the basics on command based programming. This works for both FTC and FRC although as of writing this (May, 2025) only FRC used a command base structure but it is planned to apply it to FTC
Command-based programming is a structural design pattern in which you encapsulate a request as an object, thereby allowing for:
Parameterization of clients with different requests.
Queuing of requests.
Logging or undoing operations.
This pattern is commonly used in robotics (e.g., FIRST Robotics) to define robot behavior in terms of modular, testable commands.
The main benefits of this programming structure is that it makes the code easier to read and it also allows you to solve logic issues easier because of the structure.
Modularity: Easier to manage and reuse small chunks of logic.
Testability: Commands can be independently tested.
Separation of concerns: Keeps logic separate from I/O and control.
Scalability: Makes large projects easier to manage and extend.
Represents a single action or behavior.
Implements a Command interface or extends an abstract class like CommandBase.
Lifecycle methods include:
initialize()
execute()
isFinished()
end()
Represents a physical or logical unit of a system (e.g., drivetrain, arm, shooter).
Usually extends SubsystemBase.
Contains methods to control hardware or state.
Manages the execution of commands, checking if they should run, end, or be interrupted.
Ensures that only one command requiring a subsystem runs at a time.
Frequently implemented using a singleton pattern.
This basic command consists of 2 class as a basic example but it can get a lot bigger and more expansive. With further layers of expansion and abstraction.
It is a Dive Forward command that has the basic Lifecycle methods that were talked about in the previous section.
Then it using the DrivetrainSubsystem class which is just a super simple tank drive class.
Here's a simple example of a command that drives a robot forward:
public class DriveForwardCommand extends CommandBase {
private final DrivetrainSubsystem drivetrain;
public DriveForwardCommand(DrivetrainSubsystem drivetrain) {
this.drivetrain = drivetrain;
addRequirements(drivetrain); // Declare subsystem dependency
}
@Override
public void initialize() {
System.out.println("Starting to drive forward");
}
@Override
public void execute() {
drivetrain.drive(0.5, 0); // Drive forward at 50% speed
}
@Override
public boolean isFinished() {
return false; // Run until explicitly stopped
}
@Override
public void end(boolean interrupted) {
drivetrain.stop();
}
}
public class DrivetrainSubsystem extends SubsystemBase {
private final MotorController leftMotor;
private final MotorController rightMotor;
public DrivetrainSubsystem() {
leftMotor = new MotorController(1);
rightMotor = new MotorController(2);
}
public void drive(double speed, double rotation) {
leftMotor.set(speed + rotation);
rightMotor.set(speed - rotation);
}
public void stop() {
leftMotor.set(0);
rightMotor.set(0);
}
}
Commands are often triggered by button presses or joystick input:
This binds a command to a joystick button, so it runs when the button is pressed.
Joystick joystick = new Joystick(0);
JoystickButton trigger = new JoystickButton(joystick, 1);
trigger.whenPressed(new DriveForwardCommand(drivetrain));
You can look at all of the Nichols FRC robot repositories after 2023-2024, a WPILib page that talks all about the basics of command based programming ( https://docs.wpilib.org/en/stable/docs/software/commandbased/index.html) , and the Mechanical Advantage skeleton base that they release every year. I suggest that you go and look at all of these because those are practical applications of everything in this article instead of just examples.