77
88package frc .robot .subsystems .drive ;
99
10+ import static edu .wpi .first .units .Units .Degree ;
11+ import static edu .wpi .first .units .Units .Radians ;
1012import static frc .robot .subsystems .drive .DriveConstants .*;
1113import static frc .robot .util .SparkUtil .*;
1214
@@ -43,7 +45,9 @@ public class ModuleIOSpark implements ModuleIO {
4345 private final SparkBase driveSpark ;
4446 private final SparkBase turnSpark ;
4547 private final RelativeEncoder driveEncoder ;
46- private final AbsoluteEncoder turnEncoder ;
48+ private final RelativeEncoder turnEncoder ;
49+
50+ private final AnalogEncoder absoluteEncoder ; // MODIFIED
4751
4852 // Closed loop controllers
4953 private final SparkClosedLoopController driveController ;
@@ -92,27 +96,17 @@ public ModuleIOSpark(int module) {
9296 },
9397 MotorType .kBrushless );
9498 driveEncoder = driveSpark .getEncoder ();
95- // turnEncoder = turnSpark.getAbsoluteEncoder();
96-
97- // # BEGIN CUSTOMIZED CODE:
98- switch (module ) {
99- case 0 :
100- turnEncoder = new AbsoluteAnalogEncoder (0 );
101- break ;
102- case 1 :
103- turnEncoder = new AbsoluteAnalogEncoder (1 );
104- break ;
105- case 2 :
106- turnEncoder = new AbsoluteAnalogEncoder (3 );
107- break ;
108- case 3 :
109- turnEncoder = new AbsoluteAnalogEncoder (2 );
110- break ;
111- default :
112- turnEncoder = new AbsoluteAnalogEncoder (5 );
113- }
99+ turnEncoder = turnSpark .getEncoder ();
114100
115- // # END CUSTOMIZED CODE.
101+ absoluteEncoder =
102+ new AnalogEncoder (
103+ switch (module ) {
104+ case 0 -> frontLeftAbsoluteEncoderChannel ;
105+ case 1 -> frontRightAbsoluteEncoderChannel ;
106+ case 2 -> backLeftAbsoluteEncoderChannel ;
107+ case 3 -> backRightAbsoluteEncoderChannel ;
108+ default -> 0 ;
109+ });
116110
117111 driveController = driveSpark .getClosedLoopController ();
118112 turnController = turnSpark .getClosedLoopController ();
@@ -164,25 +158,22 @@ public ModuleIOSpark(int module) {
164158 .smartCurrentLimit (turnMotorCurrentLimit )
165159 .voltageCompensation (12.0 );
166160 turnConfig
167- .absoluteEncoder
168- .inverted (turnEncoderInverted )
161+ .encoder
162+ // .inverted(turnEncoderInverted)
169163 .positionConversionFactor (turnEncoderPositionFactor )
170164 .velocityConversionFactor (turnEncoderVelocityFactor )
171- .averageDepth (2 );
172- // We do NOT attach the RoboRIO analog absolute encoder to the SPARK as a
173- // closed-loop sensor (the analog encoder is wired to the RoboRIO). Instead
174- // we run the turn PID on the RoboRIO using WPILib's PIDController and
175- // command voltages to the SPARK. Configure only the SPARK parameters here.
165+ .uvwAverageDepth (2 );
176166 turnConfig
177167 .closedLoop
168+ .feedbackSensor (FeedbackSensor .kPrimaryEncoder )
178169 .positionWrappingEnabled (true )
179170 .positionWrappingInputRange (turnPIDMinInput , turnPIDMaxInput );
180171 turnConfig
181172 .signals
182- .absoluteEncoderPositionAlwaysOn (true )
183- .absoluteEncoderPositionPeriodMs ((int ) (1000.0 / odometryFrequency ))
184- .absoluteEncoderVelocityAlwaysOn (true )
185- .absoluteEncoderVelocityPeriodMs (20 )
173+ .primaryEncoderPositionAlwaysOn (true )
174+ .primaryEncoderPositionPeriodMs ((int ) (1000.0 / odometryFrequency ))
175+ .primaryEncoderVelocityAlwaysOn (true )
176+ .primaryEncoderVelocityPeriodMs (20 )
186177 .appliedOutputPeriodMs (20 )
187178 .busVoltagePeriodMs (20 )
188179 .outputCurrentPeriodMs (20 );
@@ -193,6 +184,10 @@ public ModuleIOSpark(int module) {
193184 turnSpark .configure (
194185 turnConfig , ResetMode .kResetSafeParameters , PersistMode .kPersistParameters ));
195186
187+ tryUntilOk (
188+ turnSpark ,
189+ 5 ,
190+ () -> turnEncoder .setPosition (Radians .convertFrom (absoluteEncoder .get () * 360 , Degree )));
196191 // Create odometry queues
197192 timestampQueue = SparkOdometryThread .getInstance ().makeTimestampQueue ();
198193 drivePositionQueue =
@@ -202,7 +197,7 @@ public ModuleIOSpark(int module) {
202197 // instead of going through the Spark-specific sampling/error path which can drop
203198 // or mis-time samples for a non-Spark sensor and produce jitter in AdvantageScope.
204199 turnPositionQueue =
205- SparkOdometryThread .getInstance ().registerSignal (() -> turnEncoder . getPosition () );
200+ SparkOdometryThread .getInstance ().registerSignal (turnSpark , turnEncoder :: getPosition );
206201 //// MODIFIED
207202 }
208203
@@ -220,30 +215,12 @@ public void updateInputs(ModuleIOInputs inputs) {
220215 inputs .driveConnected = driveConnectedDebounce .calculate (!sparkStickyFault );
221216
222217 // Update turn inputs
223- // Read the external RoboRIO-mounted analog absolute encoder directly. Avoid using the
224- // Spark-registered sampling path for this signal because the analog encoder is not
225- // attached to the Spark and mixing the two sampling paths can produce missing/erratic
226- // samples in AdvantageScope.
227- boolean turnReadOk = true ;
228- double turnPos = 0.0 ;
229- double turnVel = 0.0 ;
230- try {
231- turnPos = turnEncoder .getPosition ();
232- turnVel = turnEncoder .getVelocity ();
233- } catch (Exception e ) {
234- // If reading fails, mark read as not-ok and leave defaults.
235- turnReadOk = false ;
236- }
237- if (turnReadOk ) {
238- inputs .turnPosition = new Rotation2d (turnPos ).minus (zeroRotation );
239- inputs .turnVelocityRadPerSec = turnVel ;
240- } else {
241- // fallback: keep velocity zero if we couldn't read the analog encoder.
242- inputs .turnVelocityRadPerSec = 0.0 ;
243- }
244-
245- // Still read Spark-side telemetry (applied output, bus voltage, current) via the
246- // Spark-safe helpers.
218+ sparkStickyFault = false ;
219+ ifOk (
220+ turnSpark ,
221+ turnEncoder ::getPosition ,
222+ (value ) -> inputs .turnPosition = new Rotation2d (value ).minus (zeroRotation ));
223+ ifOk (turnSpark , turnEncoder ::getVelocity , (value ) -> inputs .turnVelocityRadPerSec = value );
247224 ifOk (
248225 turnSpark ,
249226 new DoubleSupplier [] {turnSpark ::getAppliedOutput , turnSpark ::getBusVoltage },
0 commit comments