Class SwerveDrive
- java.lang.Object
-
- edu.wpi.first.wpilibj.MotorSafety
-
- edu.wpi.first.wpilibj.drive.RobotDriveBase
-
- frc.robot.subsystems.swervedrive.swerve.SwerveDrive
-
- All Implemented Interfaces:
edu.wpi.first.util.sendable.Sendable,java.lang.AutoCloseable
public class SwerveDrive extends edu.wpi.first.wpilibj.drive.RobotDriveBase implements edu.wpi.first.util.sendable.Sendable, java.lang.AutoCloseableSwerveDrive base which is meant to be platform agnostic. This implementation expect second order kinematics because second order kinematics prevents the drift that builds up when using first order kinematics. As per this ChiefDelphi post
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classSwerveDrive.SwerveModuleConfig<DriveMotorType extends edu.wpi.first.wpilibj.motorcontrol.MotorController,SteeringMotorType extends edu.wpi.first.wpilibj.motorcontrol.MotorController,AbsoluteEncoder extends com.ctre.phoenix.sensors.CANCoder>Helper class for easier swerve module creation
-
Field Summary
Fields Modifier and Type Field Description private static intinstancesCount of SwerveModule instances created.private doublem_angleSwerveModule<?,?,?>m_backLeftBack left swerve driveSwerveModule<?,?,?>m_backRightBack right swerve drivedoublem_driverMaxAngularVelocityMaximum speed in meters per second.doublem_driverMaxSpeedMPSMaximum speed in meters per second.private edu.wpi.first.wpilibj.Timerm_driveTimerprivate edu.wpi.first.wpilibj.smartdashboard.Field2dm_fieldField2d displayed on shuffleboard with current position.SwerveModule<?,?,?>m_frontLeftFront left swerve driveSwerveModule<?,?,?>m_frontRightFront right swerve driveprivate booleanm_gyroInvertedInvert the gyro reading.doublem_physicalMaxSpeedMPSMaximum speed in meters per second.private com.ctre.phoenix.sensors.WPI_Pigeon2m_pigeonIMUPigeon 2.0 centered on the robot.private edu.wpi.first.math.kinematics.ChassisSpeedsm_prevChassisSpeedprivate SwerveDriveKinematics2m_swerveKinematicsSwerve drive kinematics.private edu.wpi.first.math.estimator.SwerveDrivePoseEstimatorm_swervePoseEstimatorSwerve drive pose estimator for attempting to figure out our current position.private doublem_timerPrevprivate edu.wpi.first.math.filter.SlewRateLimiterm_turningLimiterThe slew rate limiters to make control smooth.private edu.wpi.first.math.filter.SlewRateLimiterm_xLimiterThe slew rate limiters to make control smooth.private edu.wpi.first.math.filter.SlewRateLimiterm_yLimiterThe slew rate limiters to make control smooth.
-
Constructor Summary
Constructors Constructor Description SwerveDrive(SwerveModule<?,?,?> frontLeft, SwerveModule<?,?,?> frontRight, SwerveModule<?,?,?> backLeft, SwerveModule<?,?,?> backRight, com.ctre.phoenix.sensors.WPI_Pigeon2 pigeon, double driverMaxSpeedMetersPerSecond, double driverMaxAngularVelocityRadiansPerSecond, double driverMaxDriveAccelerationMetersPerSecond, double driverMaxAngularAccelerationRadiansPerSecond, double physicalMaxSpeedMPS, boolean gyroInverted, edu.wpi.first.math.geometry.Pose2d start)Constructor for Swerve Drive assuming modules have been created and configured with PIDF and conversions.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidclose()Closes this resource, relinquishing any underlying resources.voidconfigurePigeonIMU()Configure the PigeonIMU with factory default settings and a zeroed gyroscope.static SwerveModule<?,?,?>[]createModules(double driveGearRatio, double steerGearRatio, double wheelDiameterMeters, double wheelBaseMeters, double driveTrainWidthMeters, double steeringMotorFreeSpeedRPM, double maxSpeedMPS, double maxDriveAcceleration, boolean steeringMotorInverted, boolean drivingMotorInverted, SwerveDrive.SwerveModuleConfig<?,?,?>[] configs)Create swerve drive modulesvoiddrive(double forward, double strafe, double turn, boolean fieldRelative)Drive swerve based off controller input.java.lang.StringgetDescription()Get the description of the robot drive base.edu.wpi.first.math.geometry.Pose2dgetPose()Get the current Pose, used in autonomous.edu.wpi.first.math.kinematics.SwerveModulePosition[]getPositions()Get current swerve module positions in order.edu.wpi.first.math.geometry.Rotation2dgetRotation()Get the current robot rotation.SwerveModuleState2[]getStates()Get current swerve module states in order.voidinitSendable(edu.wpi.first.util.sendable.SendableBuilder builder)Initializes thisSendableobject.voidpublish(SwerveModule.Verbosity level)Publish data from the Swerve Modules to the dashboard.voidresetEncoders()Resets the drive encoders to currently read a position of 0.voidresetOdometry(edu.wpi.first.math.geometry.Pose2d pose)Reset the odometry given the position and using current rotation from the PigeonIMU 2.voidset(double forward, double strafe, double radianPerSecond, boolean fieldRelative)Swerve drive functionvoidsetGyroInverted(boolean isInverted)Invert the gyroscope reading.voidsetModuleStates(SwerveModuleState2[] states)Set the swerve module states given an array of states.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.voidsetVoltageCompensation()Enable voltage compensation to the current battery voltage on all modules.voidsetX()Sets the wheels into an X formation to prevent movement.voidstopMotor()Stop all running and turning motors.voidsubscribe()Update swerve module parameters based on data in the dashboard.voidsynchronizeEncoders()Synchronize internal steering encoders with the absolute encoder.edu.wpi.first.math.estimator.SwerveDrivePoseEstimatorupdate()Update the swerve drive odometry.voidzeroGyro()Set the current rotation of the gyroscope (pigeonIMU 2) to 0.voidzeroModules()Sets the speed to 0 and angle to 0 for all the swerve drive modules.-
Methods inherited from class edu.wpi.first.wpilibj.drive.RobotDriveBase
feedWatchdog, normalize, setDeadband, setMaxOutput
-
-
-
-
Field Detail
-
instances
private static int instances
Count of SwerveModule instances created.
-
m_frontLeft
public final SwerveModule<?,?,?> m_frontLeft
Front left swerve drive
-
m_backLeft
public final SwerveModule<?,?,?> m_backLeft
Back left swerve drive
-
m_frontRight
public final SwerveModule<?,?,?> m_frontRight
Front right swerve drive
-
m_backRight
public final SwerveModule<?,?,?> m_backRight
Back right swerve drive
-
m_driverMaxSpeedMPS
public final double m_driverMaxSpeedMPS
Maximum speed in meters per second.
-
m_driverMaxAngularVelocity
public final double m_driverMaxAngularVelocity
Maximum speed in meters per second.
-
m_physicalMaxSpeedMPS
public final double m_physicalMaxSpeedMPS
Maximum speed in meters per second.
-
m_swerveKinematics
private final SwerveDriveKinematics2 m_swerveKinematics
Swerve drive kinematics.
-
m_swervePoseEstimator
private final edu.wpi.first.math.estimator.SwerveDrivePoseEstimator m_swervePoseEstimator
Swerve drive pose estimator for attempting to figure out our current position.
-
m_pigeonIMU
private final com.ctre.phoenix.sensors.WPI_Pigeon2 m_pigeonIMU
Pigeon 2.0 centered on the robot.
-
m_field
private final edu.wpi.first.wpilibj.smartdashboard.Field2d m_field
Field2d displayed on shuffleboard with current position.
-
m_xLimiter
private final edu.wpi.first.math.filter.SlewRateLimiter m_xLimiter
The slew rate limiters to make control smooth.
-
m_yLimiter
private final edu.wpi.first.math.filter.SlewRateLimiter m_yLimiter
The slew rate limiters to make control smooth.
-
m_turningLimiter
private final edu.wpi.first.math.filter.SlewRateLimiter m_turningLimiter
The slew rate limiters to make control smooth.
-
m_driveTimer
private final edu.wpi.first.wpilibj.Timer m_driveTimer
-
m_gyroInverted
private boolean m_gyroInverted
Invert the gyro reading.
-
m_angle
private double m_angle
-
m_prevChassisSpeed
private edu.wpi.first.math.kinematics.ChassisSpeeds m_prevChassisSpeed
-
m_timerPrev
private double m_timerPrev
-
-
Constructor Detail
-
SwerveDrive
public SwerveDrive(SwerveModule<?,?,?> frontLeft, SwerveModule<?,?,?> frontRight, SwerveModule<?,?,?> backLeft, SwerveModule<?,?,?> backRight, com.ctre.phoenix.sensors.WPI_Pigeon2 pigeon, double driverMaxSpeedMetersPerSecond, double driverMaxAngularVelocityRadiansPerSecond, double driverMaxDriveAccelerationMetersPerSecond, double driverMaxAngularAccelerationRadiansPerSecond, double physicalMaxSpeedMPS, boolean gyroInverted, edu.wpi.first.math.geometry.Pose2d start)
Constructor for Swerve Drive assuming modules have been created and configured with PIDF and conversions.- Parameters:
frontLeft- Front left swerve module configured.backLeft- Back left swerve module.frontRight- Front right swerve module.backRight- Back right swerve modulepigeon- Pigeon IMU.driverMaxSpeedMetersPerSecond- Maximum speed for all modules to follow when in teleop.driverMaxAngularVelocityRadiansPerSecond- Maximum angular velocity for turning when using the drive function.driverMaxDriveAccelerationMetersPerSecond- Maximum acceleration in meters per second for the drive motors when in teleop for the slew rate limiter.driverMaxAngularAccelerationRadiansPerSecond- Maximum angular acceleration in meters per second for the steering motors when in teleop for the slew rate limiters.physicalMaxSpeedMPS- Maximum speed a module can go physically, used to desaturate wheel speeds.gyroInverted- Invert the gyroscope for the robot.start- The starting pose on the field.
-
-
Method Detail
-
setVoltageCompensation
public void setVoltageCompensation()
Enable voltage compensation to the current battery voltage on all modules.
-
createModules
public static SwerveModule<?,?,?>[] createModules(double driveGearRatio, double steerGearRatio, double wheelDiameterMeters, double wheelBaseMeters, double driveTrainWidthMeters, double steeringMotorFreeSpeedRPM, double maxSpeedMPS, double maxDriveAcceleration, boolean steeringMotorInverted, boolean drivingMotorInverted, SwerveDrive.SwerveModuleConfig<?,?,?>[] configs)
Create swerve drive modules- Parameters:
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.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.steeringMotorInverted- The steering motor is inverted.drivingMotorInverted- The driving motor is inverted.configs- The swerve module configuration classes for the swerve drive given.- Returns:
- Array of swerve modules in the order of front left, front right, back left, back right.
-
zeroModules
public void zeroModules()
Sets the speed to 0 and angle to 0 for all the swerve drive modules.
-
configurePigeonIMU
public void configurePigeonIMU()
Configure the PigeonIMU with factory default settings and a zeroed gyroscope.
-
update
public edu.wpi.first.math.estimator.SwerveDrivePoseEstimator update()
Update the swerve drive odometry.- Returns:
- Swerve drive odometry.
-
drive
public void drive(double forward, double strafe, double turn, boolean fieldRelative)Drive swerve based off controller input.- Parameters:
forward- The speed (-1 to 1) in which the Y axis should go.strafe- The speed (-1 to 1) in which the X axis should go.turn- The speed (-1 to 1) in which the robot should turn.fieldRelative- Whether or not to use field relative controls.
-
set
public void set(double forward, double strafe, double radianPerSecond, boolean fieldRelative)Swerve drive function- Parameters:
forward- forward meters per second, strafe facing left from alliance wallstrafe- strafe meters per second, forward away from alliance wallradianPerSecond- radians per secondfieldRelative- field relative
-
setModuleStates
public void setModuleStates(SwerveModuleState2[] states)
Set the swerve module states given an array of states. Normalize the wheel speeds to abide by maximum supplied- Parameters:
states- Module states in a specified order. [front left, front right, back left, back right]- Throws:
java.lang.RuntimeException- If the CANCoder is inaccessible or not configured.
-
setX
public void setX()
Sets the wheels into an X formation to prevent movement.
-
setGyroInverted
public void setGyroInverted(boolean isInverted)
Invert the gyroscope reading.- Parameters:
isInverted- Inversion of the gryoscope, true is inverted.
-
getRotation
public edu.wpi.first.math.geometry.Rotation2d getRotation()
Get the current robot rotation.- Returns:
Rotation2dof the robot.
-
getPose
public edu.wpi.first.math.geometry.Pose2d getPose()
Get the current Pose, used in autonomous.- Returns:
- Current pose based off odometry.
-
getPositions
public edu.wpi.first.math.kinematics.SwerveModulePosition[] getPositions()
Get current swerve module positions in order.- Returns:
- Swerve module positions array.
-
getStates
public SwerveModuleState2[] getStates()
Get current swerve module states in order.- Returns:
- Swerve module states array.
-
resetOdometry
public void resetOdometry(edu.wpi.first.math.geometry.Pose2d pose)
Reset the odometry given the position and using current rotation from the PigeonIMU 2.- Parameters:
pose- Current position on the field.
-
resetEncoders
public void resetEncoders()
Resets the drive encoders to currently read a position of 0.
-
zeroGyro
public void zeroGyro()
Set the current rotation of the gyroscope (pigeonIMU 2) to 0.
-
stopMotor
public void stopMotor()
Stop all running and turning motors.- Specified by:
stopMotorin classedu.wpi.first.wpilibj.drive.RobotDriveBase
-
subscribe
public void subscribe()
Update swerve module parameters based on data in the dashboard.
-
publish
public void publish(SwerveModule.Verbosity level)
Publish data from the Swerve Modules to the dashboard.- Parameters:
level- Verbosity level in terms of CAN utilization.
-
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.
-
synchronizeEncoders
public void synchronizeEncoders()
Synchronize internal steering encoders with the absolute encoder.
-
getDescription
public java.lang.String getDescription()
Get the description of the robot drive base.- Specified by:
getDescriptionin classedu.wpi.first.wpilibj.drive.RobotDriveBase- Returns:
- string of the RobotDriveBase
-
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() throws java.lang.ExceptionCloses 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- Throws:
java.lang.Exception- if this resource cannot be closed
-
-