Driver Station Logs
When a robot does something unexpected in a match and comes back to the pit, the teams that diagnose it in ten minutes are the teams with logs. This lesson covers every log channel available to you — from the simple Driver Station console to structured WPILOG files — and how to use them when the pressure is on.
By the end of this lesson, you will:
- Identify all three log severity levels and when to use each one
- Read a Java stack trace and locate the line of code that caused a crash
- Use
DriverStation.reportError()andreportWarning()for structured, persistent messages - Explain what a WPILOG file is, where it's saved, and how to open it in AdvantageScope
- Use
DataLogManagerto add custom variables to the structured log - Distinguish between the Driver Station console (live, ephemeral) and WPILOG (persistent, replayable)
The Robot Can't Speak — But It Can Write
A robot misbehaving in a match has no way to tell you what went wrong. But it has been writing to a log file the entire time. Every message, every error, every sensor value you published — all of it, timestamped, sitting on the roboRIO's storage waiting to be read.
There are two distinct logging systems you need to understand: the Driver Station console (live text messages sent to the laptop during operation) and the WPILOG file (a structured binary file recording every variable you chose to log, replayable after the match in AdvantageScope). They serve different purposes and you need both.
The Driver Station Console: Your Live Feed
The Driver Station's Messages tab shows a live stream of text log entries from the robot. Every entry has three fields: a timestamp, a severity level, and a message. Click any row below to learn what it means.
The Three Severity Levels
| Level | Java Method | When to Use | Color in DS |
|---|---|---|---|
| INFO | System.out.println() DriverStation.reportInfo() | Status updates, state transitions, sensor values during development. Remove temporary ones before competition. | White / blue |
| WARNING | DriverStation.reportWarning() | Non-fatal anomalies: sensor value out of range, subsystem not at expected state, unexpected timing. Leave these in competition code. | Yellow / amber |
| ERROR | DriverStation.reportError() | Fatal conditions, unhandled exceptions. The DS automatically generates ERRORs for Java exceptions. Never ignore a red ERROR row. | Red |
Reading a Stack Trace
A stack trace is the most valuable log entry you will ever see. It is an exact crime scene report: what exception occurred, which class threw it, and the chain of method calls that led there. Click each line below to understand what it's telling you.
The stack trace reads from most-recent call (top) to oldest call (bottom). The first line from your own code (not WPILib internals) is almost always where the bug is. In the example above, that's IntakeSubsystem.java:47. Open that file, go to line 47, and look at what could be null. The WPILib lines below yours are just the framework calling your code — they're innocent.
Structured Logging with WPILOG
The DS console is good for live debugging. But it's ephemeral — messages scroll off and it only covers what happened while you were watching. WPILOG is WPILib's structured binary log format: every variable you publish to NetworkTables is automatically logged to a timestamped file on the roboRIO's filesystem, capturing the entire match for post-match replay.
Log files live in /home/lvuser/logs/ on the roboRIO and are named by date and match number. Connect after a match, use the WPILib Device Browser or SCP to download them, and open in AdvantageScope to replay every variable against a timeline.
DataLogManager.start();
DriverStation.startDataLog(DataLogManager.getLog());
// ─── In a subsystem ──────────────────────────────
private final DoubleLogEntry m_speedLog;
private final BooleanLogEntry m_pieceLog;
public IntakeSubsystem() {
// Create log entries with path-style keys
m_speedLog = new DoubleLogEntry(DataLogManager.getLog(), "/Intake/MotorSpeed");
m_pieceLog = new BooleanLogEntry(DataLogManager.getLog(), "/Intake/HasPiece");
}
@Override
public void periodic() {
// Write to structured log every loop
m_speedLog.append(m_motor.get());
m_pieceLog.append(hasGamePiece());
// SmartDashboard still works — both systems coexist
SmartDashboard.putNumber("Intake/MotorSpeed", m_motor.get());
}
At competition, when something goes wrong in a match, you have ten minutes between matches to diagnose it. Teams without logs are guessing. Teams with WPILOG files and AdvantageScope open the log, scrub to the moment of failure, and see exactly what every sensor and motor was doing at that instant. Motor stator current spiked? The intake jammed. Gyro drift during the turn? That's why the auto missed. State machine reads "EJECTING" when it should be "HOLDING"? There's the logic bug. Logs turn a mystery into a five-minute fix.
Before any competition practice:
- Add
DataLogManager.start()andDriverStation.startDataLog(DataLogManager.getLog())torobotInit(). Deploy, enable for 30 seconds, disable. SSH into the roboRIO (ssh lvuser@roborio-XXXX-frc.local) and confirm a.wpilogfile appeared in/home/lvuser/logs/. - Download the file and open it in AdvantageScope. Verify your SmartDashboard keys appear as log channels. If they don't, the log wasn't started before the first NetworkTables publish.
- The roboRIO has limited flash storage (~512 MB). WPILib automatically deletes old log files when space runs low. If you need to keep a specific match log, download it immediately — don't assume it will still be there after five more matches.
Knowledge Check
1. Your robot deploys successfully but immediately shows ERROR in the Driver Station console after enabling. The first line of the stack trace you can see from your code is at frc.robot.subsystems.DriveSubsystem.<init>(DriveSubsystem.java:23). What does this tell you?
2. You want to leave a permanent sensor-health check in the code that notifies the pit crew if an encoder's value is outside the expected startup range. Which logging method should you use?
3. In a match, the robot's autonomous routine fails. You download the WPILOG and open it in AdvantageScope. The /Drive/EncoderDistance channel shows the encoder went from 0 to 72 inches correctly. The /Intake/HasPiece channel shows false the entire time. The /Auto/ActiveCommand shows the sequence stuck on "IntakeCommand" for 10 seconds. What most likely caused the autonomous failure?
Instrument Your Robot for Competition Logging
- Add
DataLogManager.start()andDriverStation.startDataLog()toRobot.java robotInit(). Deploy, run for 30 seconds, and confirm a WPILOG file is written. Open it in AdvantageScope — identify at least three logged channels from your SmartDashboard output. - Add
DoubleLogEntryandBooleanLogEntryfields to yourIntakeSubsystem. Log motor speed andhasGamePiece()inperiodic(). Verify they appear in AdvantageScope with correct values across a simulated intake cycle. - Add a
DriverStation.reportWarning()in your subsystem constructor that fires if an expected sensor read returns an out-of-range value at startup (e.g., encoder > 100 at init). Deliberately cause the condition and confirm the yellow WARNING appears in the DS Messages tab. - Stretch goal: Add
SmartDashboard.putData("Active Commands", CommandScheduler.getInstance())inrobotInit(). This logs the active command list. In AdvantageScope, find the/SmartDashboard/Active Commandschannel and replay an auto run. Confirm you can see each phase of the routine by name in the timeline. This is the single most powerful tool for autonomous debugging.