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
14 changes: 7 additions & 7 deletions URCL.json
spacey-sooty marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
{
"fileName": "URCL.json",
"name": "URCL",
"version": "2024.1.0",
"version": "2024.2.0",
"frcYear": "2024",
"uuid": "84246d17-a797-4d1e-bd9f-c59cd8d2477c",
"mavenUrls": [
"https://raw.githubusercontent.com/Mechanical-Advantage/URCL/2024.1.0"
"https://raw.githubusercontent.com/Mechanical-Advantage/URCL/2024.2.0"
],
"jsonUrl": "https://raw.githubusercontent.com/Mechanical-Advantage/URCL/maven/URCL.json",
"javaDependencies": [
{
"groupId": "org.littletonrobotics.urcl",
"artifactId": "URCL-java",
"version": "2024.1.0"
"version": "2024.2.0"
}
],
"jniDependencies": [
{
"groupId": "org.littletonrobotics.urcl",
"artifactId": "URCL-driver",
"version": "2024.1.0",
"version": "2024.2.0",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
Expand All @@ -34,7 +34,7 @@
{
"groupId": "org.littletonrobotics.urcl",
"artifactId": "URCL-cpp",
"version": "2024.1.0",
"version": "2024.2.0",
"libName": "URCL",
"headerClassifier": "headers",
"sharedLibrary": false,
Expand All @@ -49,7 +49,7 @@
{
"groupId": "org.littletonrobotics.urcl",
"artifactId": "URCL-driver",
"version": "2024.1.0",
"version": "2024.2.0",
"libName": "URCLDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
Expand All @@ -62,4 +62,4 @@
]
}
]
}
}
2 changes: 1 addition & 1 deletion publish.gradle
spacey-sooty marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'maven-publish'

ext.licenseFile = files("$rootDir/LICENSE.txt")

def pubVersion = '2024.1.0'
def pubVersion = '2024.2.0'

def outputsFolder = file("$buildDir/outputs")

