11package frc .lib .monitor ;
22
3- import com .ctre .phoenix6 .hardware .CANcoder ;
43import com .ctre .phoenix6 .hardware .ParentDevice ;
5- import com .ctre .phoenix6 .hardware .TalonFX ;
64import com .reduxrobotics .canand .CanandDevice ;
7- import com .reduxrobotics .sensors .canandmag .Canandmag ;
85import com .revrobotics .spark .SparkBase ;
9- import com .revrobotics .spark .SparkMax ;
106import edu .wpi .first .wpilibj .*;
117import edu .wpi .first .wpilibj .event .EventLoop ;
128import edu .wpi .first .wpilibj2 .command .CommandScheduler ;
139import edu .wpi .first .wpilibj2 .command .Commands ;
1410import edu .wpi .first .wpilibj2 .command .button .Trigger ;
1511import frc .lib .util .Capture ;
16- import frc .robot .subsystems .drive .swerveModule .encoder .EncoderIOHelium ;
17- import lombok .Getter ;
18-
1912import java .util .function .BooleanSupplier ;
13+ import lombok .Getter ;
2014
2115/**
22- * A class designed to passively monitor and report device connection issues.
23- * Creates 2 NT Alerts, (ActiveHardwareAlerts and StickyHardwareAlerts)
16+ * A class designed to passively monitor and report device connection issues. Creates 2 NT Alerts,
17+ * (ActiveHardwareAlerts and StickyHardwareAlerts)
2418 */
2519public class HardwareWatchdog {
2620 @ Getter public static final HardwareWatchdog instance = new HardwareWatchdog ();
2721
2822 private final EventLoop eventLoop = new EventLoop ();
2923
30- // String concatenations are slow, and there really is no need to update the alert more frequently
31- // This only impacts the while active periodic alert updates, and does not impact when the appearance or disappearance of the alert occurs
24+ // String concatenations are slow, and there really is no need to update the alert more
25+ // frequently
26+ // This only impacts the while active periodic alert updates, and does not impact when the
27+ // appearance or disappearance of the alert occurs
3228 // Or the start/stop times
3329 private static final double alertUpdatePeriod = .2 ;
3430
@@ -38,80 +34,110 @@ public class HardwareWatchdog {
3834 private static final String groupActive = "ActiveHardwareAlerts" ;
3935 private static final String groupSticky = "StickyHardwareAlerts" ;
4036
41-
4237 private HardwareWatchdog () {
4338 var timer = new Timer ();
4439 timer .start ();
4540
46- CommandScheduler .getInstance ().getDefaultButtonLoop ().bind (
47- () -> {
48- if (timer .get () > gracePeriod ) {eventLoop .poll ();}
49- }
50- );
41+ CommandScheduler .getInstance ()
42+ .getDefaultButtonLoop ()
43+ .bind (
44+ () -> {
45+ if (timer .get () > gracePeriod ) {
46+ eventLoop .poll ();
47+ }
48+ });
5149 }
5250
5351 public void registerCTREDevice (ParentDevice device , Class <?> parent ) {
54- registerDevice (device ::isConnected , device .getClass ().getSimpleName () + " " + device .getDeviceID (), parent );
52+ registerDevice (
53+ device ::isConnected ,
54+ device .getClass ().getSimpleName () + " " + device .getDeviceID (),
55+ parent );
5556 }
5657
5758 public void registerSpark (SparkBase spark , Class <?> parent ) {
58- registerDevice (() -> !spark .getFaults ().can && spark .getFirmwareVersion () != 0 , "SparkMax " + spark .getDeviceId (), parent );
59+ registerDevice (
60+ () -> !spark .getFaults ().can && spark .getFirmwareVersion () != 0 ,
61+ "SparkMax " + spark .getDeviceId (),
62+ parent );
5963 }
6064
6165 public void registerDutyCycleEncoder (DutyCycleEncoder encoder , Class <?> parent ) {
62- registerDevice (encoder ::isConnected , "DutyCycleEncoder " + encoder .getSourceChannel (), parent );
66+ registerDevice (
67+ encoder ::isConnected , "DutyCycleEncoder " + encoder .getSourceChannel (), parent );
6368 }
6469
6570 public void registerReduxDevice (CanandDevice device , Class <?> parent ) {
66- registerDevice (device ::isConnected , device .getClass ().getSimpleName () + " " + device .getAddress ().getDeviceId (), parent );
71+ registerDevice (
72+ device ::isConnected ,
73+ device .getClass ().getSimpleName () + " " + device .getAddress ().getDeviceId (),
74+ parent );
6775 }
6876
6977 public void registerDevice (BooleanSupplier isConnected , String name , Class <?> parent ) {
70- String deviceDescriptor = String .format ("\" %s\" belonging to \" %s\" " , name , parent .getSimpleName ());
78+ String deviceDescriptor =
79+ String .format ("\" %s\" belonging to \" %s\" " , name , parent .getSimpleName ());
7180
72- Capture <Alert > alert = new Capture <>(new Alert (groupActive , "deviceDisconnectAlert" , Alert .AlertType .kWarning ));
81+ Capture <Alert > alert =
82+ new Capture <>(
83+ new Alert (groupActive , "deviceDisconnectAlert" , Alert .AlertType .kWarning ));
7384 Capture <Alert > stickyAlert = new Capture <>(null );
7485
7586 Capture <Double > disconnectedAt = new Capture <>(-1.0 );
7687
7788 var updateTimer = new Timer ();
7889
7990 // On disconnect
80- new Trigger (eventLoop , isConnected ).negate ().whileTrue (
81- Commands .startRun (() -> {
82- updateTimer .restart ();
83- disconnectedAt .inner = Timer .getTimestamp ();
84-
85- // Create a new sticky alert, this way old ones persist
86- stickyAlert .inner = new Alert (groupSticky , "deviceDisconnectStickyAlert" , Alert .AlertType .kWarning );
87-
88- alert .inner .set (true );
89- stickyAlert .inner .set (true );
90- }, () -> {
91- if (updateTimer .advanceIfElapsed (alertUpdatePeriod )) {
92- var timeDisconnected = Timer .getTimestamp () - disconnectedAt .get ();
93-
94- var text = String .format (
95- "Device %s has been disconnected for %.2f seconds (since %.2f)" ,
96- deviceDescriptor , timeDisconnected , disconnectedAt .get ()
97- );
98-
99- alert .inner .setText (text );
100- stickyAlert .inner .setText (text );
101- }
102- }).finallyDo (() ->
103- {
104- alert .get ().set (false );
105-
106- var stickyText = String .format (
107- "Device %s was disconnected for %.2f seconds (from %.2f to %.2f)" ,
108- deviceDescriptor , Timer .getTimestamp () - disconnectedAt .get (), disconnectedAt .get (), Timer .getTimestamp ()
109- );
110-
111- stickyAlert .inner .setText (stickyText );
112- updateTimer .stop ();
113- })
114- .ignoringDisable (true )
115- );
91+ new Trigger (eventLoop , isConnected )
92+ .negate ()
93+ .whileTrue (
94+ Commands .startRun (
95+ () -> {
96+ updateTimer .restart ();
97+ disconnectedAt .inner = Timer .getTimestamp ();
98+
99+ // Create a new sticky alert, this way old ones persist
100+ stickyAlert .inner =
101+ new Alert (
102+ groupSticky ,
103+ "deviceDisconnectStickyAlert" ,
104+ Alert .AlertType .kWarning );
105+
106+ alert .inner .set (true );
107+ stickyAlert .inner .set (true );
108+ },
109+ () -> {
110+ if (updateTimer .advanceIfElapsed (alertUpdatePeriod )) {
111+ var timeDisconnected =
112+ Timer .getTimestamp () - disconnectedAt .get ();
113+
114+ var text =
115+ String .format (
116+ "Device %s has been disconnected for %.2f seconds (since %.2f)" ,
117+ deviceDescriptor ,
118+ timeDisconnected ,
119+ disconnectedAt .get ());
120+
121+ alert .inner .setText (text );
122+ stickyAlert .inner .setText (text );
123+ }
124+ })
125+ .finallyDo (
126+ () -> {
127+ alert .get ().set (false );
128+
129+ var stickyText =
130+ String .format (
131+ "Device %s was disconnected for %.2f seconds (from %.2f to %.2f)" ,
132+ deviceDescriptor ,
133+ Timer .getTimestamp ()
134+ - disconnectedAt .get (),
135+ disconnectedAt .get (),
136+ Timer .getTimestamp ());
137+
138+ stickyAlert .inner .setText (stickyText );
139+ updateTimer .stop ();
140+ })
141+ .ignoringDisable (true ));
116142 }
117143}
0 commit comments