Skip to content

Lesson 2: Intro to WPILib

James Li edited this page May 17, 2025 · 14 revisions

What is WPILib?

  • WPILib = The library/framework we use to program our robot in Java
  • Built for FRC
  • Contains useful classes and methods for interacting with many parts of the FRC control system
    • Handles: motors, sensors, joysticks, the driver station, etc.

Our job: use WPILib to design how the robot thinks and behaves

  • E.g. organizing subsystems, defining commands, linking controls

Goals For Today

  • Understand how WPILib projects are structured
  • Learn about how commands are defined and scheduled
  • Make a small command to test it out

WPILib Code Structure Overview

image

WPILib Program Flow Overview

image
  • Command Sources: Responsible for starting commands
  • Commands: Define robot behavior
  • Subsystems: Responsible for the hardware, e.g. translating commands into motor output

Command Sources: Triggers and Default Commands

  • We bind Commands to Triggers (like button presses) in the configureBindings method inside the RobotContainer class
  • We can also specify a default command for a Subsystem that runs continuously

Example:

When the leftBumper button on the joystick is pressed, run the seedFieldCentric command

By default, continuously run the roller Subsystem based on what the joystick triggers read

Commands

  • Commands define robot actions/behaviors that tell subsystems what to do
    • Use subsystem methods to move motors, etc.
  • Each command typically controls one or more subsystems
    • Only one command can control a subsystem at a time

Declaring a Command object

  • means defining an action
  • DOES NOT RUN BY ITSELF

Examples:

Commands.run(() -> { ... })
Commands.runOnce(() -> { ... })
Commands.sequence(cmd1, cmd2, ...)
cmd1.andThen(cmd2)
new InstantCommand(() -> { ... })

Scheduling a Command

  • means telling WPILib to actually run it

Examples:

button.onTrue(cmd)        // binding to a Trigger
subsystem.setDefaultCommand(cmd)

Creating a Command Object: Example

Commands.runOnce(() -> intake.retract(), intake)
  • Commands.runOnce(...): Creates a command that runs once, then ends immediately
  • () -> intake.retract(): An anonymous function (lambda) that calls the retract() method on the intake subsystem
  • intake: Specifies the subsystem this command requires (ensures only one command controls it at a time)

This does not run the command. Pass it into something like intake.setDefaultCommand() to schedule.

Commands and Method Chaining

  • Complex commands can be built using method chaining
  • Method chaining: calling methods on the return values of other methods (in this case, Command objects)
  • You don’t need to memorize syntax now: just understand that complex behavior can be chained together.

Example:

Commands.runOnce(() -> shooter.spinUp(), shooter)
        .andThen(Commands.waitSeconds(2))
        .andThen(Commands.runOnce(() -> shooter.fire(), shooter));

What this Command does:

  • Starts by spinning up the shooter wheels
  • Waits 2 seconds for the wheels to reach speed
  • Then fires once

It uses method chaining (specifically .andThen()) to run these actions one after the other.

Command Factories

  • Instead of creating commands inline everywhere, we often write methods that return Command objects
  • These are called command factories
    • Keeps code organized and reusable
    • Placed inside the Subsystem class (if specific) or a class inside the commands/ folder

Example (inside a Climber subsystem):

public Command readyClimb() {
    return Commands.runOnce(() -> {if (climbIsReady()) climbState = ClimbState.PULL; }, this);
}

Usage (in RobotContainer):

driverController.a().onTrue(climber.readyClimb());

Subsystems

  • Represent robot parts like drivetrain, shooter, climber
  • Own the hardware (motors, sensors)
    • Responsible for converting abstract Commands into real motor actions
  • Expose methods that Commands use to control the robot
    • E.g. elevator.goToPosition()

More details in the next lesson

Code Structure Tour

Let’s trace through how input (button) turns into output (motor) in our wrist robot code.

See: the 971-robot-2025 repo.

Task for This Lesson

  • Create a command factory method inside the Climber subsystem
  • Bind it to the A button on the joystick
  • The command should print "Climb starting" when A is pressed
  • Test out your code in a simulation

A template project is provided for you here (TODO)

Clone this wiki locally