Expand Down
70 changes: 54 additions & 16 deletions src/main/java/org/littletonrobotics/urcl/URCL.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@

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.DataLogManager;
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 +47,10 @@ public class URCL {
private static RawPublisher periodicPublisher;
private static RawPublisher aliasesPublisher;
private static Notifier notifier;
private static final DataLog datalog = DataLogManager.getLog();
private static RawLogEntry persistentLogEntry = new RawLogEntry(datalog, "URCL/Raw/Persistent");
spacey-sooty marked this conversation as resolved.
Show resolved Hide resolved
private static RawLogEntry periodicLogEntry = new RawLogEntry(datalog, "/URCL/Raw/Periodic");
private static RawLogEntry aliasLogEntry = new RawLogEntry(datalog, "/URCL/Raw/Aliases");

/**
* Start capturing data from REV motor controllers to NetworkTables. This method
Expand All @@ -56,10 +63,31 @@ public static void start() {
/**
* Start capturing data from REV motor controllers to NetworkTables. This method
* should only be called once.
*
*
* @param withNT Whether or not to run with NetworkTables.
*/
public static void start(boolean withNT) {
start(Map.of(), withNT);
}

/**
* 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) {
start(aliases, true);
}

/**
* 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.
* @param withNT Whether or not to run with NetworkTables.
*/
public static void start(Map<Integer, String> aliases, boolean withNT) {
spacey-sooty marked this conversation as resolved.
Show resolved Hide resolved
if (running) {
DriverStation.reportError("URCL cannot be started multiple times", true);
return;
Expand All @@ -68,30 +96,40 @@ public static void start(Map<Integer, String> aliases) {

// 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);

// Start publishers
persistentPublisher = NetworkTableInstance.getDefault()
if (withNT) {
// Start publishers
persistentPublisher = NetworkTableInstance.getDefault()
.getRawTopic("/URCL/Raw/Persistent")
.publish("URCLr2_persistent");
periodicPublisher = NetworkTableInstance.getDefault()
periodicPublisher = NetworkTableInstance.getDefault()
.getRawTopic("/URCL/Raw/Periodic")
.publish("URCLr2_periodic");
aliasesPublisher = NetworkTableInstance.getDefault()
aliasesPublisher = NetworkTableInstance.getDefault()
.getRawTopic("/URCL/Raw/Aliases")
.publish("URCLr2_aliases");
notifier = new Notifier(() -> {
var data = getData();
persistentPublisher.set(data[0]);
periodicPublisher.set(data[1]);
aliasesPublisher.set(data[2]);
});
notifier = new Notifier(() -> {
var data = getData();
persistentPublisher.set(data[0]);
periodicPublisher.set(data[1]);
aliasesPublisher.set(data[2]);
});
} else {
notifier = new Notifier(() -> {
var data = getData();
persistentLogEntry.append(data[0]);
periodicLogEntry.append(data[1]);
aliasLogEntry.append(data[2]);
});
}

notifier.setName("URCL");
notifier.startPeriodic(period);
}
Expand All @@ -101,7 +139,7 @@ public static void start(Map<Integer, String> aliases) {
* <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,7 +151,7 @@ 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
*/
Expand Down
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
35 changes: 29 additions & 6 deletions src/main/native/cpp/URCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

#include <frc/Errors.h>
#include <frc/Notifier.h>
#include <frc/DataLogManager.h>
#include <networktables/NetworkTableInstance.h>
#include <networktables/RawTopic.h>
#include <string_view>
#include <wpi/DataLog.h>
#include <units/time.h>
#include <cstring>
Expand All @@ -26,15 +28,15 @@ static constexpr auto period = 20_ms;
bool URCL::running = false;
char* URCL::persistentBuffer = nullptr;
char* URCL::periodicBuffer = nullptr;
nt::RawPublisher URCL::persistentPublisher =
nt::RawPublisher URCL::persistentPublisher =
nt::NetworkTableInstance::GetDefault()
.GetRawTopic("/URCL/Raw/Persistent")
.Publish("URCLr2_persistent");
nt::RawPublisher URCL::periodicPublisher =
nt::RawPublisher URCL::periodicPublisher =
nt::NetworkTableInstance::GetDefault()
.GetRawTopic("/URCL/Raw/Periodic")
.Publish("URCLr2_periodic");
nt::RawPublisher URCL::aliasesPublisher =
nt::RawPublisher URCL::aliasesPublisher =
nt::NetworkTableInstance::GetDefault()
.GetRawTopic("/URCL/Raw/Aliases")
.Publish("URCLr2_aliases");
Expand All @@ -45,7 +47,18 @@ void URCL::Start() {
URCL::Start(aliases);
}

void URCL::Start(bool withNT) {
std::map<int, std::string_view> aliases;
URCL::Start(aliases, withNT);
}

void URCL::Start(std::map<int, std::string_view> aliases) {
URCL::Start(aliases, true);
}

void URCL::Start(std::map<int, std::string_view> aliases, bool withNT) {
URCL::withNT = withNT;

if (running) {
FRC_ReportError(frc::err::Error, "{}", "URCL cannot be started multiple times");
return;
Expand Down Expand Up @@ -77,6 +90,11 @@ void URCL::Start(std::map<int, std::string_view> aliases) {
persistentBuffer = URCLDriver_getPersistentBuffer();
periodicBuffer = URCLDriver_getPeriodicBuffer();

persistentLogEntry = wpi::log::RawLogEntry{frc::DataLogManager::GetLog(), "/URCL/Raw/Persistent"};
periodicLogEntry = wpi::log::RawLogEntry{frc::DataLogManager::GetLog(), "/URCL/Raw/Periodic"};
aliasesLogEntry = wpi::log::RawLogEntry{frc::DataLogManager::GetLog(), "/URCL/Raw/Aliases"};
spacey-sooty marked this conversation as resolved.
Show resolved Hide resolved
aliasesLogEntry.Append(aliasesVector);

// Start notifier
notifier.SetName("URCL");
notifier.StartPeriodic(period);
Expand All @@ -92,6 +110,11 @@ void URCL::Periodic() {
std::vector<uint8_t> periodicVector(periodicSize);
std::memcpy(persistentVector.data(), persistentBuffer + 4, persistentVector.size());
std::memcpy(periodicVector.data(), periodicBuffer + 4, periodicVector.size());
persistentPublisher.Set(persistentVector);
periodicPublisher.Set(periodicVector);
}
if (withNT) {
persistentPublisher.Set(persistentVector);
periodicPublisher.Set(periodicVector);
} else {
persistentLogEntry.Append(persistentVector);
periodicLogEntry.Append(periodicVector);
}
}
Loading