Controllers & Inputs
Overview
Controllers (gamepads/joysticks) allow drivers to operate the robot. WPILib supports Xbox controllers, PS4 controllers, and generic joysticks. We will focus on the
XboxController class.Objectives
You will learn to:
- Initialize controllers.
- Read joystick axes and buttons.
- Control motors with input.
- Handle joystick deadband.
Setup
Create a controller instance by specifying its USB port (usually 0 for driver, 1 for operator).
Note: Connect controllers to the Driver Station computer, not the robot.
Note: Connect controllers to the Driver Station computer, not the robot.
Initialization
package frc.robot;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.XboxController;
public class Robot extends TimedRobot {
// Create controller on USB port 0 (driver station)
private XboxController m_driver = new XboxController(0);
}Reading Inputs
Axes (-1.0 to 1.0):
Triggers (0.0 to 1.0):
Buttons (boolean):
getLeftX(), getLeftY()getRightX(), getRightY()Triggers (0.0 to 1.0):
getLeftTriggerAxis(), getRightTriggerAxis()Buttons (boolean):
getAButton(), getBButton(), etc.Reading Values
// ... (rest of Robot class)
@Override
public void teleopPeriodic() {
// Read joystick Y-axis (-1.0 to 1.0, negative is forward)
double speed = m_driver.getLeftY();
// Read button state (true when pressed)
boolean isPressed = m_driver.getAButton();
}
// ... (rest of class)Tank Drive Example
Map left/right joysticks directly to left/right motors.
Tank Drive Code
Control motors with joysticks:
package frc.robot;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.XboxController;
import com.ctre.phoenix6.hardware.TalonFX;
import com.ctre.phoenix6.controls.DutyCycleOut;
public class Robot extends TimedRobot {
private TalonFX m_left = new TalonFX(1);
private TalonFX m_right = new TalonFX(2);
private DutyCycleOut m_out = new DutyCycleOut(0);
private XboxController m_driver = new XboxController(0);
@Override
public void teleopPeriodic() {
// Left joystick controls left motor, right joystick controls right motor
m_left.setControl(m_out.withOutput(m_driver.getLeftY()));
m_right.setControl(m_out.withOutput(m_driver.getRightY()));
}
}Button Control
Use buttons for discrete actions (e.g., run intake). Always include an
else block to stop the motor.Button Logic
// ... (rest of Robot class)
@Override
public void teleopPeriodic() {
// Button A: Run motor forward
if (m_driver.getAButton()) {
m_motor.set(0.6);
}
// Button B: Run motor reverse
else if (m_driver.getBButton()) {
m_motor.set(-0.4);
}
// No button pressed: Stop motor
else {
m_motor.set(0.0);
}
}
// ... (rest of class)Deadband
Joysticks may not return exactly 0.0 when centered. Use
MathUtil.applyDeadband() to ignore small values.Deadband Example
// ... (rest of Robot class)
import edu.wpi.first.math.MathUtil;
@Override
public void teleopPeriodic() {
// Apply deadband: ignore values between -0.1 and 0.1
// This prevents drift when joystick is centered
double speed = MathUtil.applyDeadband(m_driver.getLeftY(), 0.1);
m_motor.set(speed);
}
// ... (rest of class)