From c6ae40cfe2b8c7977d29dc4ef7a8909e7986b30f Mon Sep 17 00:00:00 2001 From: Jonah <47046556+jwbonner@users.noreply.github.com> Date: Tue, 12 Mar 2024 19:44:00 -0400 Subject: [PATCH 1/2] Add GC stats to LoggedRobot --- .../junction/LoggedRobot.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/junction/core/src/org/littletonrobotics/junction/LoggedRobot.java b/junction/core/src/org/littletonrobotics/junction/LoggedRobot.java index 7cb6d8d9..1ea86aa9 100644 --- a/junction/core/src/org/littletonrobotics/junction/LoggedRobot.java +++ b/junction/core/src/org/littletonrobotics/junction/LoggedRobot.java @@ -13,6 +13,10 @@ package org.littletonrobotics.junction; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; + import edu.wpi.first.hal.DriverStationJNI; import edu.wpi.first.hal.FRCNetComm.tInstances; import edu.wpi.first.hal.FRCNetComm.tResourceType; @@ -32,11 +36,11 @@ * Notifier instance. */ public class LoggedRobot extends IterativeRobotBase { - public static final double defaultPeriodSecs = 0.02; private final int notifier = NotifierJNI.initializeNotifier(); private final long periodUs; private long nextCycleUs = 0; + private final GcStatsCollector gcStatsCollector = new GcStatsCollector(); private boolean useTiming = true; @@ -113,6 +117,7 @@ public void startCompetition() { loopFunc(); long userCodeEnd = Logger.getRealTimestamp(); + gcStatsCollector.update(); Logger.periodicAfterUser(userCodeEnd - userCodeStart, userCodeStart - periodicBeforeStart); } } @@ -127,4 +132,27 @@ public void endCompetition() { public void setUseTiming(boolean useTiming) { this.useTiming = useTiming; } + + private static final class GcStatsCollector { + private List gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); + private final long[] lastTimes = new long[gcBeans.size()]; + private final long[] lastCounts = new long[gcBeans.size()]; + + public void update() { + long accumTime = 0; + long accumCounts = 0; + for (int i = 0; i < gcBeans.size(); i++) { + long gcTime = gcBeans.get(i).getCollectionTime(); + long gcCount = gcBeans.get(i).getCollectionCount(); + accumTime += gcTime - lastTimes[i]; + accumCounts += gcCount - lastCounts[i]; + + lastTimes[i] = gcTime; + lastCounts[i] = gcCount; + } + + Logger.recordOutput("LoggedRobot/GCTimeMS", (double) accumTime); + Logger.recordOutput("LoggedRobot/GCCounts", (double) accumCounts); + } + } } From ce678df853418419a5712587efafe426c44ab023 Mon Sep 17 00:00:00 2001 From: Jonah <47046556+jwbonner@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:43:15 -0400 Subject: [PATCH 2/2] Add method to disable console capture --- .../littletonrobotics/junction/Logger.java | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/junction/core/src/org/littletonrobotics/junction/Logger.java b/junction/core/src/org/littletonrobotics/junction/Logger.java index 95d6c025..7f3fb1bb 100644 --- a/junction/core/src/org/littletonrobotics/junction/Logger.java +++ b/junction/core/src/org/littletonrobotics/junction/Logger.java @@ -64,10 +64,11 @@ public class Logger { private static LogTable entry = new LogTable(0); private static LogTable outputTable; private static Map metadata = new HashMap<>(); - private static ConsoleSource console; + private static ConsoleSource console = null; private static List dashboardInputs = new ArrayList<>(); private static Supplier urclSupplier = null; private static boolean deterministicTimestamps = true; + private static boolean enableConsole = false; private static LogReplaySource replaySource; private static final BlockingQueue receiverQueue = new ArrayBlockingQueue(receiverQueueCapcity); @@ -160,6 +161,13 @@ public static void disableDeterministicTimestamps() { deterministicTimestamps = false; } + /** + * Disables automatic console capture. + */ + public static void disableConsoleCapture() { + enableConsole = false; + } + /** * Returns whether a replay source is currently being used. */ @@ -176,10 +184,12 @@ public static void start() { running = true; // Start console capture - if (RobotBase.isReal()) { - console = new RIOConsoleSource(); - } else { - console = new SimConsoleSource(); + if (enableConsole) { + if (RobotBase.isReal()) { + console = new RIOConsoleSource(); + } else { + console = new SimConsoleSource(); + } } // Start replay source @@ -217,10 +227,12 @@ public static void start() { public static void end() { if (running) { running = false; - try { - console.close(); - } catch (Exception e) { - DriverStation.reportError("Failed to stop console capture.", true); + if (console != null) { + try { + console.close(); + } catch (Exception e) { + DriverStation.reportError("Failed to stop console capture.", true); + } } if (replaySource != null) { replaySource.end(); @@ -316,9 +328,11 @@ static void periodicAfterUser(long userCodeLength, long periodicBeforeLength) { long autoLogStart = getRealTimestamp(); AutoLogOutputManager.periodic(); long consoleCaptureStart = getRealTimestamp(); - String consoleData = console.getNewData(); - if (!consoleData.isEmpty()) { - recordOutput("Console", consoleData.trim()); + if (enableConsole) { + String consoleData = console.getNewData(); + if (!consoleData.isEmpty()) { + recordOutput("Console", consoleData.trim()); + } } long consoleCaptureEnd = getRealTimestamp();