Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to run without NetworkTables #7

Merged
merged 14 commits into from
Sep 3, 2024
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,7 @@ bin/


# End of https://www.gitignore.io/api/c++,java,linux,macos,gradle,windows,visualstudiocode

# clangd
/.cache
compile_commands.json
2 changes: 1 addition & 1 deletion URCL.json
spacey-sooty marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@
]
}
]
}
}
18 changes: 9 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ apply from: 'config.gradle'

// Apply Java configuration
dependencies {
implementation 'edu.wpi.first.cscore:cscore-java:2024.+'
implementation 'edu.wpi.first.cameraserver:cameraserver-java:2024.+'
implementation 'edu.wpi.first.ntcore:ntcore-java:2024.+'
implementation 'edu.wpi.first.wpilibj:wpilibj-java:2024.+'
implementation 'edu.wpi.first.wpiutil:wpiutil-java:2024.+'
implementation 'edu.wpi.first.wpimath:wpimath-java:2024.+'
implementation 'edu.wpi.first.wpiunits:wpiunits-java:2024.+'
implementation 'edu.wpi.first.hal:hal-java:2024.+'
implementation 'edu.wpi.first.cscore:cscore-java:2025.+'
implementation 'edu.wpi.first.cameraserver:cameraserver-java:2025.+'
implementation 'edu.wpi.first.ntcore:ntcore-java:2025.+'
implementation 'edu.wpi.first.wpilibj:wpilibj-java:2025.+'
implementation 'edu.wpi.first.wpiutil:wpiutil-java:2025.+'
implementation 'edu.wpi.first.wpimath:wpimath-java:2025.+'
implementation 'edu.wpi.first.wpiunits:wpiunits-java:2025.+'
implementation 'edu.wpi.first.hal:hal-java:2025.+'
implementation "org.ejml:ejml-simple:0.43.1"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.12.4"
implementation "com.fasterxml.jackson.core:jackson-core:2.12.4"
implementation "com.fasterxml.jackson.core:jackson-databind:2.12.4"
implementation 'edu.wpi.first.thirdparty.frc2024.opencv:opencv-java:4.8.0-2'
// implementation 'edu.wpi.first.thirdparty.frc2024.opencv:opencv-java:4.8.0-2'
}

