-
Notifications
You must be signed in to change notification settings - Fork 7
Home
1. n. A one-sided conversation.
Monologue is a Java annotation-based logging library for FRC. With Monologue, extensive telemetry and on-robot logging can be added to your robot code with minimal code footprint and design restrictions.
For teams already familiar with Oblog, the setup process for Monologue is very similar.
The first step to using Monologue is to add it to your robot project as a dependency. Monologue is distributed using jitpack.
To add the dependency, we only need to add a couple lines to your project’s build.gradle. First, add the following:
repositories {
maven { url 'https://jitpack.io' }
}
Secondly, add the following to the dependencies
list:
implementation 'com.github.shueja:Monologue:RELEASE_TAG'
where RELEASE_TAG is the latest release version tag (e.g. v1.0.0).
The first step of setting up Monologue is choosing a base class. Robot.java
is a good choice for this, though for command-based teams, RobotContainer.java
is a good alternative. The important part is to setup the logger after all contained classes have been constructed, typically at the end of robotInit()
or the RobotContainer
constructor. Your base class needs to implement monologue.Logged
, so that Monologue can create a level in the logging structure for it.
A basic configuration for a simple TimedRobot project would be like this:
package frc.robot;
import monologue.Monologue;
import monologue.Logged;
public class Robot extends TimedRobot implements Logged {
@Override
public void robotInit() {
...
boolean fileOnly = false;
boolean lazyLogging = false;
Monologue.setupMonologue(this, "/Robot", fileOnly, lazyLogging);
}
@Override
public void robotPeriodic() {
// setFileOnly is used to shut off NetworkTables broadcasting for most logging calls.
// Basing this condition on the connected state of the FMS is a suggestion only.
Monologue.setFileOnly(DriverStation.isFMSConnected());
Monologue.updateAll();
}
}
The first argument to Monologue.setupLogging()
is the root Logged
class, which is Robot, or this
. The second argument is the path to use for the root container. In this case, values being logged would show up in NetworkTables and DataLog under /Robot/variableName
.
IMPORTANT: Ensure your path starts with a forward slash
/
to comply with NetworkTables convention.
That is all that is required to configure Monologue to capture all your logged values periodically, publish them to NetworkTables, and add them to the on-robot data logging. Next, let's set up some values to log.
Monologue offers two annotations (@Log.NT
, @Log.File
), which can be applied to variables of supported types, or methods that return the supported types. Note that any method you apply the annotation to will be run every periodic loop. To use these, simply annotate the field or method with the desired annotation. The class containing the annotated field must implement Logged
, even your root container. Once a class has been declared Logged
, Monologue will automatically search it for annotated fields and getters to capture - as long as it is reachable from the specified root through a direct sequence of Logged
parent classes (the logger will recursively search down the tree of all Logged
fields from the root container and place the values in the NT/DataLog tree according to the class structure.).
- Primitives:
int, long, float, double, boolean
- Primitive arrays:
int[], long[], float[], double[], boolean[]
- String and String[] (note that logging Strings is significantly more performance-heavy than logging primitives)
- WPILib struct-serializable types: for example, geometry types (Pose2d, etc), other simple structured data (SwerveModuleState, etc). For the full list of struct-serializable types, see the implementing classes of StructSerializable in WPILib's Javadocs.
- Arrays of the above struct-serializable types.
- Sendables such as Field2d and Mechanism2d. (Note that these will always publish to NetworkTables, and ignore the file-only and lazy-logging features of Monologue. This is due to limitations in the Sendable API.)