Home / Offseason / Week O3
Offseason · Week 3 of 8

Command-Based Architecture

Subsystems, Commands, Triggers, and the Command Scheduler.

The Big Idea

Command-based splits robot code into Subsystems (hardware + what it can do) and Commands (actions that use that hardware). Think Lego — subsystems are pieces, commands are what you build with them.

Subsystem
Hardware abstraction
Motors, sensors, state. Exposes methods like setSpeed(), stop(), getPosition(). Never control hardware from outside the subsystem.
Command
An action
Uses subsystems. Has initialize(), execute(), end(), isFinished(). Runs on the 20ms loop.
Scheduler
Traffic controller
Runs active commands every 20ms. Prevents two commands from fighting over the same subsystem.
Trigger
What starts a command
Button press, sensor threshold, timer. Configured in RobotContainer.
java — subsystem
public class DriveSubsystem extends SubsystemBase {
    private final CANSparkMax leftMotor  = new CANSparkMax(DriveConstants.LEFT_ID,  MotorType.kBrushless);
    private final CANSparkMax rightMotor = new CANSparkMax(DriveConstants.RIGHT_ID, MotorType.kBrushless);

    public void tankDrive(double left, double right) {
        leftMotor.set(left); rightMotor.set(right);
    }
    public void stop() { leftMotor.set(0); rightMotor.set(0); }

    @Override
    public void periodic() {
        SmartDashboard.putNumber("Left Speed", leftMotor.get());
    }
}
java — command
public class TeleopDriveCommand extends Command {
    private final DriveSubsystem drive;
    private final XboxController  controller;

    public TeleopDriveCommand(DriveSubsystem drive, XboxController controller) {
        this.drive = drive; this.controller = controller;
        addRequirements(drive); // claim the subsystem
    }
    @Override public void execute() {
        drive.tankDrive(-controller.getLeftY(), -controller.getRightY());
    }
    @Override public void end(boolean interrupted) { drive.stop(); }
    @Override public boolean isFinished() { return false; }
}

Command Compositions

java — auto sequence
import static edu.wpi.first.wpilibj2.command.Commands.*;

Command auto = sequence(
    new DriveForwardCommand(drive, 1.5),
    new ScoreCommand(shooter),
    parallel(
        new DriveBackCommand(drive, 1.0),
        new StowCommand(arm)
    )
);

Knowledge Check