SwerveModule Class

The SwerveModule class initializes the swerve module on the robot. The method getState returns a new object of the SwerveModuleState class, allowing us to know the current state according to the linear speed of the throttle in meters per second and the degrees the encoder has rotated. The method setState gets the current heading of the drive and takes a SwerveModuleState object. The method will use a PID controller to turn the drive to the desired heading at a desired speed.

Note

For API specific issues, please see the WPILib API , CTRE API, and the REV Robotics API.

Constructor

 1// Initialize rotor & throttle motors
 2private WPI_TalonFX mRotor;
 3private WPI_TalonFX mThrottle;
 4
 5// Initialize rotor encoder
 6private WPI_CANCoder mRotorEncoder;
 7
 8// Initialize rotor PID controller
 9private PIDController mRotorPID;
10
11/**
12 * Construct new SwerveModule
13 *
14 * @param throttleID CAN ID of throttle motor
15 * @param rotorID CAN ID of rotor motor
16 * @param rotorEncoderID CAN ID of rotor encoder
17 * @param rotorOffsetAngleDeg rotor encoder offset
18 */
19public SwerveModule(int throttleID, int rotorID, int rotorEncoderID, double rotorOffsetAngleDeg)
20{
21    // Instantiate throttle motor
22    mThrottle = new WPI_TalonFX(throttleID);
23
24    // Instantiate rotor motor
25    mRotor = new WPI_TalonFX(rotorID);
26
27    // Instantiate rotor absolute encoder
28    mRotorEncoder = new WPI_CANCoder(rotorEncoderID);
29
30    // Reset all configuration
31    // (technically optional, but good practice in case there are old
32    // configurations that can mess with the code)
33    mThrottle.configFactoryDefault();
34    mRotor.configFactoryDefault();
35    mRotorEncoder.configFactoryDefault();
36
37    // Configures rotor motor according to previously defined constants
38    mRotor.setInverted(SwerveConstants.kRotorMotorInversion);
39    mRotor.configVoltageCompSaturation(Constants.kVoltageCompensation);
40    mRotor.enableVoltageCompensation(true);
41    mRotor.setNeutralMode(NeutralMode.Brake);
42
43    // Configures rotor encoder according to previously defined constants
44    mRotorEncoder.configAbsoluteSensorRange(AbsoluteSensorRange.Signed_PlusMinus180);
45    mRotorEncoder.configMagnetOffset(rotorOffsetAngleDeg);
46    mRotorEncoder.configSensorDirection(SwerveConstants.kRotorEncoderDirection);
47    mRotorEncoder.configSensorInitializationStrategy(
48        SensorInitializationStrategy.BootToAbsolutePosition
49    );
50
51    // Configures rotor PID controller according to previously defined constants
52    mRotorPID = new PIDController(
53        SwerveConstants.kRotor_kP,
54        SwerveConstants.kRotor_kI,
55        SwerveConstants.kRotor_kD
56    );
57
58    // Continuous input considers the min & max to be the same point and
59    // automatically calculates the shortest route to the setpoint
60    mRotorPID.enableContinuousInput(-180, 180);
61
62    // Configures throttle motor according to previously defined constants
63    mThrottle.configSelectedFeedbackSensor(FeedbackDevice.IntegratedSensor);
64    mThrottle.configVoltageCompSaturation(Constants.kVoltageCompensation);
65    mThrottle.enableVoltageCompensation(true);
66    mThrottle.setNeutralMode(NeutralMode.Brake);
67}

Warning

When using brushless motors, it is highly recommended to have liberal current limits to prevent damage to the motors. Checkout the CTRE and REV documentation for more information regarding current limits.

Methods

getState

Outputs the current state of the swerve module.

1public SwerveModuleState getState() {
2    double throttleVelocity =
3        mThrottle.getSelectedSensorVelocity() * SwerveConstants.kThrottleVelocityConversionFactor;
4
5    return new SwerveModuleState(
6        throttleVelocity,
7        Rotation2d.fromDegrees(mRotorEncoder.getAbsolutePosition())
8    );
9}

Return:

New SwerveModuleState representing the current throttle velocity and rotor angle.

getPosition

Outputs the current position of the swerve module.

1public SwerveModulePosition getPosition() {
2    double throttlePosition = mThrottle.getSelectedSensorPosition() * SwerveConstants.kThrottlePositionConversionFactor;
3
4    return new SwerveModulePosition(
5        throttlePosition,
6        Rotation2d.fromDegrees(mRotorEncoder.getAbsolutePosition())
7    );
8}

Return:

New SwerveModulePosition representing the current throttle position and rotor angle.

setState

Sets the state of the swerve module.

 1public void setState(SwerveModuleState state) {
 2    // Optimize the desired state so that the rotor doesn't have to spin more than
 3    // 90 degrees to get to the desired angle
 4    SwerveModuleState optimizedState = SwerveModuleState.optimize(state, getState().angle);
 5
 6    // Calculate rotor output using rotor PID controller by comparing the current
 7    // angle with the desired angle
 8    double rotorOutput = mRotorPID.calculate(
 9        getState().angle.getDegrees(),
10        optimizedState.angle.getDegrees()
11    );
12
13    mRotor.set(rotorOutput);
14    mThrottle.set(optimizedState.speedMetersPerSecond);
15}

Parameters:

  1. state - desired SwerveModuleState (angle & speed) of SwerveModule

Note

Check out the code we use in these docs on our Github!