Unofficial REV-Compatible Logger
Since REV does not provide an official method of automatically recording data from the Spark Max and Spark Flex, we have provided an unofficial alternative for Java and C++ called URCL (Unofficial REV-Compatible Logger). This enables live plotting and logging of all devices similar to CTRE's Tuner X plotting feature and Phoenix 6 signal logger.
After setup, periodic CAN frames from all Spark Max and Spark Flex devices are published to NetworkTables or DataLog. When using NetworkTables, WPILib's DataLogManager can be used to capture the data to a log file. These frames are viewable in AdvantageScope (see Managing Log Files and Connecting to Live Sources).
- All signals are captured automatically, with no manual setup for new devices.
- Every frame is captured, even when the status frame period is faster than the robot loop cycle.
- Frames are logged with timestamps based on the CAN RX time, enabling more accurate acceleration characterization with SysId compared to traditional logging in user code (see "SysId Usage" below).
- Logging is highly efficient; operations are threaded and run for under 80µs per 20ms periodic cycle, even when logging a large number of devices.
- All functions of REVLib are unaffected.
As this library is not an official REV tool, support queries should be directed to the URCL issues page or software@team6328.org rather than REV's support contact.
Setup
Install the URCL vendordep by going to "WPILib: Manage Vendor Libraries" > "Install new libraries (online)" in VSCode and pasting in the URL below.
https://raw.githubusercontent.com/Mechanical-Advantage/URCL/maven/URCL.json
URCL publishes to NetworkTables by default, where data can be saved to a log file by enabling WPILib's DataLogManager. Alternatively, URCL can log directly to a DataLog. The logger should be started in robotInit
, as shown below.
- WPILib (Java)
- WPILib (C++)
- AdvantageKit
public void robotInit() {
// If publishing to NetworkTables and DataLog
DataLogManager.start();
URCL.start();
// If logging only to DataLog
URCL.start(DataLogManager.getLog());
}
#include "frc/DataLogManager.h"
#include "URCL.h"
void Robot::RobotInit() {
// If publishing to NetworkTables and DataLog
frc::DataLogManager::Start();
URCL::Start();
// If logging only to DataLog
URCL::Start(frc::DataLogManager::GetLog());
}
public void robotInit() {
// ...
Logger.registerURCL(URCL.startExternal());
Logger.start();
}
URCL compatibility with AdvantageKit is provided for convenience only; the data recorded to the log is NOT available in replay. REV motor controllers must still be part of an IO implementation with defined inputs to support replay.
To more easily identify devices in the log, CAN IDs can be assigned to aliases by passing a map object to the start()
or startExternal()
method. The keys are CAN IDs and the values are strings for the names to use in the log. Any devices not assigned an alias will be logged using their default names.
SysId Usage
- After setting up URCL as shown above, configure the SysId routine using
null
for the mechanism log consumer. An example is shown below for Java. This configuration can be performed within the subsystem class.
- WPILib
- AdvantageKit
// Create the SysId routine
var sysIdRoutine = new SysIdRoutine(
new SysIdRoutine.Config(),
new SysIdRoutine.Mechanism(
(voltage) -> subsystem.runVolts(voltage.in(Volts)),
null, // No log consumer, since data is recorded by URCL
subsystem
)
);
// The methods below return Command objects
sysIdRoutine.quasistatic(SysIdRoutine.Direction.kForward);
sysIdRoutine.quasistatic(SysIdRoutine.Direction.kReverse);
sysIdRoutine.dynamic(SysIdRoutine.Direction.kForward);
sysIdRoutine.dynamic(SysIdRoutine.Direction.kReverse);
// Create the SysId routine
var sysIdRoutine = new SysIdRoutine(
new SysIdRoutine.Config(
null, null, null,
(state) -> Logger.recordOutput("SysIdTestState", state.toString())
),
new SysIdRoutine.Mechanism(
(voltage) -> subsystem.runVolts(voltage.in(Volts)),
null, // No log consumer, since data is recorded by URCL
subsystem
)
);
// The methods below return Command objects
sysIdRoutine.quasistatic(SysIdRoutine.Direction.kForward);
sysIdRoutine.quasistatic(SysIdRoutine.Direction.kReverse);
sysIdRoutine.dynamic(SysIdRoutine.Direction.kForward);
sysIdRoutine.dynamic(SysIdRoutine.Direction.kReverse);
-
Run the SysId routine on the robot. The SysId commands can be configured as auto routines or connected to a button trigger.
-
Download the log file and open it in AdvantageScope. In the menu bar, go to
File
>Export Data...
. Set the format to "WPILOG" and the field set to "Include Generated". Click the save icon and choose a location to save the log.
The log file from the robot must be opened and exported by AdvantageScope before opening it using the SysId analyzer. This is required to convert the CAN data recorded by URCL to a format compatible with SysId.
-
Open the SysId analyzer by searching for "WPILib: Start Tool" in the VSCode command palette and choosing "SysId" (or using the desktop launcher on Windows). Open the exported log file by clicking "Open data log file..."
-
Choose the following fields below to run the analysis using the default encoder. Position and velocity data from secondary encoders can also be used (alternate, external, analog, absolute, etc).
- Position = "NT:/URCL/<Device>/MotorPositionRotations"
- Velocity = "NT:/URCL/<Device>/MotorVelocityRPM"
- Voltage = "NT:/URCL/<Device>/AppliedOutputVoltage"
The gains produced by SysId will use the units the Spark Max/Flex is configured to report (using setPositionConversionFactor
and setVelocityConversionFactor
). By default, these are rotations and RPM with no gearing applied. If the units used when recording data do not match the desired units, the scaling can be adjusted in SysId during analysis.