-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Driver dashboard alerts #51
base: main
Are you sure you want to change the base?
Changes from all commits
323973b
d0e6642
f52af3b
f64ab33
77495ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package org.team1540.robot2024; | ||
|
||
import com.ctre.phoenix6.CANBus; | ||
import edu.wpi.first.hal.can.CANStatus; | ||
import edu.wpi.first.wpilibj.DriverStation; | ||
import edu.wpi.first.wpilibj.RobotController; | ||
import edu.wpi.first.wpilibj.Timer; | ||
import org.team1540.robot2024.util.Alert; | ||
|
||
/** | ||
* Class for managing high-level robot alerts, such as low battery and CAN bus errors. Subsystem-specific alerts, | ||
* such as motor disconnects, should be handled by their respective subsystems. | ||
*/ | ||
public class AlertManager { | ||
private static AlertManager instance; | ||
|
||
public static AlertManager getInstance() { | ||
if (instance == null) instance = new AlertManager(); | ||
return instance; | ||
} | ||
|
||
private static final double lowBatteryDisableTime = 1.5; | ||
private static final double lowBatteryVoltageThreshold = 12.0; | ||
private static final double canErrorTimeThreshold = 0.5; | ||
|
||
private final Timer disabledTimer = new Timer(); | ||
private final Timer canInitialErrorTimer = new Timer(); | ||
private final Timer canErrorTimer = new Timer(); | ||
private final Timer canivoreErrorTimer = new Timer(); | ||
|
||
private int lastRioCanTEC = 0; | ||
private int lastRioCanREC = 0; | ||
private int lastCanivoreTEC = 0; | ||
private int lastCanivoreREC = 0; | ||
|
||
private final Alert canErrorAlert = | ||
new Alert("RIO CAN bus error", Alert.AlertType.ERROR); | ||
private final Alert canivoreErrorAlert = | ||
new Alert("Swerve CAN bus error", Alert.AlertType.ERROR); | ||
private final Alert lowBatteryAlert = | ||
new Alert("Battery voltage is low", Alert.AlertType.WARNING); | ||
|
||
public void start() { | ||
disabledTimer.restart(); | ||
canErrorTimer.restart(); | ||
canivoreErrorTimer.restart(); | ||
canInitialErrorTimer.restart(); | ||
} | ||
|
||
public void update() { | ||
// Update timers | ||
CANStatus rioCanStatus = RobotController.getCANStatus(); | ||
if (rioCanStatus.transmitErrorCount > lastRioCanTEC || rioCanStatus.receiveErrorCount > lastRioCanREC) { | ||
canErrorTimer.reset(); | ||
} | ||
lastRioCanTEC = rioCanStatus.transmitErrorCount; | ||
lastRioCanREC = rioCanStatus.receiveErrorCount; | ||
|
||
CANBus.CANBusStatus canivoreStatus = CANBus.getStatus(Constants.SwerveConfig.CAN_BUS); | ||
if (!canivoreStatus.Status.isOK() | ||
|| canivoreStatus.TEC > lastCanivoreTEC | ||
|| canivoreStatus.REC > lastCanivoreREC) { | ||
canivoreErrorTimer.reset(); | ||
} | ||
lastCanivoreTEC = canivoreStatus.TEC; | ||
lastCanivoreREC = canivoreStatus.REC; | ||
|
||
if (DriverStation.isEnabled()) disabledTimer.reset(); | ||
|
||
canErrorAlert.set( | ||
!canErrorTimer.hasElapsed(canErrorTimeThreshold) | ||
&& canInitialErrorTimer.hasElapsed(canErrorTimeThreshold)); | ||
canivoreErrorAlert.set( | ||
!canivoreErrorTimer.hasElapsed(canErrorTimeThreshold) | ||
&& canInitialErrorTimer.hasElapsed(canErrorTimeThreshold)); | ||
lowBatteryAlert.setText("Battery voltage is low (" + RobotController.getBatteryVoltage() + "V)"); | ||
lowBatteryAlert.set( | ||
RobotController.getBatteryVoltage() < lowBatteryVoltageThreshold | ||
&& disabledTimer.hasElapsed(lowBatteryDisableTime)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,16 +92,17 @@ public ModuleIOTalonFX(SwerveFactory.SwerveModuleHW hw, PhoenixTimeSyncSignalRef | |
@Override | ||
public void updateInputs(ModuleIOInputs inputs) { | ||
odometrySignalRefresher.refreshSignals(); | ||
BaseStatusSignal.refreshAll( | ||
inputs.driveMotorConnected = BaseStatusSignal.refreshAll( | ||
driveVelocity, | ||
driveAppliedVolts, | ||
driveCurrent, | ||
driveTempCelsius, | ||
turnAbsolutePosition, | ||
driveTempCelsius).isOK(); | ||
inputs.turnMotorConnected = BaseStatusSignal.refreshAll( | ||
turnVelocity, | ||
turnAppliedVolts, | ||
turnCurrent, | ||
turnTempCelsius); | ||
turnTempCelsius).isOK(); | ||
inputs.turnEncoderConnected = BaseStatusSignal.refreshAll(turnAbsolutePosition).isOK(); | ||
Comment on lines
+95
to
+105
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Javadoc says that ^, do we know if it's enough to matter on the 250hz bus? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refresh is a non-blocking call, so the performance improvement is probably minimal. These signals are being update at 50hz, only drive and turn position are on 250hz |
||
|
||
inputs.drivePositionRad = Units.rotationsToRadians(drivePosition.getValueAsDouble()) / DRIVE_GEAR_RATIO; | ||
inputs.driveVelocityRadPerSec = Units.rotationsToRadians(driveVelocity.getValueAsDouble()) / DRIVE_GEAR_RATIO; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this take any considerable amount of time with the NT stuff? (wpilib apparently has profiling tools somewhere)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alerts don't publish very much stuff to NT, so this shouldn't take a significant amount of time. We could profile it if we see loop overruns because of
SmartDashboard.updateValues()
. I can take a look at this when a test on the robot.