Unit 7: Advanced FRC Coding
The `SwerveDrivetrain` Subsystem
This subsystem is the final piece of our swerve drive puzzle. After building the individual `SwerveModule` class, we need a central hub to manage all four modules, handle odometry, and use kinematics to create cohesive robot movement.
Purpose of the `SwerveDrivetrain`
This class acts as the "brain" of the drivetrain. It orchestrates all the individual components, providing a simple interface for commands to use, like `drive()`, which abstracts away all the complex swerve logic.
Key Responsibilities
- Manage Modules: It creates and holds the four `SwerveModule` objects.
- Handle Kinematics: It uses the `SwerveDriveKinematics` object to translate a desired `ChassisSpeeds` into four individual `SwerveModuleState` objects.
- Update Odometry: In its `periodic()` method, it continuously updates the `SwerveDriveOdometry` with fresh sensor data from the modules and the gyro.
- Provide Robot Pose: It offers getter methods for commands and other systems to know the robot's current position on the field.
A Complete `SwerveDrivetrain` Subsystem Example
This code demonstrates how the `SwerveDrivetrain` subsystem brings everything together.
public class SwerveDrivetrain extends SubsystemBase {
// Gyro for heading
private final Gyro gyro;
// The four swerve modules
private final SwerveModule frontLeft, frontRight, backLeft, backRight;
// Kinematics and Odometry objects from WPILib
private final SwerveDriveKinematics kinematics;
private final SwerveDriveOdometry odometry;
public SwerveDrivetrain() {
// ... create gyro object ...
// Create the four module objects
frontLeft = new SwerveModule(...);
frontRight = new SwerveModule(...);
backLeft = new SwerveModule(...);
backRight = new SwerveModule(...);
// ... create kinematics object ...
// Create the odometry object, giving it the starting pose
odometry = new SwerveDriveOdometry(kinematics, gyro.getRotation2d(), getModulePositions(), new Pose2d());
}
// This is the main control method for the drivetrain
public void drive(ChassisSpeeds chassisSpeeds) {
// Use kinematics to get the desired state for each module
SwerveModuleState[] moduleStates = kinematics.toSwerveModuleStates(chassisSpeeds);
// Send the desired state to each module
frontLeft.setDesiredState(moduleStates[0]);
frontRight.setDesiredState(moduleStates[1]);
backLeft.setDesiredState(moduleStates[2]);
backRight.setDesiredState(moduleStates[3]);
}
// This method is called every 20ms
@Override
public void periodic() {
// Update the odometry with the latest sensor readings
odometry.update(gyro.getRotation2d(), getModulePositions());
}
public Pose2d getPose() {
return odometry.getPoseMeters();
}
}
Test Your Knowledge
Question: In which method of the `SwerveDrivetrain` subsystem is the robot's odometry (its estimated position on the field) continuously updated?