Gray Matter LogoGray Matter Workshop

Implementing Logging

KEY CONCEPT

Setting Up DataLogManager

We log with WPILib's built-in DataLogManager. No vendordep, no LoggedRobot, no replay layer. Two lines in Robot's constructor turn it on; after that, anything published to NetworkTables (your telemetry plus the Driver-Station and joystick data) is captured to a .wpilog file you open in AdvantageScope.

↳ TAKEAWAY

Turn it on in Robot's constructor, then publish what you care about to NetworkTables. DataLogManager records every NT change to disk.

Turning on logging

DataLogManageris part of WPILib, so there's nothing to install. Start it in Robot's constructor before anything else, and add the Driver-Station data feed:

Where the logs go

  • Simulation: a .wpilog under ./logs in your project.
  • On SystemCore: a USB drive if one is plugged in, otherwise /home/systemcore/logs.
  • Phoenix 6 devices additionally log to a .hoot file (high-rate signal data) that you can open in Tuner X or AdvantageScope, so you get that extra detail for free.

What you get automatically

The moment DataLogManager.start() runs, these are captured with no further code:

Captured for free

  • Every NetworkTables value change, including everything your telemetry publishes (more below)
  • Console output: anything printed to stdout/stderr
  • Driver-Station data (via startDataLog): alliance, mode, match time, and full joystick axes/buttons
  • Phoenix 6 signals in the .hoot file: motor positions, velocities, currents, temperatures

Logging your own values

To log something specific, publish it to NetworkTables; DataLogManager records the change to the .wpilog automatically. For a quick number, SmartDashboard.putNumber("Arm/Position", pos) works. For structured types like Pose2d or ChassisVelocities, use a NetworkTables struct publisher so AdvantageScope can render them natively.

πŸ—ΊοΈ The drivetrain telemetry surface (struct publishers)

The template's Telemetryclass is the project's logging surface. It publishes the swerve state to NetworkTables with type-aware struct publishers; CTRE calls it from the odometry thread (register with drivetrain.registerTelemetry(telemetry::telemeterize)). Because it's on NetworkTables, DataLogManager writes it to the .wpilog too.

πŸ“Š Logging from a mechanism (there's no periodic() in v3)

v3 mechanisms don't have a periodic()method, so "publish my state every loop" needs a different home. The simple pattern is a runRepeatedly(...) default command that publishes each tick whenever nothing else is using the mechanism:

You can also publish from inside a command body, right next to the setpoint that produced the value β€” handy for logging target-vs-actual during a move.

Performance Considerations

  • Use hierarchical keys (e.g. "Arm/Position") so the log stays organized.
  • Prefer struct types: publish one Pose2d rather than three separate numbers.
  • Avoid high-frequency strings. They're expensive; log numbers and booleans.
  • Don't over-publish. Too much NT traffic can affect loop timing.

Workshop Code Implementation

Robot.java β€” starting DataLogManager

Loading file...

πŸ”§ Drivetrain telemetry

The drivetrain is the canonical example: it publishes Pose2d, velocity, and per-module states to NetworkTables through its telemetry helper, and DataLogManager records all of it.

Loading file...

AdvantageScope

AdvantageScope is the natural viewer for the logs you're producing. It reads .wpilog files for post-match analysis and connects to your robot over NetworkTables for live monitoring. (Glass and Tuner X can also read these; Tuner X opens the .hoot files.)

πŸ“‘ Real-Time Data Viewing

Everything you publish to NetworkTables is visible live.

  1. Open AdvantageScope on your driver station
  2. Select "Connect to Robot" from the menu
  3. Enter your team number or robot address
  4. Browse the NetworkTables tree β€” your keys land under their table (e.g. Drivetrain/Pose)
  5. Add graphs, the 3D field view, or swerve module visualizations

πŸ“₯ Post-Match Log Analysis

Pull .wpilog files off the USB drive or download them from the robot with AdvantageScope.

  1. Open Preferences and set the robot address / log folder
  2. Click "File" > "Download Logs..."
  3. Select the logs to download (newest at top)
  4. Open the downloaded .wpilog file
  5. Add line graphs or use the 3D field view for analysis

Where the data lives in NetworkTables

Your published values land under whatever table you chose, and the auto-captured data sits alongside it:

  • Drivetrain/Pose, Drivetrain/Velocity, …: your telemetry struct publishers
  • SmartDashboard/...: anything you sent via SmartDashboard.put*
  • Driver-Station and joystick data captured by startDataLog

AdvantageScope Pro Tips

  • Overlay multiple signals: compare target vs actual on the same graph
  • Video sync: line log data up with match video
  • Save layouts: reusable dashboards for quick analysis
  • Drag struct types in: drop a logged Pose2d onto the 2D/3D field view directly
AdvantageScope Documentation

Logging Best Practices

βœ… Do

  • Log sensor inputs, motor outputs, and target setpoints together
  • Use hierarchical keys (Subsystem/Parameter)
  • Prefer struct types (Pose2d, SwerveModuleVelocity[]) over flattened number arrays
  • Start DataLogManager first thing in Robot's constructor
  • Download logs after every match and review between matches

❌ Don’t

  • Log high-frequency strings (use numbers or booleans)
  • Publish so much that NetworkTables traffic hurts loop timing
  • Forget a USB drive on the robot if you want the log off the controller easily
  • Ignore loop-overrun warnings from excessive publishing

Additional Resources

CHECKPOINT Β· 5 ITEMS

What's Next?

Up Next: Drive to Point

With DataLogManager recording your pose, velocities, and module states, you're ready to implement autonomous navigation, with every PID setpoint, error, and motor output captured for tuning the moment something looks off.