// Set up exports properly
Expand Down
2 changes: 1 addition & 1 deletion config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ nativeUtils.withCrossRoboRIO()
nativeUtils {
wpi {
configureDependencies {
wpiVersion = "2024.+"
wpiVersion = "2025.+"
opencvYear = "frc2024"
googleTestYear = "frc2024"
niLibVersion = "2024.2.1"
Expand Down
78 changes: 66 additions & 12 deletions src/main/java/org/littletonrobotics/urcl/URCL.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@

import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.networktables.RawPublisher;
import edu.wpi.first.util.datalog.DataLog;
import edu.wpi.first.util.datalog.RawLogEntry;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.Notifier;

/**
* <h2>URCL (Unofficial REV-Compatible Logger)</h2>
*
*
* This unofficial logger enables automatic capture of CAN traffic from REV
* motor controllers to NetworkTables, viewable using AdvantageScope. See the
* corresponding <a href=
* "https://github.com/Mechanical-Advantage/AdvantageScope/blob/main/docs/REV-LOGGING.md">
* AdvantageScope documentation</a> for more details.
*
*
* <p>
* <b>As this library is not an official REV tool, support queries should be
* directed to the URCL
Expand All @@ -44,6 +46,9 @@ public class URCL {
private static RawPublisher periodicPublisher;
private static RawPublisher aliasesPublisher;
private static Notifier notifier;
private static RawLogEntry persistentLogEntry;
private static RawLogEntry periodicLogEntry;
private static RawLogEntry aliasLogEntry;

/**
* Start capturing data from REV motor controllers to NetworkTables. This method
Expand All @@ -53,10 +58,20 @@ public static void start() {
start(Map.of());
}

/**
* Start capturing data from REV motor controllers to a Datalog. This method
* should only be called once.
*
* @param log the DataLog to log to.
*/
public static void start(DataLog log) {
start(Map.of(), log);
}

/**
* Start capturing data from REV motor controllers to NetworkTables. This method
* should only be called once.
*
*
* @param aliases The set of aliases mapping CAN IDs to names.
*/
public static void start(Map<Integer, String> aliases) {
Expand All @@ -68,7 +83,7 @@ public static void start(Map<Integer, String> aliases) {

// Update aliases buffer
updateAliasesBuffer(aliases);

// Start driver
URCLJNI.start();
persistentBuffer = URCLJNI.getPersistentBuffer();
Expand Down Expand Up @@ -96,12 +111,51 @@ public static void start(Map<Integer, String> aliases) {
notifier.startPeriodic(period);
}

/**
* Start capturing data from REV motor controllers to a DataLog. This method
* should only be called once.
*
* @param aliases The set of aliases mapping CAN IDs to names.
* @param log the DataLog to log to. Note using a DataLog means it will not
* log to NetworkTables.
*/
public static void start(Map<Integer, String> aliases, DataLog log) {
if (running) {
DriverStation.reportError("URCL cannot be started multiple times", true);
return;
}
running = true;

// Update aliases buffer
updateAliasesBuffer(aliases);

// Start driver
URCLJNI.start();
persistentBuffer = URCLJNI.getPersistentBuffer();
periodicBuffer = URCLJNI.getPeriodicBuffer();
persistentBuffer.order(ByteOrder.LITTLE_ENDIAN);
periodicBuffer.order(ByteOrder.LITTLE_ENDIAN);

persistentLogEntry = new RawLogEntry(log, "URCL/Raw/Persistent", "",
"URCLr2_persistent");
periodicLogEntry = new RawLogEntry(log, "/URCL/Raw/Periodic", "", "URCLr2_periodic");
aliasLogEntry = new RawLogEntry(log, "/URCL/Raw/Aliases", "", "URCLr2_aliases");
notifier = new Notifier(() -> {
var data = getData();
persistentLogEntry.update(data[0]);
periodicLogEntry.append(data[1]);
aliasLogEntry.update(data[2]);
});
notifier.setName("URCL");
notifier.startPeriodic(period);
}

/**
* Start capturing data from REV motor controllers to an external framework like
* <a href=
* "https://github.com/Mechanical-Advantage/AdvantageKit">AdvantageKit</a>. This
* method should only be called once.
*
*
* @return The log supplier, to be called periodically
*/
public static Supplier<ByteBuffer[]> startExternal() {
Expand All @@ -113,17 +167,17 @@ public static Supplier<ByteBuffer[]> startExternal() {
* <a href=
* "https://github.com/Mechanical-Advantage/AdvantageKit">AdvantageKit</a>. This
* method should only be called once.
*
*
* @param aliases The set of aliases mapping CAN IDs to names.
* @return The log supplier, to be called periodically
*/
public static Supplier<ByteBuffer[]> startExternal(Map<Integer, String> aliases) {
if (running) {
DriverStation.reportError("URCL cannot be started multiple times", true);
ByteBuffer[] emptyOutput = new ByteBuffer[] {
ByteBuffer.allocate(0),
ByteBuffer.allocate(0),
ByteBuffer.allocate(0)
ByteBuffer.allocate(0),
ByteBuffer.allocate(0),
ByteBuffer.allocate(0)
};
return () -> emptyOutput;
}
Expand Down Expand Up @@ -167,9 +221,9 @@ private static ByteBuffer[] getData() {
int persistentSize = persistentBuffer.getInt(0);
int periodicSize = periodicBuffer.getInt(0);
return new ByteBuffer[] {
persistentBuffer.slice(4, persistentSize),
periodicBuffer.slice(4, periodicSize),
aliasesBuffer
persistentBuffer.slice(4, persistentSize),
periodicBuffer.slice(4, periodicSize),
aliasesBuffer
};
}
}
24 changes: 10 additions & 14 deletions src/main/java/org/littletonrobotics/urcl/URCLJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.littletonrobotics.urcl;

import java.io.IOException;
import java.lang.System;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;

Expand All @@ -18,7 +19,6 @@
*/
public class URCLJNI {
static boolean libraryLoaded = false;
static RuntimeLoader<URCLJNI> loader = null;

/**
* Helper class for determining whether or not to load the driver on static
Expand All @@ -29,7 +29,7 @@ public static class Helper {

/**
* Get whether to load the driver on static init.
*
*
* @return true if the driver will load on static init
*/
public static boolean getExtractOnStaticLoad() {
Expand All @@ -38,7 +38,7 @@ public static boolean getExtractOnStaticLoad() {

/**
* Set whether to load the driver on static init.
*
*
* @param load the new value
*/
public static void setExtractOnStaticLoad(boolean load) {
Expand All @@ -49,9 +49,7 @@ public static void setExtractOnStaticLoad(boolean load) {
static {
if (Helper.getExtractOnStaticLoad()) {
try {
loader = new RuntimeLoader<>("URCLDriver", RuntimeLoader.getDefaultExtractionRoot(),
URCLJNI.class);
loader.loadLibrary();
RuntimeLoader.loadLibrary("URCLDriver");
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
Expand All @@ -62,32 +60,30 @@ public static void setExtractOnStaticLoad(boolean load) {

/**
* Force load the library.
*
*
* @throws java.io.IOException thrown if the native library cannot be found
*/
public static synchronized void forceLoad() throws IOException {
if (libraryLoaded) {
return;
}
loader = new RuntimeLoader<>("URCLDriver", RuntimeLoader.getDefaultExtractionRoot(),
URCLJNI.class);
loader.loadLibrary();
RuntimeLoader.loadLibrary("URCLDriver");
libraryLoaded = true;
}

/** Start logging. */
public static native void start();

/**
/**
* Get the shared buffer with persistent data.
*
*
* @return The shared buffer
*/
public static native ByteBuffer getPersistentBuffer();

/**
/**
* Get the shared buffer with periodic data.
*
*
* @return The shared buffer
*/
public static native ByteBuffer getPeriodicBuffer();
Expand Down
Loading
Loading