Skip to content

Commit 17de0ea

Browse files
committed
add TalonFXS
1 parent ea02394 commit 17de0ea

File tree

4 files changed

+37
-18
lines changed

4 files changed

+37
-18
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
}
1212

1313
group = "org.strykeforce"
14-
version = "25.0.1-SNAPSHOT"
14+
version = "25.0.1"
1515

1616
java {
1717
targetCompatibility = JavaVersion.VERSION_17

src/main/java/org/strykeforce/swerve/FXSwerveModule.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class FXSwerveModule implements SwerveModule {
4141
private final TalonFX driveTalon;
4242
private final double azimuthCountsPerRev;
4343
private final double driveCountsPerRev;
44+
private final double azimuthPulseWidthCPR;
4445
private final double driveGearRatio;
4546
private final double wheelCircumferenceMeters;
4647
private final double driveDeadbandMetersPerSecond;
@@ -52,7 +53,7 @@ public class FXSwerveModule implements SwerveModule {
5253
private int closedLoopSlot;
5354
private int azimuthSlot;
5455
private boolean compensateLatency;
55-
private double azimuthPositionOffset;
56+
private double azimuthPositionOffset = 0.0;
5657

5758
// Status Signals
5859
private StatusSignal<Angle> drivePosition;
@@ -64,6 +65,7 @@ private FXSwerveModule(FXBuilder builder) {
6465
driveTalon = builder.driveTalon;
6566
azimuthCountsPerRev = builder.azimuthCountsPerRev;
6667
driveCountsPerRev = builder.driveCountsPerRev;
68+
azimuthPulseWidthCPR = builder.azimuthPulseWidthCPR;
6769
driveGearRatio = builder.driveGearRatio;
6870
wheelCircumferenceMeters = Math.PI * Inches.of(builder.wheelDiameterInches).in(Meters);
6971
driveDeadbandMetersPerSecond = builder.driveDeadbandMetersPerSecond;
@@ -169,7 +171,7 @@ public void loadAndSetAzimuthZeroReference() {
169171
index,
170172
azimuthAbsoluteCounts - reference);
171173

172-
azimuthPositionOffset = reference;
174+
azimuthPositionOffset = reference / azimuthPulseWidthCPR;
173175
setAzimuthPosition(azimuthAbsoluteCounts);
174176
}
175177

@@ -182,17 +184,23 @@ public TalonFX getDriveTalon() {
182184
}
183185

184186
private double getAzimuthAbsoluteEncoderCounts() {
185-
double extraRotations =
186-
azimuthPosition.getValueAsDouble() > 0
187-
? Math.floor(azimuthPosition.getValueAsDouble())
188-
: Math.ceil(azimuthPosition.getValueAsDouble());
189-
return azimuthPosition.getValueAsDouble() - extraRotations; // correct to within one rotation
187+
// double extraRotations =
188+
// azimuthPosition.getValueAsDouble() > 0
189+
// ? Math.floor(azimuthPosition.getValueAsDouble())
190+
// : Math.ceil(azimuthPosition.getValueAsDouble());
191+
// return azimuthPosition.getValueAsDouble() - extraRotations; // correct to within one
192+
// rotation
193+
return ((int) (azimuthPosition.getValueAsDouble() * azimuthPulseWidthCPR)) & 0xFFF;
190194
}
191195

192196
private double getAzimuthEcoderPosition() {
193197
return azimuthPosition.getValueAsDouble() - azimuthPositionOffset;
194198
}
195199

200+
public double getAzimuthPositionOffset() {
201+
return azimuthPositionOffset;
202+
}
203+
196204
@Override
197205
public Rotation2d getAzimuthRotation2d() {
198206
double azimuthCounts = getAzimuthEcoderPosition();
@@ -312,6 +320,7 @@ public static class FXBuilder {
312320
public static final double kDefaultTalonFXCountsPerRev = 1.0;
313321
private double azimuthCountsPerRev = kDefaultTalonFXCountsPerRev;
314322
private double driveCountsPerRev = kDefaultTalonFXCountsPerRev;
323+
private double azimuthPulseWidthCPR = 4096.0;
315324

316325
private TalonFXS azimuthTalon;
317326
private TalonFX driveTalon;
@@ -357,6 +366,11 @@ public FXBuilder azimuthEncoderCountsPerRevolution(double countsPerRev) {
357366
return this;
358367
}
359368

369+
public FXBuilder azimuthPulseWidthCPR(double azimuthPulseWidthCPR) {
370+
this.azimuthPulseWidthCPR = azimuthPulseWidthCPR;
371+
return this;
372+
}
373+
360374
public FXBuilder driveDeadbandMetersPerSecond(double driveDeadbandMetersPerSecond) {
361375
this.driveDeadbandMetersPerSecond = driveDeadbandMetersPerSecond;
362376
return this;
@@ -416,7 +430,13 @@ private void validateSwerveModuleObject(FXSwerveModule module) {
416430
if (module.azimuthCountsPerRev <= 0)
417431
throw new IllegalArgumentException(
418432
"azimuth encoder counts per revolution must be greater than zero.");
419-
433+
if (module.azimuthPulseWidthCPR <= 0)
434+
throw new IllegalArgumentException("azimuth pulse width cpr must be greater than zero");
435+
// TalonFXSConfiguration azimuthConfig = new TalonFXSConfiguration();
436+
// module.azimuthTalon.getConfigurator().refresh(azimuthConfig);
437+
// if (azimuthConfig.ExternalFeedback.ExternalFeedbackSensorSource
438+
// != ExternalFeedbackSensorSourceValue.PulseWidth)
439+
// throw new IllegalArgumentException("Azimuth must use Pulse Width Feedback");
420440
if (module.driveCountsPerRev <= 0)
421441
throw new IllegalArgumentException(
422442
"drive encoder counts per revolution must be greater than zero.");

src/main/kotlin/org/strykeforce/telemetry/measurable/TalonFXSMeasureable.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class TalonFXSMeasureable @JvmOverloads constructor(
118118
Measure(DIFF_CLOSED_LOOP_REF, "Differential Closed Loop Reference"){talonFXS.differentialClosedLoopReference.valueAsDouble},
119119
Measure(DIFF_CLOSED_LOOP_REF_SLOPE, "Differential Closed Loop Reference Slope"){talonFXS.differentialClosedLoopReferenceSlope.valueAsDouble},
120120
Measure(DIFF_CLOSED_LOOP_SLOT, "Differential Closed Loop Slot"){talonFXS.differentialClosedLoopSlot.valueAsDouble},
121+
Measure(PULSE_WIDTH_POSITION, "Pulse Width Position") {((talonFXS.position.valueAsDouble * 4096.0).toInt() and 0xFFF).toDouble()}
121122
)
122123

123124
override fun equals(other: Any?): Boolean {

src/test/java/org/strykeforce/swerve/TalonSwerveModuleTest.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,11 @@ void v6ResetDriveEncoder() {
123123
@DisplayName("FX Should reset drive encoder")
124124
void FXResetDriveEncoder() {
125125
TalonFX driveTalon = mock(com.ctre.phoenix6.hardware.TalonFX.class);
126+
TalonFXS azimuthTalon = mock(TalonFXS.class);
126127
when(driveTalon.setPosition(0)).thenReturn(StatusCode.OK);
127128
FXSwerveModule module =
128129
new FXSwerveModule.FXBuilder()
129-
.azimuthTalon(mock(TalonFXS.class))
130+
.azimuthTalon(azimuthTalon)
130131
.driveTalon(driveTalon)
131132
.driveGearRatio(kDriveGearRatio)
132133
.wheelDiameterInches(kWheelDiameterInches)
@@ -283,38 +284,35 @@ void storeFXAzimuthZeroReference() {
283284
when(azimuthTalon.getPosition()).thenReturn(azimuthPositionStatusSig);
284285
when(azimuthPositionStatusSig.getValueAsDouble()).thenReturn(expectedZeroReference);
285286
module.storeAzimuthZeroReference();
286-
assertEquals(expectedZeroReference, Preferences.getDouble(key, -1));
287+
assertEquals((int) (expectedZeroReference * 4096.0) & 0xFFF, Preferences.getDouble(key, -1));
287288

288289
expectedZeroReference = 67.0 / 4096.0;
289290
index = 1; // Front Right
290291
key = String.format("SwerveDrive/wheel.%d", index);
291292
module = builder.wheelLocationMeters(new Translation2d(1, -1)).build();
292293
when(azimuthPositionStatusSig.getValueAsDouble()).thenReturn(expectedZeroReference);
293294
module.storeAzimuthZeroReference();
294-
assertEquals(expectedZeroReference, Preferences.getDouble(key, -1));
295+
assertEquals((int) (expectedZeroReference * 4096.0) & 0xFFF, Preferences.getDouble(key, -1));
295296

296297
expectedZeroReference = -6767.0 / 4096.0;
297298
index = 2; // Back Left
298299
key = String.format("SwerveDrive/wheel.%d", index);
299300
module = builder.wheelLocationMeters(new Translation2d(-1, 1)).build();
300301
when(azimuthPositionStatusSig.getValueAsDouble()).thenReturn(expectedZeroReference);
301302
module.storeAzimuthZeroReference();
302-
assertEquals(
303-
expectedZeroReference - Math.ceil(expectedZeroReference), Preferences.getDouble(key, -1));
303+
assertEquals((int) (expectedZeroReference * 4096.0) & 0xFFF, Preferences.getDouble(key, -1));
304304

305305
expectedZeroReference = 6727.0 / 4096.0;
306306
index = 3; // Back Right
307307
key = String.format("SwerveDrive/wheel.%d", index);
308308
module = builder.wheelLocationMeters(new Translation2d(-1, -1)).build();
309309
when(azimuthPositionStatusSig.getValueAsDouble()).thenReturn(expectedZeroReference);
310310
module.storeAzimuthZeroReference();
311-
assertEquals(
312-
expectedZeroReference - Math.floor(expectedZeroReference),
313-
Preferences.getDouble(key, -1));
311+
assertEquals((int) (expectedZeroReference * 4096.0) & 0xFFF, Preferences.getDouble(key, -1));
314312
}
315313

316314
@ParameterizedTest
317-
@CsvSource({"0, 0, 0", "1, 0, 0", "1.00024, 0, 0.00024", "0, 0.67554, 0.67554"})
315+
@CsvSource({"0, 0, 0", "1, 0, 0", "1.00024, 0, 0.00024", "0, 2767, 0.67554"})
318316
@DisplayName("should set FX azimuth zero")
319317
void shouldSetFXAzimuthZero(
320318
double absoluteEncoderPosition, double zeroReference, double setpoint) {

0 commit comments

Comments
 (0)