Reading Joysticks and Binding Triggers
Read gamepads with CommandXboxController and bind buttons to commands using Triggers (onTrue, whileTrue).
Sign in to track progress, earn XP, and save lessons.
Controllers in FRC
Drivers use gamepads or joysticks plugged into the Driver Station. WPILib reads them through controller classes. The XboxController class works with the Xbox 360, Xbox One/Series controllers, and the Logitech F310 when its switch is set to XInput ("X") mode — these are the most common FRC controllers.
For command-based code, use CommandXboxController, which adds convenient button "trigger" methods.
Reading axes and buttons (raw)
XboxController driver = new XboxController(0); // DS USB slot 0
double forward = -driver.getLeftY(); // sticks are inverted: up is negative
double turn = driver.getRightX();
boolean shoot = driver.getAButton();
Joystick axes range from -1.0 to 1.0. A common gotcha: the Y axis is negative when pushed forward, so you usually negate it.
Triggers: the command-based way
A Trigger represents a boolean condition (a button press, a sensor state, anything). You bind commands to triggers in a method usually called configureBindings() inside RobotContainer:
CommandXboxController driver = new CommandXboxController(0);
// Run the intake WHILE the A button is held; stop when released
driver.a().whileTrue(intake.intakeCommand());
// Run a command ONCE when the right bumper is pressed
driver.rightBumper().onTrue(arm.raiseToScore());
// Combine conditions
driver.a().and(driver.b()).onTrue(robot.specialMode());
Key binding methods:
onTrue(cmd)— schedule the command when the trigger becomes true (rising edge).whileTrue(cmd)— run while the trigger is true; interrupt when it goes false.onFalse(cmd)/toggleOnTrue(cmd)— other edge behaviors.
Because CommandXboxController has named methods (a(), b(), leftBumper(), povUp(), etc.), bindings read almost like English.
Triggers aren't just buttons
A Trigger can wrap any boolean supplier:
new Trigger(arm::atTarget).onTrue(Commands.runOnce(() -> led.setGreen()));
This is the declarative power of command-based: instead of polling if (...) every loop, you declare "when this becomes true, do that."
Driving with default commands + triggers
A typical teleop setup combines both ideas: the drivetrain's default command reads the sticks every loop, while triggers handle mechanism actions:
drivetrain.setDefaultCommand(
drivetrain.run(() -> drivetrain.arcadeDrive(-driver.getLeftY(), driver.getRightX())));
driver.a().whileTrue(intake.intakeCommand());
driver.b().onTrue(shooter.shoot());
Tip: deadbands
Real sticks rarely rest at exactly 0. Apply a deadband (MathUtil.applyDeadband(value, 0.1)) so small stick drift doesn't creep the robot.
Key takeaways
- Use XboxController (raw) or CommandXboxController (command-based) to read gamepads.
- Axes are -1.0 to 1.0; the Y axis is negative when pushed forward — usually negate it.
- Triggers bind commands to conditions: onTrue, whileTrue, onFalse, toggleOnTrue.
- A Trigger can wrap any boolean, not just buttons — enabling declarative reactions.
- Apply MathUtil.applyDeadband to stick inputs to ignore resting drift.
Lesson quiz
RequiredAnswer all 3 questions correctly to complete this lesson.
1.Using CommandXboxController, what does binding a command with whileTrue() do?
2.What is the value range of an axis read from getRawAxis() on a Joystick or XboxController?
3.In the modern command-based API, how do you obtain a Trigger for the A button on a CommandXboxController?
Answer every question to submit.