Skip to content

Triggers and Scheduling

Remember that Triggers are the stimuli that trigger robot behavior, which we call Commands. We say that Triggers “schedule” Commands.

sources/Triggers, at their core, are methods that return a boolean - true for active, and false for inactive. You can fetch a trigger’s active status with the getAsBoolean() method:

Trigger motorTooFastTrigger = new Trigger(() -> motor.speed() > 60);
boolean isMotorTooFast = motorTooFastTrigger.getAsBoolean();

There are 2 ways triggers can schedule commands:

  1. trigger.onTrue(Command): Schedules a command when a trigger switches from inactive to active. In the following example, the runAtThrottle command will run once teleop mode is selected and enabled.
public class Robot {
private final ExampleMechanism intake = new ExampleMechanism();
private static boolean teleopEnabled() {
return RobotState.isTeleopEnabled(); // in case you didn't know!
}
public Robot() {
Trigger teleopEnabledTrigger = new Trigger(() -> teleopEnabled());
teleopEnabledTrigger.onTrue(intake.runAtThrottle(0.5));
// A shorthand for the above:
new Trigger(() -> teleopEnabled()).onTrue(intake.runAtThrottle(0.5));
}
}
  1. trigger.whileTrue(Command): Identical to onTrue, but cancels the running command when the trigger becomes inactive again. If teleopEnabledTrigger.onTrue(...) was changed to teleopEnabledTrigger.whileTrue(...), disabling teleop mode on the driver station will cancel the runAtThrottle command mid-run.
Note

You can bind multiple commands to the same trigger!

Trigger teleopEnabledTrigger = new Trigger(() -> RobotState.isTeleopEnabled());
teleopEnabledTrigger.whileTrue(intake.runAtThrottle(0.5));
teleopEnabledTrigger.whileTrue(shooter.runAtThrottle(0.5));

You can also stack whileTrue() and onTrue() calls:

new Trigger(() -> RobotState.isTeleopEnabled())
.whileTrue(intake.runAtThrottle(0.5))
.whileTrue(shooter.runAtThrottle(0.5));

A common stimulus for robot behavior is the buttons on a controller. For instance, shooting balls while the x button on the operator controller is held. From section 1A, you might recall that fetching the state of a button can be done like so:

XboxController xbox = new XboxController(0);
boolean aButtonHeld = xbox.getAButton();

Where the getAButton() method returns true if the button is being held, and false otherwise. So, it’s possible to create a trigger mapped to the a button like so:

XboxController xbox2 = new XboxController(0);
Trigger aButton = new Trigger(() -> xbox2.getAButton());
aButton.whileTrue(someCommand());

However, this is a common enough usecase that the commands framework provides a special class, called CommandXboxController, that makes interfacing with controller buttons easier for command-based programming.

CommandXboxController xbox3 = new CommandXboxController(0);
Trigger aButton2 = xbox3.a();
aButton2.whileTrue(someCommand());
// shorthand:
xbox3.a().whileTrue(someCommand());

You can also decide to run a command immediately, bypassing triggers entirely, like so:

Scheduler.getDefault().schedule(myAutonomousCommand());
System.out.println("Hello!");

Think of calling schedule() as ordering a robot to start washing the dishes without waiting for it to finish. In this case, the println("Hello!") statement will run before the autonomous command completes.

Note

This is generally not recommended outside of running commands for autonomous mode.

Example Usage with TimedRobot:

class Robot extends TimedRobot {
@Override
public void autonomousInit() {
Scheduler.getDefault().schedule(myAutonomousCommand());
}
}

Example OpMode usage:

@Autonomous
class MyAutoOpMode extends PeriodicOpMode {
@Override
public void start() {
Scheduler.getDefault().schedule(myAutonomousCommand());
}
}