Intro to Command-Based Programming Lesson

Intro to Command-Based Programming

Welcome to the framework that brings it all together. The Command-Based model is the official, modern, and powerful way to structure robot code for clarity, reliability, and scalability. This is the standard we use on FRC 2910.

Why Do We Need a New Model?

Imagine trying to code a full competition robot inside a single `Robot.java` file. It would become a tangled mess, impossible to debug or for multiple programmers to work on. The Command-Based model solves this by enforcing a strict separation of concerns.

The Core Philosophy: What it IS vs. What it DOES

The entire framework is built on this simple separation:

  • Subsystems: These represent what the robot IS. They are the physical mechanisms like the `Drivetrain`, `IntakeSubsystem`, or `ArmSubsystem`.
  • Commands: These represent what the robot DOES. They are specific actions like `DriveWithJoysticks`, `IntakeGamePiece`, or `MoveArmToAngle`.

A Command uses one or more Subsystems to accomplish its goal.

The Three Key Players

You'll work with three main components in a Command-Based project.

1. Subsystems

A subsystem class is a container for all the hardware (motors, sensors) related to a single mechanism. Its job is to provide simple methods to control its hardware. A subsystem should never know about joysticks or buttons.

public class IntakeSubsystem extends SubsystemBase {
    private final Spark m_intakeMotor = new Spark(5);

    public void setMotorSpeed(double speed) {
        m_intakeMotor.set(speed);
    }
}
    

2. Commands

A command class defines a single, self-contained action. This is where your logic, like state machines, will live. A command "requires" the subsystem(s) it needs, which prevents two commands from controlling the same mechanism at once.

public class IntakeCommand extends Command {
    private final IntakeSubsystem m_intake;

    public IntakeCommand(IntakeSubsystem intake) {
        m_intake = intake;
        addRequirements(m_intake); // Declare that this command uses the intake
    }

    @Override
    public void execute() {
        m_intake.setMotorSpeed(0.8);
    }
    // ... other command methods ...
}
    

3. RobotContainer

This class is the central hub where everything is put together. Its job is to create instances of your subsystems and controllers, and most importantly, to bind commands to controller buttons.

public class RobotContainer {
    // Create subsystems
    private final IntakeSubsystem m_intake = new IntakeSubsystem();
    
    // Create controllers
    private final XboxController m_operatorController = new XboxController(1);

    public RobotContainer() {
        configureButtonBindings();
    }

    private void configureButtonBindings() {
        // When the 'A' button is held, run a new IntakeCommand
        new JoystickButton(m_operatorController, XboxController.Button.kA.value)
            .whileTrue(new IntakeCommand(m_intake));
    }
}
    

Test Your Knowledge

Question: In the Command-Based model, which component is responsible for creating the motor controller objects for the intake mechanism?