A control scheme is doing its job when the driver stops noticing it. They think "go there" and the robot goes there. The scheme below is WPILib command-based Java, written for an actual competition driver.
Start in RobotContainer with a CommandXboxController on port 0. WPILib gives you named factory methods for every button, so you bind declaratively instead of polling in a loop.
private final CommandXboxController driver = new CommandXboxController(0);
private final DriveSubsystem drive = new DriveSubsystem();
private void configureBindings() {
// Default command: field-relative joystick drive every loop
drive.setDefaultCommand(drive.run(() -> drive.driveFieldRelative(
-driver.getLeftY(), // forward (Y is inverted on Xbox sticks)
-driver.getLeftX(), // strafe
-driver.getRightX() // rotation
)));
// Reset field-relative heading to "away from driver station"
driver.start().onTrue(drive.runOnce(drive::zeroHeading));
// Hold left bumper for precision/slow mode
driver.leftBumper().whileTrue(drive.run(() -> drive.driveFieldRelative(
-driver.getLeftY() * 0.35,
-driver.getLeftX() * 0.35,
-driver.getRightX() * 0.35)));
}
Those minus signs matter. Xbox sticks report +1 when pulled toward the driver, so forward needs a negative sign, and forgetting it is the single most common day-one bug.
onTrue and whileTrue are the two binding methods you will use most. onTrue runs once on a rising edge, which is what a gyro reset needs. whileTrue runs while the button is held and cancels on release, which is what slow mode needs.
Slow mode here is a scale factor rather than a separate command tree. Multiplying the inputs by 0.35 gives about one-third speed for lining up on the HUB or playing careful defense, and you don't have to duplicate any logic.
Apply a deadband so a drifting stick doesn't creep the robot. MathUtil.applyDeadband(value, 0.1) is the idiomatic call. The DifferentialDrive class already applies 0.02 internally, but in swerve code you apply your own, and 0.05 to 0.10 is typical.
double x = MathUtil.applyDeadband(-driver.getLeftX(), 0.1);
Write the physical mapping down and tape it to the operator console: Left stick = translate, Right stick = rotate, Start = reset gyro, Left bumper = slow. Hand that card to a substitute driver and they should be able to drive a qualification match cold.
Test it on blocks first, then on the practice field. Drive a figure-eight around two cones. If the robot tracks where you point in field-relative mode no matter which way the bumper is facing, your gyro and inversions are correct.
the part worth keeping
Key takeaways
- Use CommandXboxController factory methods (start(), leftBumper()) with onTrue for one-shot actions and whileTrue for held actions.
- Invert Xbox Y axes for forward, and apply your own deadband (0.05-0.10) on swerve before scaling for slow mode.
- Document the physical button map on a card at the operator console so any driver can run a match.
Drive TeamWorked Examples & Mini-Projectslesson 1 of 5
Keep going
Take the quiz+10 XP with an accountMore in Worked Examples & Mini-Projects
where this came from
Sources and corrections
This lesson is AI-assisted: drafted from primary sources, then reviewed and edited by hand. Errors still get through. When one is reported we fix it and write down what changed, in public, in the corrections log.
sources and further reading
- docs.wpilib.orgWPILib: Binding Commands to Triggers
- docs.wpilib.orgWPILib: Joystick & Controller Input
clipped to this lesson
Articles that go further on this
The lesson gets you through the topic. These go wider on it, and they read in one sitting.
- 13 min readFRC Code Structure Best Practices: Command-Based Project ArchitectureHow to structure an FRC command-based robot project the right way — subsystems, commands, RobotContainer, and Constants — verified against official WPILib docs./blogread it
- 20 min readHow to Program FRC Swerve Drive with WPILibA practical guide to programming FRC swerve drive with WPILib: kinematics, SwerveModuleState, field-relative control, odometry, and where PathPlanner fits./blogread it
- 15 min readFRC Odometry and Pose Estimation: Field-Centric Control with WPILibHow an FRC robot tracks its field position with WPILib: wheel odometry vs pose estimation, gyro heading, fusing AprilTag vision, and field-centric driving./blogread it
answer sheet
Lesson quiz
All 4 right completes the lesson. Miss one and only that question comes back, anything you already answered correctly stays banked.
0 of 4 answered
01How is the gyro/heading reset typically wired to the controller in an FRC driver control scheme?
02Why does a production driver-control scheme apply a joystick deadband?
03How is precision/slow mode typically implemented when the left bumper is held?
04Why is the Xbox controller's Y axis negated when commanding forward drive?
Answer every question to submit.
All 34 lessons in Drive Teamopenclose
01 / prerequisites
02 / the-drive-team-and-its-roles
03 / driver-station-and-controls
04 / driver-practice-and-match-performance
05 / the-pit-and-match-turnaround
06 / worked-examples-mini-projects
- Not read yet:Project 1: A Production-Ready Driver Control Scheme
- Not read yet:Project 2: A Drivetrain That Survives a Whole Match
- Not read yet:Project 3: Build a Paper + Spreadsheet Scouting System
- Not read yet:Project 4: Pull Live OPR & EPA Data with Python
- Not read yet:Project 5: The One-Page Pre-Match Strategy Brief
07 / common-mistakes-troubleshooting
08 / advanced-strategy-case-studies