Section 2: Commands

WPILib has a system to allow for high level actions to be safely and easily coordinated via Commands, Subsystems and Triggers, called Command-based. It is the way that robot mechanism actions are handled in modern FRC programming, and any deviations from the code design patterns it expects are considered unsafe, both in terms of code behavior, and physical safety.

In Command-based architecture, each physical mechanism is represented through a Subsystem class, and each action that the mechanism takes is represented through a Command. Each Command can be scheduled to run by Trigger s, which can be anything from "The primary driver's controller's a button is down" to "The sensor detected a game piece for longer than .5 seconds."

One crucial difference with normal programming is that normal coding is in a imperative style, meaning you are in control of what happens when, using bigger blocks of code, but Command-based architecture is a declarative event-driven style, where you declare that a short bit of code (A Command) should run when an event (A Trigger) happens, and the library handles the rest.

Subsystems

The mechanism in which Command-based architecture enforces behavioral and physical safety is through Subsystem mutexing. A mutex, or mutual exclusion, means that a resource cannot be accessed by two operations at the same time, or in this case, two Commands cannot require the same Subsystem(s) simultaneously. If command A is running and requires the arm subsystem, but command B is scheduled and it also requires the arm subsystem, then command A is canceled so that command B can run.

A Subsystem can only be used by one Command at a time, but a Command can take control of multiple Subsystems, such as a "place game piece" command taking control of the Arm subsystem and Wrist subsystem simultaneously.

TODO: Make lesson

Lambdas

Declaring what code runs is done through lambas. It is similar to functions/methods in that it is defined and run later, but the reference to that define code can be passed around as data, and called upon by code. Commands primarily use Runnables (which just runs code) and Suppliers (which outputs a value) as the creation of a Command object and when that command is actually run are different times.

The syntax of a lambda is as follows:

var lambda = () -> {
  // Some code that runs later
  // If this is a Supplier, then a return statement would be at the end.
};

If all a lambda does is call upon an existing method, IE:

var lambda = () -> { foo.bar() };

Then it can be shortened as such:

var lamdba = foo::bar;

Executing Commands with Triggers

To run a command, it must be scheduled to execute via Trigger s. A Trigger takes in a boolean state (button down, sensor tripped, etc.) and schedules or cancels Commands that are bound to it when the state changes.

For a lesson on binding Commands to Trigger s, see below:

Lesson 2.?: Binding Commands to Triggers

NEVER schedule commands manually or execute them manually through command.schedule() and command.execute() .

Commands

There are many types of Commands that do different things. Each command type have their own pages and accompanying lessons:

Lesson 2.?: run Command

Command factories

A factory method is a method that hides the object instantiation (new ) within itself, making it cleaner to read the code. WPILib has many factory methods for commands, which allows for use of commands without calling class constructors explicitly.

There are two sources for command factories:

  • The Subsystem class

    • Commands from these factories automatically declare the subsystem as a requirement, allowing for implicit command requirements.

    • Does not contain all the factories.

  • import static edu.wpi.first.wpilibj2.command.Commands.*;

    • Has factories for every command type.

    • Does not have implicit command requirements.

You can also make your own command factories in a subsystem class. This allows for command actions to be a single method from the outside, while keeping resources, variables, and logic on the inside.

Command groups

In addition, commands can be grouped together to run sequentially, in parallel, racing each other, etc. See the below lesson for more:

Lesson 2.?: Command Groups

Last updated

Was this helpful?