Skip to content

Commit cb0ad28

Browse files
nlaverdureclaude
andcommitted
Report Phoenix device alerts from the drivetrain
Phoenix 26.70.0-alpha-2 adds alerts for its devices, reported through an AlertableCollection that user code registers devices with and calls report() on each loop. This follows the pattern in CTRE's SwerveWithChoreo example (CommandSwerveDrivetrain), keeping the devices behind the IO layer: ModuleIO gains a no-op registerAlerts(), ModuleIOTalonFXBase registers its drive TalonFX, steer TalonFX, and CANcoder, and Drive owns a "Swerve" collection that it reports from periodic(). On a SystemCore robot controller these alerts go to MrcLib and show in the Driver Station and NetworkTables dashboards. They do not reach the AdvantageKit log, because WPILib's AlertDataJNI.getAlerts() lists only WPILib-created alerts (issue #47, allwpilib#8731). In simulation the alerts are a no-op. PhoenixAlert's Javadoc says so, and disassembly of the sim builds (Windows swsim and hwsim, Linux x86-64) shows the platform::Alert constructor storing handle 0 without calling a backend, while the SystemCore build calls MRC_Alert_CreateAlert. A 20 s sim run with ModuleIOSimTalonFX temporarily swapped in confirmed it: Phoenix initialized, WPILib alerts were logged under /RealOutputs/Alerts, and no Swerve group appeared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent dd6fbe9 commit cb0ad28

4 files changed

Lines changed: 23 additions & 0 deletions

File tree

‎src/main/java/frc/robot/subsystems/drive/Drive.java‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static org.wpilib.units.Units.*;
1515

1616
import choreo.trajectory.SwerveSample;
17+
import com.ctre.phoenix6.alerts.AlertableCollection;
1718
import frc.lib.RobotMode;
1819
import frc.robot.Constants;
1920
import frc.robot.Constants.FeatureFlags;
@@ -59,6 +60,8 @@ public class Drive extends SubsystemBase {
5960
"Drive/gyroDisconnected",
6061
"Disconnected gyro, using kinematics as fallback.",
6162
Alert.Level.HIGH);
63+
// Phoenix reports these alerts on a robot controller and treats them as a no-op elsewhere
64+
private final AlertableCollection deviceAlerts = new AlertableCollection("Swerve");
6265

6366
private final BooleanPublisher alignEncodersPub;
6467

@@ -112,6 +115,9 @@ public Drive(
112115
modules[1] = new Module(frModuleIO, "FrontRight");
113116
modules[2] = new Module(blModuleIO, "BackLeft");
114117
modules[3] = new Module(brModuleIO, "BackRight");
118+
for (var module : modules) {
119+
module.registerAlerts(deviceAlerts);
120+
}
115121

116122
// Usage reporting for swerve template
117123
// TODO: update instance string to match the official 2027 AKit template when released.
@@ -209,6 +215,7 @@ public void periodic() {
209215
boolean gyroDisconnected = !gyroInputs.connected && Constants.currentMode != RobotMode.SIM;
210216
gyroDisconnectedAlert.set(gyroDisconnected);
211217
Logger.recordOutput("Faults/Drive/GyroDisconnected", gyroDisconnected);
218+
deviceAlerts.report();
212219

213220
// Profiling output
214221
if (FeatureFlags.PROFILING_ENABLED) {

‎src/main/java/frc/robot/subsystems/drive/Module.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import static frc.robot.subsystems.drive.DriveConstants.*;
1414

15+
import com.ctre.phoenix6.alerts.AlertableCollection;
1516
import frc.robot.Constants.FeatureFlags;
1617
import org.littletonrobotics.junction.Logger;
1718
import org.wpilib.math.geometry.Rotation2d;
@@ -200,6 +201,11 @@ public double getSimCurrentDrawAmps() {
200201
return inputs.driveCurrentAmps + inputs.turnCurrentAmps;
201202
}
202203

204+
/** Registers the module's Phoenix device alerts with the given collection. */
205+
public void registerAlerts(AlertableCollection alerts) {
206+
io.registerAlerts(alerts);
207+
}
208+
203209
/** Sets the zero position of the turn axis to the current rotation */
204210
public void setTurnZero() {
205211
Rotation2d newTurnZero = inputs.turnZero.minus(inputs.turnPosition);

‎src/main/java/frc/robot/subsystems/drive/ModuleIO.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package frc.robot.subsystems.drive;
99

10+
import com.ctre.phoenix6.alerts.AlertableCollection;
1011
import org.littletonrobotics.junction.AutoLog;
1112
import org.wpilib.math.geometry.Rotation2d;
1213

@@ -61,4 +62,7 @@ public default void setTurnPosition(Rotation2d rotation) {}
6162

6263
/** Update the turn zero position of the turn absolute encoder */
6364
public default void setTurnZero(Rotation2d rotation) {}
65+
66+
/** Registers the module's Phoenix device alerts with the given collection. */
67+
public default void registerAlerts(AlertableCollection alerts) {}
6468
}

‎src/main/java/frc/robot/subsystems/drive/ModuleIOTalonFXBase.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import com.ctre.phoenix6.BaseStatusSignal;
1616
import com.ctre.phoenix6.StatusSignal;
17+
import com.ctre.phoenix6.alerts.AlertableCollection;
1718
import com.ctre.phoenix6.configs.CANcoderConfiguration;
1819
import com.ctre.phoenix6.configs.TalonFXConfiguration;
1920
import com.ctre.phoenix6.controls.MotionMagicTorqueCurrentFOC;
@@ -194,4 +195,9 @@ public void setTurnZero(Rotation2d rotation) {
194195
cancoderConfig.MagnetSensor.MagnetOffset = rotation.getRotations();
195196
cancoder.getConfigurator().apply(cancoderConfig);
196197
}
198+
199+
@Override
200+
public void registerAlerts(AlertableCollection alerts) {
201+
alerts.withAlertable(driveTalon).withAlertable(turnTalon).withAlertable(cancoder);
202+
}
197203
}

0 commit comments

Comments
 (0)