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.
01.Using CommandXboxController, what does binding a command with whileTrue() do?
02.What is the value range of a joystick or XboxController axis, such as getLeftY()?
03.In the modern command-based API, how do you obtain a Trigger for the A button on a CommandXboxController?
Answer every question to submit.
All 51 lessons in Programming, Controls & Sensors
- Not started:Mini-Project: A Closed-Loop Elevator with Motion Magic
- Not started:Mini-Project: A Velocity-Controlled Shooter on REVLib
- Not started:Mini-Project: A Teleop Swerve Drive Subsystem
- Not started:Mini-Project: An Autonomous Routine with PathPlanner
- Not started:Mini-Project: Vision-Aligned Scoring with Limelight
- Not started:State-Space Control and Kalman Filtering
- Not started:Log Replay Architecture with AdvantageKit
- Not started:Advanced Pose Estimation: Multi-Tag Fusion and Standard Deviations
- Not started:Robot Coordination, Alerts, and Operator Feedback
- Not started:Case Study: Hardening Software Before an Event