Class SwerveModule<DriveMotorType extends edu.wpi.first.wpilibj.motorcontrol.MotorController,AngleMotorType extends edu.wpi.first.wpilibj.motorcontrol.MotorController,AbsoluteEncoderType>
- java.lang.Object
-
- frc.robot.subsystems.swervedrive.swerve.SwerveModule<DriveMotorType,AngleMotorType,AbsoluteEncoderType>
-
- Type Parameters:
DriveMotorType- Main motor type that drives the wheel.AngleMotorType- Motor that controls the angle of the wheel.AbsoluteEncoderType- Absolute encoder for the swerve drive module.
- All Implemented Interfaces:
edu.wpi.first.util.sendable.Sendable,edu.wpi.first.wpilibj.motorcontrol.MotorController,java.lang.AutoCloseable
public class SwerveModule<DriveMotorType extends edu.wpi.first.wpilibj.motorcontrol.MotorController,AngleMotorType extends edu.wpi.first.wpilibj.motorcontrol.MotorController,AbsoluteEncoderType> extends java.lang.Object implements edu.wpi.first.wpilibj.motorcontrol.MotorController, edu.wpi.first.util.sendable.Sendable, java.lang.AutoCloseableSwerve module for representing a single swerve module of the robot.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classSwerveModule.SwerveModuleLocationSwerve Module location on the robot.static classSwerveModule.VerbosityVerbosity levels for data publishing,
-
Field Summary
Fields Modifier and Type Field Description private SwerveEncoder<?>absoluteEncoderAbsolute encoder for the swerve module.doubleangleOffsetAngle offset of the CANCoder at initialization.private edu.wpi.first.math.controller.SimpleMotorFeedforwarddriveFeedforwardDrive feedforward for PID when driving by velocity.SwerveMotordriveMotorMotor Controllers for drive motor of the swerve module.private doubledrivePowerPower to drive motor from -1 to 1.private doubledriveTrainWidthThe Distance between centers of right and left wheels in meters.private booleaninvertedDriveInverted drive motor.private booleaninvertedTurnInverted turning motor.doublemaxDriveSpeedMPSMaximum speed in meters per second, used to eliminate unnecessary movement of the module.private edu.wpi.first.wpilibj.shuffleboard.ShuffleboardTabmoduleTabprivate java.util.HashMap<java.lang.String,edu.wpi.first.wpilibj.shuffleboard.SimpleWidget>NT4Entriesprivate doublesteeringKVkV for steering feedforward.private SwerveModule.SwerveModuleLocationswerveLocationEnum representing the swerve module's location on the robot, assuming square.edu.wpi.first.math.geometry.Translation2dswerveModuleLocationSwerve Module location object relative to the center of the robot.private doubletargetAngleStore the last angle for optimization.private doubletargetAngularVelocityRPSAngular velocity in radians per second.private doubletargetVelocityTarget velocity for the swerve module.SwerveMotorturningMotorMotor Controller for the turning motor of the swerve drive module.private doublewheelBaseThe Distance between front and back wheels of the robot in meters.
-
Constructor Summary
Constructors Constructor Description SwerveModule(DriveMotorType mainMotor, AngleMotorType angleMotor, AbsoluteEncoderType encoder, SwerveModule.SwerveModuleLocation swervePosition, double driveGearRatio, double steerGearRatio, double steeringOffsetDegrees, double wheelDiameterMeters, double wheelBaseMeters, double driveTrainWidthMeters, double steeringMotorFreeSpeedRPM, double maxSpeedMPS, double maxDriveAcceleration, double drivingPowerLimit, double steeringPowerLimit, boolean steeringInverted, boolean drivingInverted)Swerve module constructor.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description booleanactiveCAN()Check that the link is good on the swerve module and CAN bus is able to retrieve data.private edu.wpi.first.wpilibj.shuffleboard.SimpleWidgetaddEntry(java.lang.String name, java.lang.Object defaultValue)Create a widget and add the entry to the hashmap of entries for network tables.voidclose()Closes this resource, relinquishing any underlying resources.voiddisable()Disable the motor controller.doubleget()Common interface for getting the current set speed of a motor controller.booleangetInverted()Common interface for returning if a motor controller is in the inverted state or not.edu.wpi.first.math.kinematics.SwerveModulePositiongetPosition()Get the swerve module position based off the sensors.SwerveModuleState2getState()Get the module state.private edu.wpi.first.math.geometry.Translation2dgetSwerveModulePosition(SwerveModule.SwerveModuleLocation swerveLocation)Get the swerve module position inTranslation2dfrom the enum passed.voidinitSendable(edu.wpi.first.util.sendable.SendableBuilder builder)Initializes thisSendableobject.voidpublish(SwerveModule.Verbosity level)Publish data to the smart dashboard relating to this swerve module.booleanremoteIntegratedEncoder()Checks if the absolute encoder is able to be read directly by the motor controller instead of using the synchronizeEncoder() function periodically.voidresetEncoders()Reset the REV encoders onboard the SparkMax's to 0, and set's the drive motor to position to 0 and synchronizes the internal steering encoders with the absolute encoder.voidset(double speed)Common interface for setting the speed of a motor controller.private voidsetAngle(double angle)Set the angle of the swerve module without feedforward.voidsetAngle(double angle, double feedforward)Set the angle of the swerve module.voidsetAngleOffset(double offset)Configure the magnetic offset in the CANCoder.voidsetCurrentLimit(int currentLimit, SwerveMotor.ModuleMotorType type)Set the current limit for the swerve drive motor, remember this may cause jumping if used in conjunction with voltage compensation.voidsetInverted(boolean isInverted)Common interface for inverting direction of a motor controller.voidsetInvertedAbsoluteEncoder(boolean isInverted)Invert the absolute encoder.voidsetInvertedTurn(boolean isInverted)Set the steering motor to be inverted.voidsetPIDF(double p, double i, double d, double f, double integralZone, SwerveMotor.ModuleMotorType moduleMotorType)Set the PIDF coefficients for the closed loop PID onboard the motor controller.voidsetState(SwerveModuleState2 state)Set the module speed and angle based off the module state.voidsetVelocity(double velocity)Set the drive motor velocity in MPS.voidsetVoltageCompensation(double nominalVoltage)Set the voltage compensation for the swerve module motor.voidstopMotor()Stops motor movement.voidsubscribe()Subscribe from data within smart dashboard to make changes to the swerve module.static java.lang.StringSwerveModuleLocationToString(SwerveModule.SwerveModuleLocation swerveLocation)ConvertSwerveModule.SwerveModuleLocationtoStringrepresentation.voidsynchronizeSteeringEncoder()Synchronizes the internal encoder for the steering motor with the value from the absolute encoder.
-
-
-
Field Detail
-
swerveModuleLocation
public final edu.wpi.first.math.geometry.Translation2d swerveModuleLocation
Swerve Module location object relative to the center of the robot.
-
driveMotor
public final SwerveMotor driveMotor
Motor Controllers for drive motor of the swerve module.
-
turningMotor
public final SwerveMotor turningMotor
Motor Controller for the turning motor of the swerve drive module.
-
swerveLocation
private final SwerveModule.SwerveModuleLocation swerveLocation
Enum representing the swerve module's location on the robot, assuming square.
-
absoluteEncoder
private final SwerveEncoder<?> absoluteEncoder
Absolute encoder for the swerve module.
-
driveTrainWidth
private final double driveTrainWidth
The Distance between centers of right and left wheels in meters.
-
wheelBase
private final double wheelBase
The Distance between front and back wheels of the robot in meters.
-
driveFeedforward
private final edu.wpi.first.math.controller.SimpleMotorFeedforward driveFeedforward
Drive feedforward for PID when driving by velocity.
-
steeringKV
private final double steeringKV
kV for steering feedforward.
-
moduleTab
private final edu.wpi.first.wpilibj.shuffleboard.ShuffleboardTab moduleTab
-
NT4Entries
private final java.util.HashMap<java.lang.String,edu.wpi.first.wpilibj.shuffleboard.SimpleWidget> NT4Entries
-
angleOffset
public double angleOffset
Angle offset of the CANCoder at initialization.
-
maxDriveSpeedMPS
public double maxDriveSpeedMPS
Maximum speed in meters per second, used to eliminate unnecessary movement of the module.
-
invertedDrive
private boolean invertedDrive
Inverted drive motor.
-
invertedTurn
private boolean invertedTurn
Inverted turning motor.
-
drivePower
private double drivePower
Power to drive motor from -1 to 1.
-
targetAngle
private double targetAngle
Store the last angle for optimization.
-
targetAngularVelocityRPS
private double targetAngularVelocityRPS
Angular velocity in radians per second.
-
targetVelocity
private double targetVelocity
Target velocity for the swerve module.
-
-
Constructor Detail
-
SwerveModule
public SwerveModule(DriveMotorType mainMotor, AngleMotorType angleMotor, AbsoluteEncoderType encoder, SwerveModule.SwerveModuleLocation swervePosition, double driveGearRatio, double steerGearRatio, double steeringOffsetDegrees, double wheelDiameterMeters, double wheelBaseMeters, double driveTrainWidthMeters, double steeringMotorFreeSpeedRPM, double maxSpeedMPS, double maxDriveAcceleration, double drivingPowerLimit, double steeringPowerLimit, boolean steeringInverted, boolean drivingInverted)
Swerve module constructor. Both motors MUST be aMotorControllerclass. It is recommended to create a command to reset the encoders when triggered and- Parameters:
mainMotor- Main drive motor. Must be aMotorControllertype.angleMotor- Angle motor for controlling the angle of the swerve module.encoder- Absolute encoder for the swerve module.driveGearRatio- Drive gear ratio in form of (rotation:1 AKA rotations/1) to get the encoder ticks per rotation.steerGearRatio- Steering motor gear ratio (usually 12.8:1 for MK4 in form of rotations:1 or rotations/1), only applied if using Neo's.swervePosition- Swerve Module position on the robot.steeringOffsetDegrees- The current offset of the absolute encoder from 0 in degrees.wheelDiameterMeters- The wheel diameter of the swerve drive module in meters.wheelBaseMeters- The Distance between front and back wheels of the robot in meters.driveTrainWidthMeters- The Distance between centers of right and left wheels in meters.steeringMotorFreeSpeedRPM- The RPM free speed of the steering motor.maxSpeedMPS- The maximum drive speed in meters per second.maxDriveAcceleration- The maximum drive acceleration in meters^2 per second.drivingPowerLimit- The power limit for the closed loop PID of the driver motor.steeringPowerLimit- The power limit for the closed loop PID of the steering motor.steeringInverted- The steering motor is inverted.drivingInverted- The driving motor is inverted.- Throws:
java.lang.RuntimeException- if an assertion fails or invalid swerve module location is given.
-
-
Method Detail
-
SwerveModuleLocationToString
public static java.lang.String SwerveModuleLocationToString(SwerveModule.SwerveModuleLocation swerveLocation)
ConvertSwerveModule.SwerveModuleLocationtoStringrepresentation.- Parameters:
swerveLocation- Swerve position to convert.- Returns:
Stringname of theSwerveModule.SwerveModuleLocationenum.
-
resetEncoders
public void resetEncoders()
Reset the REV encoders onboard the SparkMax's to 0, and set's the drive motor to position to 0 and synchronizes the internal steering encoders with the absolute encoder.
-
synchronizeSteeringEncoder
public void synchronizeSteeringEncoder()
Synchronizes the internal encoder for the steering motor with the value from the absolute encoder.
-
setPIDF
public void setPIDF(double p, double i, double d, double f, double integralZone, SwerveMotor.ModuleMotorType moduleMotorType)Set the PIDF coefficients for the closed loop PID onboard the motor controller. Tuning the PIDP = .5 and increase it by .1 until oscillations occur, then decrease by .05 then .005 until oscillations stop and angle is perfect or near perfect.
I = 0 tune this if your PID never quite reaches the target, after tuning D. Increase this by P*.01 each time and adjust accordingly.
D = 0 tune this if the PID accelerates too fast, it will smooth the motion. Increase this by P*10 and adjust accordingly.
F = 0 tune this if the PID is being used for velocity, the F is multiplied by the target and added to the voltage output. Increase this by 0.01 until the PIDF reaches the desired state in a fast enough manner.
Documentation for this is best described by CTRE here.- Parameters:
p- Proportional gain for closed loop. This is multiplied by closed loop error in sensor units.i- Integral gain for closed loop. This is multiplied by closed loop error in sensor units every PID Loop.d- Derivative gain for closed loop. This is multiplied by derivative error (sensor units per PID loop).f- Feed Fwd gain for Closed loop.integralZone- Integral Zone can be used to auto clear the integral accumulator if the sensor pos is too far from the target. This prevents unstable oscillation if the kI is too large. Value is in sensor units.moduleMotorType- Swerve drive motor type.
-
setAngleOffset
public void setAngleOffset(double offset)
Configure the magnetic offset in the CANCoder.- Parameters:
offset- Magnetic offset in degrees.
-
activeCAN
public boolean activeCAN()
Check that the link is good on the swerve module and CAN bus is able to retrieve data.- Returns:
- true on all devices are accessible over CAN.
-
remoteIntegratedEncoder
public boolean remoteIntegratedEncoder()
Checks if the absolute encoder is able to be read directly by the motor controller instead of using the synchronizeEncoder() function periodically.- Returns:
- If the absolute sensor in the steering motor is directly accessed by the motor controller.
-
setAngle
public void setAngle(double angle, double feedforward)Set the angle of the swerve module.- Parameters:
angle- Angle in degrees.feedforward- The feedforward for the PID.
-
setAngle
private void setAngle(double angle)
Set the angle of the swerve module without feedforward.- Parameters:
angle- Angle in degrees.
-
setVelocity
public void setVelocity(double velocity)
Set the drive motor velocity in MPS.- Parameters:
velocity- Velocity in MPS.
-
getState
public SwerveModuleState2 getState()
Get the module state.- Returns:
- SwerveModuleState with the encoder inputs.
- Throws:
java.lang.RuntimeException- Exception if CANCoder doesnt exist
-
setState
public void setState(SwerveModuleState2 state)
Set the module speed and angle based off the module state.- Parameters:
state- Module state.
-
getPosition
public edu.wpi.first.math.kinematics.SwerveModulePosition getPosition()
Get the swerve module position based off the sensors.- Returns:
- Swerve Module position, with the angle as what the angle is supposed to be, not what it actually is.
-
subscribe
public void subscribe()
Subscribe from data within smart dashboard to make changes to the swerve module.
-
addEntry
private edu.wpi.first.wpilibj.shuffleboard.SimpleWidget addEntry(java.lang.String name, java.lang.Object defaultValue)Create a widget and add the entry to the hashmap of entries for network tables.- Parameters:
name- Key to display on shuffleboard.defaultValue- Default value.- Returns:
- Widget that can be modified.
-
publish
public void publish(SwerveModule.Verbosity level)
Publish data to the smart dashboard relating to this swerve module.- Parameters:
level- Verbosity level, affects the CAN utilization, on HIGH it will enable the update button.
-
initSendable
public void initSendable(edu.wpi.first.util.sendable.SendableBuilder builder)
Initializes thisSendableobject.- Specified by:
initSendablein interfaceedu.wpi.first.util.sendable.Sendable- Parameters:
builder- sendable builder
-
close
public void close()
Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by thetry-with-resources statement.While this interface method is declared to throw
Exception, implementers are strongly encouraged to declare concrete implementations of theclosemethod to throw more specific exceptions, or to throw no exception at all if the close operation cannot fail.Cases where the close operation may fail require careful attention by implementers. It is strongly advised to relinquish the underlying resources and to internally mark the resource as closed, prior to throwing the exception. The
closemethod is unlikely to be invoked more than once and so this ensures that the resources are released in a timely manner. Furthermore it reduces problems that could arise when the resource wraps, or is wrapped, by another resource.Implementers of this interface are also strongly advised to not have the
closemethod throwInterruptedException.This exception interacts with a thread's interrupted status, and runtime misbehavior is likely to occur if an
InterruptedExceptionis suppressed.More generally, if it would cause problems for an exception to be suppressed, the
AutoCloseable.closemethod should not throw it.Note that unlike the
closemethod ofCloseable, thisclosemethod is not required to be idempotent. In other words, calling thisclosemethod more than once may have some visible side effect, unlikeCloseable.closewhich is required to have no effect if called more than once.However, implementers of this interface are strongly encouraged to make their
closemethods idempotent.- Specified by:
closein interfacejava.lang.AutoCloseable
-
disable
public void disable()
Disable the motor controller.- Specified by:
disablein interfaceedu.wpi.first.wpilibj.motorcontrol.MotorController
-
stopMotor
public void stopMotor()
Stops motor movement. Motor can be moved again by calling set without having to re-enable the motor.- Specified by:
stopMotorin interfaceedu.wpi.first.wpilibj.motorcontrol.MotorController
-
set
public void set(double speed)
Common interface for setting the speed of a motor controller.- Specified by:
setin interfaceedu.wpi.first.wpilibj.motorcontrol.MotorController- Parameters:
speed- The speed to set. Value should be between -1.0 and 1.0.
-
get
public double get()
Common interface for getting the current set speed of a motor controller.- Specified by:
getin interfaceedu.wpi.first.wpilibj.motorcontrol.MotorController- Returns:
- The current set speed. Value is between -1.0 and 1.0.
-
getSwerveModulePosition
private edu.wpi.first.math.geometry.Translation2d getSwerveModulePosition(SwerveModule.SwerveModuleLocation swerveLocation)
Get the swerve module position inTranslation2dfrom the enum passed.- Parameters:
swerveLocation- Swerve module location enum.- Returns:
- Location as
Translation2d. - Throws:
java.lang.RuntimeException- If Enum value is not defined.
-
setVoltageCompensation
public void setVoltageCompensation(double nominalVoltage)
Set the voltage compensation for the swerve module motor.- Parameters:
nominalVoltage- Nominal voltage for operation to output to.
-
setCurrentLimit
public void setCurrentLimit(int currentLimit, SwerveMotor.ModuleMotorType type)Set the current limit for the swerve drive motor, remember this may cause jumping if used in conjunction with voltage compensation. This is useful to protect the motor from current spikes.- Parameters:
currentLimit- Current limit in AMPS at free speed.type- Swerve Drive Motor type to configure.
-
setInvertedTurn
public void setInvertedTurn(boolean isInverted)
Set the steering motor to be inverted.- Parameters:
isInverted- The state of inversion, true is inverted.
-
setInvertedAbsoluteEncoder
public void setInvertedAbsoluteEncoder(boolean isInverted)
Invert the absolute encoder.- Parameters:
isInverted- The state of inversion, true is inverted.
-
getInverted
public boolean getInverted()
Common interface for returning if a motor controller is in the inverted state or not.- Specified by:
getInvertedin interfaceedu.wpi.first.wpilibj.motorcontrol.MotorController- Returns:
- isInverted The state of the inversion true is inverted.
-
setInverted
public void setInverted(boolean isInverted)
Common interface for inverting direction of a motor controller.- Specified by:
setInvertedin interfaceedu.wpi.first.wpilibj.motorcontrol.MotorController- Parameters:
isInverted- The state of inversion, true is inverted.
-
-