the video version
The same lesson as a narrated video. Watch it on YouTube
The two core ideas#
The command-based framework organizes code around two abstractions:
- Subsystems — a collection of hardware that works as a unit (a drivetrain, an arm, an intake). The subsystem owns its motors and sensors and exposes clean public methods like
setSpeed()orgetAngle(). The rest of the code can't touch the motors directly — only through the subsystem. - Commands — actions the robot performs (drive forward, raise the arm, run the intake). Commands use subsystems to do their work.
This separation keeps your code organized: hardware details stay inside subsystems, and behavior lives in commands.
Creating a subsystem#
The recommended way is to subclass SubsystemBase (Java/C++):
public class Intake extends SubsystemBase {
private final PWMSparkMax m_motor = new PWMSparkMax(5);
public void run() { m_motor.set(0.8); }
public void stop() { m_motor.set(0.0); }
@Override
public void periodic() {
// Called automatically every 20 ms by the scheduler
}
}
A subsystem's periodic() is run automatically by the scheduler — perfect for logging sensor values or running closed-loop updates.
The CommandScheduler#
The CommandScheduler is a singleton that runs the whole system. You start it by calling CommandScheduler.getInstance().run() once per loop — and the Command Robot template does this for you in robotPeriodic(). Each loop, the scheduler:
- Runs each subsystem's
periodic(). - Polls triggers/button bindings.
- Runs the currently scheduled commands.
- Handles commands that have finished or been interrupted.
Requirements: the resource-management rule#
The single most important rule: each command declares which subsystems it requires. The scheduler guarantees that no two commands require the same subsystem at the same time. If a new command needs a subsystem already in use, the old command is interrupted (by default). This prevents two pieces of code from fighting over the same motor — a classic source of bugs.
Default commands#
A subsystem can have a default command that runs whenever no other command requires it. The classic example: the drivetrain's default command reads the joysticks and drives the robot, so the robot is always drivable unless something else (like an auto-aim command) takes over.
drivetrain.setDefaultCommand(
drivetrain.run(() -> drivetrain.arcadeDrive(driver.getLeftY(), driver.getRightX())));
Why this scales#
With subsystems + the scheduler + requirements, complex robots stay manageable: each mechanism is isolated, conflicts are impossible by design, and behavior is composed from small, reusable commands. This is why command-based is the recommended structure for nearly all teams.
the part worth keeping
Key takeaways
- Subsystems encapsulate hardware; commands encapsulate behavior.
- Subclass SubsystemBase to create a subsystem; its periodic() runs automatically.
- The CommandScheduler runs everything; the Command Robot template calls it in robotPeriodic().
- Each command declares required subsystems, so two commands can never fight over one subsystem.
- Default commands run when nothing else needs the subsystem — e.g., joystick driving.
Programming, Controls & SensorsThe Robot Program: Lifecycle and Command-Based Architecturelesson 2 of 4
Keep going
Take the quiz+10 XP with an accountMore in The Robot Program: Lifecycle and Command-Based Architecture
where this came from
Sources and corrections
This lesson is AI-assisted: drafted from primary sources, then reviewed and edited by hand. Errors still get through. When one is reported we fix it and write down what changed, in public, in the corrections log.
sources and further reading
- docs.wpilib.orgWhat Is Command-Based Programming?
- docs.wpilib.orgSubsystems
- docs.wpilib.orgThe Command Scheduler
clipped to this lesson
Articles that go further on this
The lesson gets you through the topic. These go wider on it, and they read in one sitting.
- 9 min readFRC Command-Based Programming: Subsystems, Commands, and the SchedulerA beginner-friendly guide to WPILib command-based programming in Java: subsystems, commands, the CommandScheduler, triggers, and composing commands./blogread it
- 13 min readFRC Code Structure Best Practices: Command-Based Project ArchitectureHow to structure an FRC command-based robot project the right way — subsystems, commands, RobotContainer, and Constants — verified against official WPILib docs./blogread it
answer sheet
Lesson quiz
All 3 right completes the lesson. Miss one and only that question comes back, anything you already answered correctly stays banked.
0 of 3 answered
01In command-based programming, what does a subsystem represent?
02How does the CommandScheduler prevent two commands from fighting over the same hardware?
03What is a major advantage of the command-based framework over writing everything directly in teleopPeriodic?
Answer every question to submit.
All 51 lessons in Programming, Controls & Sensorsopenclose
01 / prerequisites
02 / foundations-tools-and-first-program
03 / robot-program-and-command-based
04 / motors-and-control
05 / autonomous-trajectories-simulation
06 / sensing-fundamentals
07 / encoders
08 / gyros-imus-orientation
09 / closed-loop-control
10 / vision-pose-estimation
11 / worked-examples-mini-projects
- Not read yet:Mini-Project: A Closed-Loop Elevator with Motion Magic
- Not read yet:Mini-Project: A Velocity-Controlled Shooter on REVLib
- Not read yet:Mini-Project: A Teleop Swerve Drive Subsystem
- Not read yet:Mini-Project: An Autonomous Routine with PathPlanner
- Not read yet:Mini-Project: Vision-Aligned Scoring with Limelight
12 / common-mistakes-troubleshooting
13 / advanced-techniques-case-studies
- Not read yet:State-Space Control and Kalman Filtering
- Not read yet:Log Replay Architecture with AdvantageKit
- Not read yet:Advanced Pose Estimation: Multi-Tag Fusion and Standard Deviations
- Not read yet:Robot Coordination, Alerts, and Operator Feedback
- Not read yet:Case Study: Hardening Software Before an Event