TelemetryKit¶
TelemetryKit (tkit) is a C++ telemetry framework for FRC robots. It provides structured logging with support for NetworkTables 4, WPILog files, and console output.
Features¶
- Type-Safe - Compile-time type checking with
std::variantstorage - Multiple Receivers - Log to NT4, WPILog files, and console simultaneously
- Struct Support - WPILib struct serialization with automatic schema publishing
- Unit Metadata - Automatic unit extraction from WPILib units library for AdvantageScope
- Field-Change-Only - Only logs values when they change to reduce overhead
Quick Start¶
Installation¶
- Open VS Code with your FRC project
- Press
Ctrl+Shift+P(orCmd+Shift+Pon Mac) - Type "WPILib: Manage Vendor Libraries"
- Select "Install new libraries (online)"
- Paste this URL:
Basic Usage¶
Robot.cpp
#include <telemetrykit/TelemetryKit.h>
void Robot::RobotInit() {
auto& logger = tkit::Logger::GetInstance();
// Add receivers
logger.AddReceiver(std::make_unique<tkit::NetworkTablesReceiver>()); // (1)!
logger.AddReceiver(std::make_unique<tkit::WPILogWriter>("/home/lvuser/logs")); // (2)!
logger.Start(); // (3)!
}
void Robot::RobotPeriodic() {
auto& logger = tkit::Logger::GetInstance();
// Log primitive values (using member functions)
logger.RecordOutput("DriveTrain/Speed", 3.5); // (4)!
logger.RecordOutput("DriveTrain/Enabled", true);
// Or use global convenience functions
tkit::RecordOutput("DriveTrain/Current", 12.5); // (5)!
// Log structs (automatically handles schema publishing)
frc::Pose2d pose{1.5_m, 2.3_m, frc::Rotation2d{45_deg}};
logger.RecordOutput("RobotPose", tkit::MakeStructValue(pose)); // (6)!
// Update logger (sends data to all receivers)
logger.Periodic(); // (7)!
}
- Publishes to NT4 for real-time viewing in Shuffleboard, Glass, or AdvantageScope
- Writes timestamped
.wpilogfiles to/home/lvuser/logs/ - Initializes all receivers (calls
OnStart()on each) - Logger member function - call on the logger instance
- Global convenience function - equivalent to
Logger::GetInstance().RecordOutput(...) - Serializes struct and collects all schemas (including nested Translation2d, Rotation2d)
- Sends all logged data to receivers (calls
OnUpdate()on each)
Member Functions vs Global Functions
Both approaches work identically - use logger.RecordOutput(...) for member functions or tkit::RecordOutput(...) for global convenience functions. Choose whichever style you prefer!
Call Periodic() Every Cycle
Logger::Periodic() (or tkit::Periodic()) must be called in RobotPeriodic() to flush data to all receivers.
Architecture¶
graph LR
A[Logger] --> B[LogTable]
B --> C[NetworkTablesReceiver]
B --> D[WPILogWriter]
B --> E[ConsoleReceiver]
C --> F[NT4 Client]
D --> G[.wpilog File]
E --> H[Console]
The Logger manages a LogTable (key-value store) and distributes updates to multiple receivers. Each receiver processes the data in its own way:
- NetworkTablesReceiver - Publishes to NT4 for real-time dashboard viewing
- WPILogWriter - Saves to .wpilog files for post-match analysis
- ConsoleReceiver - Prints to console for debugging
Next Steps¶
- Core Concepts - Learn about Logger, LogValue, and Receivers
- Alerts - Driver Station alerts and threshold monitoring
- Units - Unit metadata and WPILib units integration
- Receivers - Configure output destinations
- Struct Logging - Working with WPILib geometry types
- Examples - Common usage patterns
Design¶
- Zero-copy where possible - Minimal allocations during periodic calls
- Field-change-only - Only log values when they change
- Type-safe - Catch type errors at compile time
- Schema-aware - Automatic struct schema publishing for NT4 and WPILog