Skip to content

Case Study: Hardening Software Before an Event

learnfrc.com
learnfrc.comAuthor
Veer Bajaj
Veer BajajMaintainer

The gap between a robot that works in the shop and one that works in elimination matches is hardening. Here is a concrete, source-grounded checklist top teams run before every event.

Before packing, run WPILib’s preemptive troubleshooting: confirm firmware versions match across the roboRIO, PDH, radio, and every motor controller (mismatched firmware causes mysterious dropouts). Scan the CAN bus in Phoenix Tuner X and the REV Hardware Client; confirm every device in your written CAN ID map answers and has a unique ID. Verify CAN utilization is comfortably below 90%.

2. Fail-safe defaults and exception safety

Section titled “2. Fail-safe defaults and exception safety”

Wrap risky constructors in try/catch – some pneumatics/CAN objects (Compressor, Solenoid, PneumaticHub) can throw on construction if the CAN bus is disconnected at boot. A single uncaught exception in robotInit means no code runs all match. Defensive construction keeps the rest of the robot alive:

try { m_compressor = new Compressor(PneumaticsModuleType.REVPH); }
catch (Exception e) { DriverStation.reportError("PH init failed", false); }

Give every subsystem a safe default (motors neutral, mechanisms holding) so a crashed command doesn’t leave an output stuck on.

Strip System.out.println debugging (it causes loop overruns), disable any test-only code paths, and make sure logging is bounded – log cached values, not repeated CAN queries, so you don’t overrun under match load.

4. Make autos deterministic and selectable

Section titled “4. Make autos deterministic and selectable”

Use a SendableChooser so drivers pick the auto from the dashboard, mirror paths for the red alliance via the alliance flag, and simulate every auto before the event. Run each auto on blocks with wheels off the ground as a final sanity check. A deterministic auto that you’ve replayed (AdvantageKit) or simulated is one you can trust under pressure.

Commit working code to git and tag the exact commit you compete with so you can roll back instantly when a ‘quick fix’ between matches breaks something. Never deploy untested code in eliminations. A common failure pattern: a last-minute uncommitted change deployed in the pit, then a crash on field with no known-good version to revert to. The fix is process: protected main branch, tagged event builds, and a rule that field deploys come only from a tested, committed build.

Log battery voltage every match and review the DS log for brown-out (orange) lines. Rotate batteries, retire weak ones, and add current limits to any mechanism that spiked the 12V fault counter.

Run this checklist as a team ritual, not an individual’s memory. The teams that rarely have ‘mystery’ field failures are the ones who made hardening a repeatable process.

  • Match firmware versions and scan CAN (Phoenix Tuner X / REV Hardware Client) against a written ID map before every event.
  • Wrap risky constructors in try/catch and give every subsystem a safe default so one crash doesn’t kill the whole match.
  • Strip prints/test code, bound logging, and make autos deterministic, alliance-mirrored, and simulated before the event.
  • Tag the exact competing commit in git; field deploys come only from tested, committed builds – never untested pit edits.

This lesson was adapted from learnfrc.com.