Skip to content

Lesson 2: Intro to WPILib

James Li edited this page May 21, 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 configureBindings in RobotContainer
  • We can also set a default command for a Subsystem to run when idle

Examples

Run intakeCommand when button 2 is pressed:

joystick.button(2).onTrue(intake.intakeCommand());

Set arcadeDriveCommand to run by default:

drive.setDefaultCommand(drive.arcadeDriveCommand(
    () -> driverController.getLeftY(),
    () -> driverController.getRightX()));

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
  • When placed inside a Subsystem class, use this as the required subsystem (it's a reference to the instance of the class)

Example (inside a Climber subsystem):

public Command readyClimb() {
  return Commands.runOnce(
      // lambdas with more than one expression should be wrapped in curly braces {}
      () -> {
        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

A template project is provided for you here (TODO)

Clone this wiki locally