One of the first things I’d toss out is “Why”? What’s the end goal of doing checking? Defining this will help scope what things are reasonable to check versus not.
In general, any verification requires redundant pieces of information which can be used to verify a condition. Two pieces are required to detect an issue. You can see pieces of info indicate mismatching conditions, clearly one must be wrong. However, you won’t know which is wrong. Three are required to “correct” for it (ie know which piece of info was incorrect).
Any datalink (SPI, I2C, CAN) device should have either a status/ID register, or at least an expected communication sequence. If this cannot be read properly at startup, you can set a flag to indicate the device is faulted and unavailable.
Since motors are expected to draw current, you can compare the actual current against some expected value.
Same for encoders - if current is flowing to the mechanism, you can deduce some motion should be ocurring. The better you know the mechanism, the tighter constraint you can put on what motion is reasonable.
FYI One other example from industry: Lots of automotive speed sensors (encoders) use anelectrical-current based protocol, rather than just voltage like FRC encoders.
~20mA = “High”
~4mA = “Low”
0mA = Unplugged (fault)
I would believe this sort of signaling is beyond standard FRC capabilities right now, unless you design your own breakout board?
But, once you detect a fault, what do you do? You can lock out certan functionality of the robot. You could just display a warning to operators, or just pit crew even. You could do nothing. You could use an alternate method of calculation. This is where it wraps back around to the first question: What’s the end goal?
FMEA may be of interest to you?