the video version
The same lesson as a narrated video. Watch it on YouTube
What a command is#
A command has four lifecycle pieces: initialize() (once at start), execute() (every loop), isFinished() (returns true to end), and end(boolean interrupted) (cleanup). A command runs from when it's scheduled until it finishes or is interrupted.
You can write a full command class, but modern WPILib strongly encourages lambdas and factory methods instead — they cover almost every use case with far less code.
Inline commands with factories#
The Commands utility class and subsystem helper methods build commands inline:
// Run the intake until the button is released (runEnd: run, then stop)
Command intakeCmd = intake.runEnd(intake::run, intake::stop);
// A command that does one thing and finishes immediately
Command stopCmd = Commands.runOnce(intake::stop, intake);
// Run until a condition is met
Command raiseCmd = arm.run(arm::raise).until(arm::atTop);
Common building blocks:
run(...)— runs an action every loop (never finishes on its own).runOnce(...)— runs once and ends.runEnd(run, end)— runs an action, then runs an end action when it stops..until(condition)— adds an end condition to any command..withTimeout(seconds)— ends after a time limit.
Using the subsystem's own run/runEnd factory methods automatically adds that subsystem as a requirement.
Compositions: building bigger behavior#
Commands are composable — you combine small commands into bigger ones. The main compositions:
- Sequential — run commands one after another:
Command auto = Commands.sequence( drivetrain.driveForward(2.0), arm.raiseToScore(), intake.eject()); - Parallel — run commands at the same time. Variants include
parallel()(waits for all),race()(ends when the first ends), anddeadline()(ends when one specific "deadline" command ends). - Decorators —
.andThen(...),.alongWith(...),.raceWith(...)chain commands fluently:arm.raiseToScore().andThen(intake.eject());
Because a composition is itself a command, you can nest compositions inside compositions — a full autonomous routine is just one big command.
A practical pattern#
Keep command factories as methods on the subsystem that returns them:
public class Intake extends SubsystemBase {
public Command intakeCommand() { return runEnd(this::run, this::stop); }
}
Then wiring becomes a one-liner: driver.a().whileTrue(intake.intakeCommand()); (covered next). This keeps behavior close to the hardware it controls and keeps RobotContainer readable.
When to write a class#
Write a dedicated command class only when logic is genuinely complex (lots of state, multiple phases) and a lambda would be unreadable. For most actions, inline factories are cleaner and less error-prone.
the part worth keeping
Key takeaways
- A command has initialize / execute / isFinished / end; most are built with lambdas instead.
- Use factory methods (run, runOnce, runEnd) and decorators (.until, .withTimeout, .andThen).
- Compositions (sequence, parallel, race, deadline) combine commands into bigger behavior.
- Subsystem factory methods auto-add the subsystem as a requirement.
- Write a full command class only for genuinely complex, multi-phase logic.
Programming, Controls & SensorsThe Robot Program: Lifecycle and Command-Based Architecturelesson 3 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.orgCommands
- docs.wpilib.orgCommand Compositions
- docs.wpilib.orgOrganizing Command-Based Robot Projects
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
- 15 min readHow to Design an FRC Intake: Rollers, Compression, and MotorsA primary-source FRC intake design guide: over-the-bumper vs under-bumper, roller vs wheel, compliance and durometer, compression and wrap, and motor selection./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 a Command's lifecycle, when is the execute() method called?
02What does the boolean parameter in end(boolean interrupted) tell you?
03Why is it a good pattern to keep command factory methods on the subsystem that returns them?
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