Skip to content

Robot Coordination, Alerts, and Operator Feedback

learnfrc.com
learnfrc.comAuthor
Veer Bajaj
Veer BajajMaintainer

Advanced teams don’t just make the robot work – they make its internal state observable to drivers and pit crew so problems surface before they cost a match. WPILib and the vendors provide tools for exactly this.

WPILib’s Alert class publishes named warnings/errors to dashboards (Elastic, AdvantageScope, Shuffleboard) over NetworkTables instead of burying them in console spam. Construct an Alert(String text, AlertType type) (types: kError, kWarning, kInfo) and toggle it with set(boolean) from periodic():

private final Alert m_lowBattery =
new Alert("Battery below 11.5V -- swap before next match", AlertType.kWarning);
private final Alert m_camDisconnected =
new Alert("Front camera disconnected", AlertType.kError);
private double m_lastHeartbeat = -1;
@Override public void periodic() {
m_lowBattery.set(RobotController.getBatteryVoltage() < 11.5);
// A Limelight increments its 'hb' heartbeat once per frame; if it stops
// changing, the camera is no longer streaming.
double hb = LimelightHelpers.getLimelightNTDouble("", "hb");
m_camDisconnected.set(hb == m_lastHeartbeat);
m_lastHeartbeat = hb;
}

Now the pit crew sees a red banner the instant a camera drops, rather than discovering it on the field. (Detecting a disconnect by checking whether a NetworkTables entry merely exists is unreliable – the entry persists after the device drops; the heartbeat is the correct signal.)

Motor controllers expose health: getFaults() / getStickyFaults() on REV SPARK devices, and on CTRE devices isConnected() (or BaseStatusSignal.isAllGood()) for CAN presence plus sticky-fault status signals. (CTRE’s isAlive() reports the WPILib motor-safety watchdog, not CAN connectivity, so don’t use it to detect a disconnected device.) Roll these into Alerts so a missing CAN device is loud, not silent.

Addressable LEDs (e.g. WS2812B strips driven from a roboRIO PWM port via AddressableLED/AddressableLEDBuffer, or a CTRE CANdle) turn the robot into its own status display: green when the shooter is at speed, blue when a game piece is held, flashing when vision has a lock. Drivers react to color far faster than to a laptop dashboard, and human players read it from across the field.

m_buffer.setLED(i, atSpeed ? Color.kGreen : Color.kRed);
m_leds.setData(m_buffer);

Close the loop with the driver physically: controller.setRumble(RumbleType.kBothRumble, 1.0) for a moment when a game piece is acquired so the operator doesn’t have to watch a sensor.

These aren’t about making the robot move – they’re about operational reliability. Elite teams treat the robot as a system the humans must monitor under stress. Surfacing faults (Alerts), state (LEDs), and confirmation (rumble) shortens the loop between ‘something is wrong’ and ‘a human fixes it,’ which directly converts to fewer dropped matches. Build a one-glance status convention, document it for your drivers, and rehearse it.

  • Use WPILib’s Alert API – new Alert(text, AlertType) plus set(boolean) – to publish named warnings/errors to dashboards instead of console spam.
  • Roll device faults (REV getFaults(), CTRE status signals) into Alerts; detect a Limelight disconnect via its ‘hb’ heartbeat, not entry existence.
  • Drive addressable LEDs (AddressableLED / CTRE CANdle) as a status display drivers and human players read instantly.
  • Add controller rumble for tactile confirmation; observability of robot state directly reduces dropped matches.

This lesson was adapted from learnfrc.com.