1- package org .carlmontrobotics .lib199 ;
1+ package org .carlmontrobotics .lib199 . swerve ;
22
33import java .util .function .Supplier ;
44
1414import edu .wpi .first .math .geometry .Rotation2d ;
1515import edu .wpi .first .math .kinematics .SwerveModuleState ;
1616import edu .wpi .first .math .trajectory .TrapezoidProfile ;
17+ import edu .wpi .first .util .sendable .Sendable ;
18+ import edu .wpi .first .util .sendable .SendableBuilder ;
1719import edu .wpi .first .wpilibj .Timer ;
1820import edu .wpi .first .wpilibj .smartdashboard .SmartDashboard ;
1921
2022/**
2123 * A class that stores all the variables and methods applicaple to a single swerve module,
2224 * such as moving, getting encoder values, or configuring PID.
2325 */
24- public class SwerveModule {
26+ public class SwerveModule implements Sendable {
2527 public enum ModuleType {FL , FR , BL , BR };
2628
2729 private SwerveConfig config ;
2830 private ModuleType type ;
29- private String moduleString ;
3031 private CANSparkMax drive , turn ;
3132 private CANCoder turnEncoder ;
3233 private PIDController drivePIDController ;
3334 private ProfiledPIDController turnPIDController ;
3435 private TrapezoidProfile .Constraints turnConstraints ;
35- private double driveModifier , maxSpeed , turnZero ;
36+ private double driveModifier , turnZero ;
3637 private Supplier <Float > pitchDegSupplier , rollDegSupplier ;
3738 private boolean reversed ;
3839 private Timer timer ;
3940 private SimpleMotorFeedforward forwardSimpleMotorFF , backwardSimpleMotorFF , turnSimpleMotorFeedforward ;
40- private double lastAngle , maxAchievableTurnVelocityDps , maxAchievableTurnAccelerationMps2 , turnToleranceDeg ;
41+ private double lastAngle , maxAchievableTurnVelocityDps , maxAchievableTurnAccelerationMps2 , turnToleranceDeg , angleDiff ;
4142
4243 public SwerveModule (SwerveConfig config , ModuleType type , CANSparkMax drive , CANSparkMax turn , CANCoder turnEncoder , double driveModifier ,
43- double maxSpeed , int arrIndex , Supplier <Float > pitchDegSupplier , Supplier <Float > rollDegSupplier ) {
44+ int arrIndex , Supplier <Float > pitchDegSupplier , Supplier <Float > rollDegSupplier ) {
4445 //SmartDashboard.putNumber("Target Angle (deg)", 0.0);
4546 this .timer = new Timer ();
4647 timer .start ();
@@ -49,21 +50,6 @@ public SwerveModule(SwerveConfig config, ModuleType type, CANSparkMax drive, CAN
4950 this .type = type ;
5051 this .drive = drive ;
5152
52- switch (type ) {
53- case FL :
54- moduleString = "FL" ;
55- break ;
56- case FR :
57- moduleString = "FR" ;
58- break ;
59- case BL :
60- moduleString = "BL" ;
61- break ;
62- case BR :
63- moduleString = "BR" ;
64- break ;
65- }
66-
6753 double positionConstant = config .wheelDiameterMeters * Math .PI / config .driveGearing ;
6854 drive .setInverted (config .driveInversion [arrIndex ]);
6955 drive .getEncoder ().setPositionConversionFactor (positionConstant );
@@ -76,7 +62,7 @@ public SwerveModule(SwerveConfig config, ModuleType type, CANSparkMax drive, CAN
7662 final double neoFreeCurrentAmps = 1.3 ;
7763 final double neoStallCurrentAmps = 166 ;
7864 double currentLimitAmps = neoFreeCurrentAmps + 2 *motorTorqueLimitNewtonMeters / neoStallTorqueNewtonMeters * (neoStallCurrentAmps -neoFreeCurrentAmps );
79- SmartDashboard .putNumber (moduleString + " current limit (amps)" , currentLimitAmps );
65+ SmartDashboard .putNumber (type . toString () + " current limit (amps)" , currentLimitAmps );
8066 drive .setSmartCurrentLimit ((int )Math .min (50 , currentLimitAmps ));
8167
8268 this .forwardSimpleMotorFF = new SimpleMotorFeedforward (config .kForwardVolts [arrIndex ],
@@ -120,7 +106,6 @@ public SwerveModule(SwerveConfig config, ModuleType type, CANSparkMax drive, CAN
120106 this .turnEncoder .configAbsoluteSensorRange (AbsoluteSensorRange .Signed_PlusMinus180 );
121107
122108 this .driveModifier = driveModifier ;
123- this .maxSpeed = maxSpeed ;
124109 this .reversed = config .reversed [arrIndex ];
125110 this .turnZero = config .turnZero [arrIndex ];
126111
@@ -147,9 +132,8 @@ public void periodic() {
147132 turn .setVoltage (MathUtil .clamp (turnVolts , -12.0 , 12.0 ));
148133 } else {
149134 turn .setVoltage (turnSimpleMotorFeedforward .calculate (goal .velocity ));
150- }
135+ }
151136 prevTurnVelocity = state .velocity ;
152- SmartDashboard .putNumber (moduleString + " error (deg)" , turnPIDController .getPositionError ());
153137 }
154138
155139 /**
@@ -192,8 +176,6 @@ private void setSpeed(double speedMps) {
192176 // Compute desired and actual speeds in m/s
193177 double desiredSpeed = speedMps * driveModifier ;
194178 double actualSpeed = getCurrentSpeed ();
195- SmartDashboard .putNumber (moduleString + " Desired Speed (mps)" , desiredSpeed );
196- SmartDashboard .putNumber (moduleString + " Actual Speed (mps)" , actualSpeed );
197179 double targetVoltage = (actualSpeed >= 0 ? forwardSimpleMotorFF :
198180 backwardSimpleMotorFF ).calculate (desiredSpeed , calculateAntiGravitationalA (pitchDegSupplier .get (), rollDegSupplier .get ()));//clippedAcceleration);
199181
@@ -215,12 +197,12 @@ private void setAngle(double angle) {
215197 double maxDeltaTheta = Math .asin (deltaTime *config .autoCentripetalAccel /(Math .abs (getCurrentSpeed ())+0.0001 ));
216198 setMaxTurnVelocity (maxDeltaTheta *180 /Math .PI );
217199 //SmartDashboard.putNumber(moduleString + "Target Angle:", 360 * angle * (reversed ? -1 : 1));
218-
200+
219201 // Find the minimum distance to travel from lastAngle to angle and determine the
220202 // correct direction to trvel the minimum distance. This is used in order to accurately
221203 // calculate the goal velocity.
222- double angleDiff = MathUtil .inputModulus (angle - lastAngle , -180 , 180 );
223- SmartDashboard .putNumber (moduleString + " angleDiff (deg)" , angleDiff );
204+ angleDiff = MathUtil .inputModulus (angle - lastAngle , -180 , 180 );
205+ // SmartDashboard.putNumber(moduleString + " angleDiff (deg)", angleDiff);
224206
225207 turnPIDController .setGoal (new TrapezoidProfile .State (angle * (reversed ? -1 : 1 ), 0 ));
226208 lastAngle = angle ;
@@ -248,8 +230,12 @@ public double getCurrentSpeed() {
248230
249231 /**
250232 * Updates SmartDashboard with information about this module.
233+ *
234+ * @deprecated Put this Sendable to SmartDashboard instead
251235 */
236+ @ Deprecated
252237 public void updateSmartDashboard () {
238+ String moduleString = type .toString ();
253239 // Display the position of the quadrature encoder.
254240 SmartDashboard .putNumber (moduleString + " Incremental Position" , turnEncoder .getPosition ());
255241 // Display the position of the analog encoder.
@@ -268,7 +254,7 @@ public void updateSmartDashboard() {
268254 SmartDashboard .putNumber (moduleString + "Antigravitational Acceleration" , calculateAntiGravitationalA (pitchDegSupplier .get (), rollDegSupplier .get ()));
269255 SmartDashboard .putBoolean (moduleString + " Turn is at Goal" , turnPIDController .atGoal ());
270256 }
271-
257+
272258 public void toggleMode () {
273259 if (drive .getIdleMode () == IdleMode .kBrake && turn .getIdleMode () == IdleMode .kCoast ) coast ();
274260 else brake ();
@@ -288,4 +274,26 @@ public void setMaxTurnVelocity(double maxVel) {
288274 turnConstraints = new TrapezoidProfile .Constraints (maxVel , turnConstraints .maxAcceleration );
289275 turnPIDController .setConstraints (turnConstraints );
290276 }
291- }
277+
278+ @ Override
279+ public void initSendable (SendableBuilder builder ) {
280+ builder .setActuator (true );
281+ builder .setSafeState (() -> setSpeed (0 ));
282+ builder .setSmartDashboardType ("SwerveModule" );
283+ builder .addDoubleProperty ("Incremental Position" , turnEncoder ::getPosition , null );
284+ builder .addDoubleProperty ("Absolute Angle (deg)" , turnEncoder ::getAbsolutePosition , null );
285+ builder .addDoubleProperty ("Turn Measured Pos (deg)" , this ::getModuleAngle , null );
286+ builder .addDoubleProperty ("Encoder Position" , drive .getEncoder ()::getPosition , null );
287+ // Display the speed that the robot thinks it is travelling at.
288+ builder .addDoubleProperty ("Current Speed" , this ::getCurrentSpeed , null );
289+ builder .addDoubleProperty ("Turn Setpoint Pos (deg)" , () -> turnPIDController .getSetpoint ().position , null );
290+ builder .addDoubleProperty ("Turn Setpoint Vel (dps)" , () -> turnPIDController .getSetpoint ().velocity , null );
291+ builder .addDoubleProperty ("Turn Goal Pos (deg)" , () -> turnPIDController .getGoal ().position , null );
292+ builder .addDoubleProperty ("Turn Goal Vel (dps)" , () -> turnPIDController .getGoal ().velocity , null );
293+ builder .addDoubleProperty ("Antigravitational Acceleration" , () -> calculateAntiGravitationalA (pitchDegSupplier .get (), rollDegSupplier .get ()), null );
294+ builder .addBooleanProperty ("Turn is at Goal" , turnPIDController ::atGoal , null );
295+ builder .addDoubleProperty ("Error (deg)" , turnPIDController ::getPositionError , null );
296+ builder .addDoubleProperty ("Desired Speed (mps)" , drivePIDController ::getSetpoint , null );
297+ builder .addDoubleProperty ("Angle Diff (deg)" , () -> angleDiff , null );
298+ }
299+ }
0 commit comments