Skip to content

Commit 5ca6adb

Browse files
committed
make swerve and SparkVelocityPIDController Sendables
1 parent 3fb1b3c commit 5ca6adb

3 files changed

Lines changed: 71 additions & 67 deletions

File tree

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package org.carlmontrobotics.lib199;
22

33
import com.revrobotics.CANSparkMax;
4+
import com.revrobotics.CANSparkMax.ControlType;
45
import com.revrobotics.RelativeEncoder;
56
import com.revrobotics.SparkMaxPIDController;
6-
import com.revrobotics.CANSparkMax.ControlType;
77

8-
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
8+
import edu.wpi.first.util.sendable.Sendable;
9+
import edu.wpi.first.util.sendable.SendableBuilder;
910

10-
public class SparkVelocityPIDController {
11+
public class SparkVelocityPIDController implements Sendable {
1112

13+
@SuppressWarnings("unused")
1214
private final CANSparkMax spark;
1315
private final SparkMaxPIDController pidController;
1416
private final RelativeEncoder encoder;
@@ -29,38 +31,9 @@ public SparkVelocityPIDController(String name, CANSparkMax spark, double default
2931
this.kS = kS;
3032
this.kV = kV;
3133

32-
SmartDashboard.putNumber(name + ": P", currentP);
33-
SmartDashboard.putNumber(name + ": I", currentI);
34-
SmartDashboard.putNumber(name + ": D", currentD);
35-
SmartDashboard.putNumber(name + ": Target Speed", targetSpeed);
36-
SmartDashboard.putNumber(name + ": Tolerance", tolerance);
37-
3834
pidController.setReference(targetSpeed, ControlType.kVelocity, 0, calculateFF(targetSpeed));
3935
}
4036

41-
public void periodic() {
42-
double p = SmartDashboard.getNumber(name + ": P", currentP);
43-
double i = SmartDashboard.getNumber(name + ": I", currentI);
44-
double d = SmartDashboard.getNumber(name + ": D", currentD);
45-
46-
if(p != currentP) {
47-
pidController.setP(p);
48-
currentP = p;
49-
}
50-
if(i != currentI) {
51-
pidController.setI(i);
52-
currentI = i;
53-
}
54-
if(d != currentD) {
55-
pidController.setD(d);
56-
currentD = d;
57-
}
58-
59-
setTargetSpeed(SmartDashboard.getNumber(name + ": Target Speed", targetSpeed));
60-
setTolerance(SmartDashboard.getNumber(name + ": Tolerance", tolerance));
61-
SmartDashboard.putNumber(name + ": Current Speed", encoder.getVelocity());
62-
}
63-
6437
public RelativeEncoder getEncoder() {
6538
return encoder;
6639
}
@@ -79,7 +52,6 @@ public double getTargetSpeed() {
7952

8053
public void setTargetSpeed(double targetSpeed) {
8154
if(targetSpeed == this.targetSpeed) return;
82-
SmartDashboard.putNumber(name + ": Target Speed", targetSpeed);
8355
this.targetSpeed = targetSpeed;
8456
pidController.setReference(targetSpeed, ControlType.kVelocity, 0, calculateFF(targetSpeed));
8557
}
@@ -89,12 +61,36 @@ public double getTolerance() {
8961
}
9062

9163
public void setTolerance(double tolerance) {
92-
SmartDashboard.putNumber(name + ": Tolerance", tolerance);
9364
this.tolerance = tolerance;
9465
}
9566

9667
public double calculateFF(double velocity) {
9768
return kS * Math.signum(velocity) + kV * velocity;
9869
}
9970

71+
@Override
72+
public void initSendable(SendableBuilder builder) {
73+
builder.setActuator(true);
74+
builder.setSmartDashboardType("SparkVelocityPIDController");
75+
builder.addDoubleProperty("P", () -> currentP, p -> {
76+
pidController.setP(p);
77+
currentP = p;
78+
});
79+
builder.addDoubleProperty("I", () -> currentI, i -> {
80+
pidController.setI(i);
81+
currentI = i;
82+
});
83+
builder.addDoubleProperty("D", () -> currentD, d -> {
84+
pidController.setD(d);
85+
currentD = d;
86+
});
87+
builder.addDoubleProperty("Target Speed", () -> targetSpeed, newSpeed -> {
88+
if(newSpeed == targetSpeed) return;
89+
pidController.setReference(newSpeed, ControlType.kVelocity, 0, calculateFF(newSpeed));
90+
targetSpeed = newSpeed;
91+
});
92+
builder.addDoubleProperty("Tolerance", () -> tolerance, newTolerance -> tolerance = newTolerance);
93+
builder.addDoubleProperty("Current Speed", encoder::getVelocity, null);
94+
}
95+
10096
}

src/main/java/org/carlmontrobotics/lib199/SwerveConfig.java renamed to src/main/java/org/carlmontrobotics/lib199/swerve/SwerveConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.carlmontrobotics.lib199;
1+
package org.carlmontrobotics.lib199.swerve;
22

33
public final class SwerveConfig {
44

src/main/java/org/carlmontrobotics/lib199/SwerveModule.java renamed to src/main/java/org/carlmontrobotics/lib199/swerve/SwerveModule.java

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.carlmontrobotics.lib199;
1+
package org.carlmontrobotics.lib199.swerve;
22

33
import java.util.function.Supplier;
44

@@ -14,33 +14,34 @@
1414
import edu.wpi.first.math.geometry.Rotation2d;
1515
import edu.wpi.first.math.kinematics.SwerveModuleState;
1616
import edu.wpi.first.math.trajectory.TrapezoidProfile;
17+
import edu.wpi.first.util.sendable.Sendable;
18+
import edu.wpi.first.util.sendable.SendableBuilder;
1719
import edu.wpi.first.wpilibj.Timer;
1820
import 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

Comments
 (0)