- Required Robot: Testbed
This challenge introduces arcade drive control, a more intuitive driving method where one joystick axis controls forward/backward movement and another axis controls rotation. Arcade drive is often preferred by drivers because it mirrors the control scheme of many video games and vehicles, making it more natural to learn. Understanding arcade drive is essential for creating user-friendly robot controls and serves as a foundation for more advanced control schemes like field-oriented driving.
Create a drivetrain subsystem that uses arcade drive control where the left joystick Y-axis controls forward/backward movement and the right joystick X-axis controls rotation. The robot should move forward/backward while simultaneously turning left/right based on the combined joystick inputs. The drivetrain should respond smoothly and predictably to driver input.
- Motors:
- Front Left Motor: TalonSRX (CAN ID: 20)
- Back Left Motor: VictorSPX (CAN ID: 21)
- Front Right Motor: TalonSRX (CAN ID: 22)
- Back Right Motor: VictorSPX (CAN ID: 23)
- Controller: Xbox Controller (Port: 0)
- Motor Configuration:
- Neutral Mode: Brake
- Right Side Inverted: True
- Voltage Compensation: 12V
- Open Loop Ramp: 0.2 seconds
- Create a new Drivetrain subsystem class that extends SubsystemBase
- Initialize motor controllers and configure them with proper settings
- Create MotorControllerGroup instances for left and right sides
- Initialize a DifferentialDrive object using the motor controller groups
- Create a method to accept speed and rotation values for arcade drive
- Create a default command that reads joystick input and calls the arcade drive method
- Configure controller bindings in RobotContainer
- Add telemetry to display motor outputs on SmartDashboard
- Robot drives forward when left joystick is pushed forward
- Robot drives backward when left joystick is pulled backward
- Robot turns left when right joystick is pushed left
- Robot turns right when right joystick is pushed right
- Robot can drive forward/backward and turn simultaneously
- Response is smooth and proportional to joystick positions
- Motors stop when joysticks are in center position
- Telemetry data shows individual motor outputs
- For Step 1: Create
DrivetrainSubsystem.javain the subsystems package. Usepublic class DrivetrainSubsystem extends SubsystemBase { ... }. Importedu.wpi.first.wpilibj2.command.SubsystemBase. - For Step 2: Use
WPI_TalonSRXandWPI_VictorSPXclasses. Example:private final WPI_TalonSRX frontLeft = new WPI_TalonSRX(20);. Configure each motor in the constructor withsetNeutralMode(NeutralMode.Brake),configVoltageCompSaturation(12), andenableVoltageCompensation(true). - For Step 3: Create groups using
MotorControllerGroup leftMotors = new MotorControllerGroup(frontLeft, backLeft);. Importedu.wpi.first.wpilibj.motorcontrol.MotorControllerGroup. - For Step 4: Initialize with
private final DifferentialDrive differentialDrive = new DifferentialDrive(leftMotors, rightMotors);. Importedu.wpi.first.wpilibj.drive.DifferentialDrive. - For Step 5: Create a public method like
public void arcadeDrive(double speed, double rotation) { differentialDrive.arcadeDrive(speed, rotation); }. Consider adding safety features likedifferentialDrive.setSafetyEnabled(false);in the constructor. - For Step 6: Use
RunCommandfactory method:new RunCommand(() -> arcadeDrive(-driverController.getLeftY(), driverController.getRightX()), this). Note the negative sign for Y-axis inversion. - For Step 7: In RobotContainer.java, instantiate your drivetrain and set the default command in
configureDefaultCommands()method. - For Step 8: In the subsystem's
periodic()method, addSmartDashboard.putNumber("Left Motor Output", leftMotors.get())and similar for right motors. - Remember to apply deadbands using
MathUtil.applyDeadband()with a value around 0.1 to prevent drift. - If the robot turns in the opposite direction than expected, try negating the rotation input in your command.
- The DifferentialDrive class automatically handles the math to convert speed and rotation into individual wheel speeds.
- Squared Inputs: Modify the control to square the joystick inputs while preserving signs for more precise control around center position.
- Speed Limiting: Add a button or axis to limit the maximum drive speed (slow mode).
- Turn Rate Limiting: Add a separate speed limit for rotation that's different from forward/backward speed.
- Curvature Drive: Experiment with
curvatureDrive()instead ofarcadeDrive()for different driving characteristics. - Quick Turn: Add a button that enables quick turn mode when using curvature drive.
- Ramping Control: Add custom ramping to smooth acceleration and deceleration beyond the motor controller's built-in ramp.
- Heading Hold: Use an IMU to maintain the robot's heading when the rotation joystick is centered.
- Drive Characterization: Implement simple drive characterization to measure and display kS, kV, and kA values.
- WPILib Documentation: Differential Drive Kinematics
- WPILib Documentation: DifferentialDrive Class
- CTRE TalonSRX Documentation
- CTRE VictorSPX Documentation
- WPILib Documentation: Command-Based Programming
- FRC Programming Done Right: Drivetrain
- GitHub Example: Differential Drive Bot
- Team 364 BaseTalonBot Example
- Chief Delphi: Drive Train Discussion