From c32594859b814e005eba92966cb77f8177bc2ff8 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Mon, 20 Mar 2023 16:09:40 -0700 Subject: [PATCH 01/11] remove temp limit --- .../org/carlmontrobotics/lib199/MotorErrors.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java index 981669dd..ab5472b2 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java @@ -15,12 +15,15 @@ public final class MotorErrors { private static final HashMap temperatureSparks = new HashMap<>(); private static final HashMap sparkTemperatureLimits = new HashMap<>(); - private static final ArrayList overheatedSparks = new ArrayList<>(); + private static final HashMap overheatedSparks = new HashMap<>(); private static final HashMap flags = new HashMap<>(); private static final HashMap stickyFlags = new HashMap<>(); + public static final int kOverheatTripCount = 5; + static { Lib199Subsystem.registerPeriodic(MotorErrors::doReportSparkMaxTemp); + Lib199Subsystem.registerPeriodic(MotorErrors::printSparkMaxErrorMessages); } public static void reportError(ErrorCode error) { @@ -108,6 +111,7 @@ public static void reportSparkMaxTemp(CANSparkMax spark, int temperatureLimit) { int id = spark.getDeviceId(); temperatureSparks.put(id, spark); sparkTemperatureLimits.put(id, temperatureLimit); + overheatedSparks.put(id, 0); } public static void doReportSparkMaxTemp() { @@ -115,12 +119,12 @@ public static void doReportSparkMaxTemp() { double temp = spark.getMotorTemperature(); SmartDashboard.putNumber("Port " + port + " Spark Max Temp", temp); // Check if temperature exceeds the setpoint or if the contoller has already overheated to prevent other code from resetting the current limit after the controller has cooled - if(temp >= sparkTemperatureLimits.get(port) || overheatedSparks.contains(port)) { - if(!overheatedSparks.contains(port)) { - overheatedSparks.add(port); + if(temp >= sparkTemperatureLimits.get(port) || overheatedSparks.get(port) >= kOverheatTripCount) { + if(overheatedSparks.get(port) < kOverheatTripCount + 1) { + overheatedSparks.put(port, kOverheatTripCount + 1); System.err.println("Port " + port + " spark max is operating at " + temp + " degrees Celsius! It will be disabled until the robot code is restarted."); } - spark.setSmartCurrentLimit(1); + // spark.setSmartCurrentLimit(1); } }); } From 909eaf38c7c27d12b6dee307e968b80240b3cc00 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Mon, 20 Mar 2023 16:11:17 -0700 Subject: [PATCH 02/11] disable failing test --- src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java index dde70623..df2d8508 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java @@ -155,6 +155,7 @@ public void testDummySparkMax() { @Test public void testReportSparkMaxTemp() { + if(true) return; doTestReportSparkMaxTemp(0); doTestReportSparkMaxTemp(1); doTestReportSparkMaxTemp(2); From 6977fd98c615cfb952177f232de8d9d1418e4ad1 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Fri, 24 Mar 2023 19:06:18 -0700 Subject: [PATCH 03/11] empty commit From c1eee3c0351ef1fbe70c0182fe86d5e068d4c6c6 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 1 Apr 2023 22:55:51 -0700 Subject: [PATCH 04/11] fix #37 --- .../{ => lib199}/MotorConfig.java | 2 +- .../lib199/MotorControllerFactory.java | 1 - .../carlmontrobotics/lib199/MotorErrors.java | 18 ++++++-- .../lib199/swerve/SwerveModule.java | 2 +- .../lib199/MotorControllerFactoryTest.java | 1 - .../lib199/MotorErrorsTest.java | 44 +++++++++++++++---- 6 files changed, 51 insertions(+), 17 deletions(-) rename src/main/java/org/carlmontrobotics/{ => lib199}/MotorConfig.java (91%) diff --git a/src/main/java/org/carlmontrobotics/MotorConfig.java b/src/main/java/org/carlmontrobotics/lib199/MotorConfig.java similarity index 91% rename from src/main/java/org/carlmontrobotics/MotorConfig.java rename to src/main/java/org/carlmontrobotics/lib199/MotorConfig.java index 7915bed0..5d2417b4 100644 --- a/src/main/java/org/carlmontrobotics/MotorConfig.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorConfig.java @@ -1,4 +1,4 @@ -package org.carlmontrobotics; +package org.carlmontrobotics.lib199; public class MotorConfig { diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java b/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java index df3dd8eb..61462212 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java @@ -17,7 +17,6 @@ import com.revrobotics.CANSparkMaxLowLevel; import com.revrobotics.SparkMaxPIDController; -import org.carlmontrobotics.MotorConfig; import org.carlmontrobotics.lib199.sim.MockSparkMax; import org.carlmontrobotics.lib199.sim.MockTalonSRX; import org.carlmontrobotics.lib199.sim.MockVictorSPX; diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java index ab5472b2..020c474a 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java @@ -1,6 +1,5 @@ package org.carlmontrobotics.lib199; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -117,14 +116,25 @@ public static void reportSparkMaxTemp(CANSparkMax spark, int temperatureLimit) { public static void doReportSparkMaxTemp() { temperatureSparks.forEach((port, spark) -> { double temp = spark.getMotorTemperature(); + double limit = sparkTemperatureLimits.get(port); + int numTrips = overheatedSparks.get(port); SmartDashboard.putNumber("Port " + port + " Spark Max Temp", temp); + + if(temp > limit) { + if(numTrips < kOverheatTripCount) { + overheatedSparks.put(port, ++numTrips); + } + } else { + overheatedSparks.put(port, 0); + } + // Check if temperature exceeds the setpoint or if the contoller has already overheated to prevent other code from resetting the current limit after the controller has cooled - if(temp >= sparkTemperatureLimits.get(port) || overheatedSparks.get(port) >= kOverheatTripCount) { - if(overheatedSparks.get(port) < kOverheatTripCount + 1) { + if(numTrips >= kOverheatTripCount) { + if(numTrips < kOverheatTripCount + 1) { overheatedSparks.put(port, kOverheatTripCount + 1); System.err.println("Port " + port + " spark max is operating at " + temp + " degrees Celsius! It will be disabled until the robot code is restarted."); } - // spark.setSmartCurrentLimit(1); + spark.setSmartCurrentLimit(1); } }); } diff --git a/src/main/java/org/carlmontrobotics/lib199/swerve/SwerveModule.java b/src/main/java/org/carlmontrobotics/lib199/swerve/SwerveModule.java index 202dc0f0..b49ade03 100644 --- a/src/main/java/org/carlmontrobotics/lib199/swerve/SwerveModule.java +++ b/src/main/java/org/carlmontrobotics/lib199/swerve/SwerveModule.java @@ -174,7 +174,7 @@ private double calculateAntiGravitationalA(Float gyroPitchDeg, Float gyroRollDeg double g = 9.81; //meters per second squared // gravitationalA is estimated to work for small angles, not 100% accurate at large angles double antiGravitationalA = g * (modulePitchComponent * Math.sin(Math.PI * gyroPitchDeg / 180) - moduleRollComponent * Math.sin(Math.PI * gyroRollDeg / 180)); - SmartDashboard.putNumber("AntiGravitational accelration", antiGravitationalA); + SmartDashboard.putNumber("AntiGravitational acceleration", antiGravitationalA); return antiGravitationalA; } /** diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorControllerFactoryTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorControllerFactoryTest.java index 76a9e223..d0791dbf 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorControllerFactoryTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorControllerFactoryTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; -import org.carlmontrobotics.MotorConfig; import org.carlmontrobotics.lib199.testUtils.ErrStreamTest; import org.carlmontrobotics.lib199.testUtils.SimDeviceTestRule; import org.junit.ClassRule; diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java index df2d8508..ca614453 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; import com.ctre.phoenix.ErrorCode; import com.revrobotics.REVLibError; @@ -45,7 +46,7 @@ public static interface TemperatureSparkMax { public static class Instance { - private int smartCurrentLimit = 50; + private int smartCurrentLimit = MotorConfig.NEO.currentLimit; private double temperature = 30; private final int id; @@ -155,7 +156,8 @@ public void testDummySparkMax() { @Test public void testReportSparkMaxTemp() { - if(true) return; + assertTrue(MotorErrors.kOverheatTripCount > 0); + doTestReportSparkMaxTemp(0); doTestReportSparkMaxTemp(1); doTestReportSparkMaxTemp(2); @@ -163,32 +165,56 @@ public void testReportSparkMaxTemp() { private void doTestReportSparkMaxTemp(int id) { TemperatureSparkMax spark = (TemperatureSparkMax)Mocks.createMock(CANSparkMax.class, new TemperatureSparkMax.Instance(id), TemperatureSparkMax.class); + String smartDashboardKey = "Port " + id + " Spark Max Temp"; MotorErrors.reportSparkMaxTemp((CANSparkMax)spark, 40); spark.setSmartCurrentLimit(50); + spark.setTemperature(20); CommandScheduler.getInstance().run(); - String smartDashboardKey = "Port " + id + " Spark Max Temp"; assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); + spark.setTemperature(20); CommandScheduler.getInstance().run(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); + + if(MotorErrors.kOverheatTripCount > 1) { + spark.setTemperature(51); + CommandScheduler.getInstance().run(); + assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + assertEquals(50, spark.getSmartCurrentLimit()); + + spark.setTemperature(20); + CommandScheduler.getInstance().run(); + assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + assertEquals(50, spark.getSmartCurrentLimit()); + } + assertEquals(0, errStream.size()); - spark.setTemperature(40); - CommandScheduler.getInstance().run(); - assertEquals(40, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); - assertEquals(1, spark.getSmartCurrentLimit()); + + for(int i = 0; i < MotorErrors.kOverheatTripCount; i++) { + assertEquals(50, spark.getSmartCurrentLimit()); + assertEquals(0, errStream.size()); + + spark.setTemperature(51); + CommandScheduler.getInstance().run(); + assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + } + assertNotEquals(0, errStream.size()); errStream.reset(); - spark.setTemperature(50); + + spark.setTemperature(51); CommandScheduler.getInstance().run(); - assertEquals(50, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(1, spark.getSmartCurrentLimit()); + spark.setTemperature(20); CommandScheduler.getInstance().run(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(1, spark.getSmartCurrentLimit()); + assertEquals(0, errStream.size()); } From 47e4d79721e12d628cf9b94c60b95b3f0b40fb94 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 1 Apr 2023 23:10:23 -0700 Subject: [PATCH 05/11] fix logic bug --- src/main/java/org/carlmontrobotics/lib199/MotorErrors.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java index 020c474a..0cee42dc 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java @@ -124,7 +124,7 @@ public static void doReportSparkMaxTemp() { if(numTrips < kOverheatTripCount) { overheatedSparks.put(port, ++numTrips); } - } else { + } else if(numTrips < kOverheatTripCount) { overheatedSparks.put(port, 0); } From 325297b87a543ab17165f48abaa5b8f44b74f320 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 1 Apr 2023 23:18:31 -0700 Subject: [PATCH 06/11] document kOverheatTripCount + 1 --- src/main/java/org/carlmontrobotics/lib199/MotorErrors.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java index 0cee42dc..c3574fca 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java @@ -131,6 +131,8 @@ public static void doReportSparkMaxTemp() { // Check if temperature exceeds the setpoint or if the contoller has already overheated to prevent other code from resetting the current limit after the controller has cooled if(numTrips >= kOverheatTripCount) { if(numTrips < kOverheatTripCount + 1) { + // Set trip count to kOverheatTripCount + 1 to flag that an error message has already been printed + // This prevents the error message from being re-printed every time the periodic method is run overheatedSparks.put(port, kOverheatTripCount + 1); System.err.println("Port " + port + " spark max is operating at " + temp + " degrees Celsius! It will be disabled until the robot code is restarted."); } From 354d6b220f8e26f53e58b7ae772d380a5a84533c Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 1 Apr 2023 23:19:43 -0700 Subject: [PATCH 07/11] simplify logic --- .../java/org/carlmontrobotics/lib199/MotorErrors.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java index c3574fca..375d73ca 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorErrors.java @@ -120,12 +120,12 @@ public static void doReportSparkMaxTemp() { int numTrips = overheatedSparks.get(port); SmartDashboard.putNumber("Port " + port + " Spark Max Temp", temp); - if(temp > limit) { - if(numTrips < kOverheatTripCount) { + if(numTrips < kOverheatTripCount) { + if(temp > limit) { overheatedSparks.put(port, ++numTrips); + } else { + overheatedSparks.put(port, 0); } - } else if(numTrips < kOverheatTripCount) { - overheatedSparks.put(port, 0); } // Check if temperature exceeds the setpoint or if the contoller has already overheated to prevent other code from resetting the current limit after the controller has cooled From 32510fd2fddd0ae03ef892a670236511a8914992 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 6 May 2023 19:20:12 -0700 Subject: [PATCH 08/11] test smartcurrentlimit reset in temperature MotorErrorsTest --- .../java/org/carlmontrobotics/lib199/MotorErrorsTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java index ca614453..c20e1332 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java @@ -167,25 +167,28 @@ private void doTestReportSparkMaxTemp(int id) { TemperatureSparkMax spark = (TemperatureSparkMax)Mocks.createMock(CANSparkMax.class, new TemperatureSparkMax.Instance(id), TemperatureSparkMax.class); String smartDashboardKey = "Port " + id + " Spark Max Temp"; MotorErrors.reportSparkMaxTemp((CANSparkMax)spark, 40); - spark.setSmartCurrentLimit(50); spark.setTemperature(20); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); spark.setTemperature(20); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); if(MotorErrors.kOverheatTripCount > 1) { spark.setTemperature(51); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); spark.setTemperature(20); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); @@ -198,6 +201,7 @@ private void doTestReportSparkMaxTemp(int id) { assertEquals(0, errStream.size()); spark.setTemperature(51); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); } @@ -206,11 +210,13 @@ private void doTestReportSparkMaxTemp(int id) { errStream.reset(); spark.setTemperature(51); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(1, spark.getSmartCurrentLimit()); spark.setTemperature(20); + spark.setSmartCurrentLimit(50); CommandScheduler.getInstance().run(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(1, spark.getSmartCurrentLimit()); From 1b2d9016d7fd55589fed49162e221f1cf7c04499 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sun, 7 May 2023 01:17:16 -0700 Subject: [PATCH 09/11] add units to MotorConfig --- .../java/org/carlmontrobotics/lib199/MotorConfig.java | 8 ++++---- .../carlmontrobotics/lib199/MotorControllerFactory.java | 4 ++-- .../java/org/carlmontrobotics/lib199/MotorErrorsTest.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorConfig.java b/src/main/java/org/carlmontrobotics/lib199/MotorConfig.java index 5d2417b4..f307b2bd 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorConfig.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorConfig.java @@ -5,11 +5,11 @@ public class MotorConfig { public static final MotorConfig NEO = new MotorConfig(70, 40); public static final MotorConfig NEO_550 = new MotorConfig(40, 20); - public final int temperatureLimit, currentLimit; + public final int temperatureLimitCelsius, currentLimitAmps; - public MotorConfig(int temperatureLimit, int currentLimit) { - this.temperatureLimit = temperatureLimit; - this.currentLimit = currentLimit; + public MotorConfig(int temperatureLimitCelsius, int currentLimitAmps) { + this.temperatureLimitCelsius = temperatureLimitCelsius; + this.currentLimitAmps = currentLimitAmps; } } diff --git a/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java b/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java index 61462212..740ca54d 100644 --- a/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java +++ b/src/main/java/org/carlmontrobotics/lib199/MotorControllerFactory.java @@ -129,13 +129,13 @@ public static CANSparkMax createSparkMax(int id, MotorConfig config) { spark = MockSparkMax.createMockSparkMax(id, CANSparkMaxLowLevel.MotorType.kBrushless); } - MotorErrors.reportSparkMaxTemp(spark, config.temperatureLimit); + MotorErrors.reportSparkMaxTemp(spark, config.temperatureLimitCelsius); MotorErrors.reportError(spark.restoreFactoryDefaults()); MotorErrors.reportError(spark.follow(ExternalFollower.kFollowerDisabled, 0)); MotorErrors.reportError(spark.setIdleMode(IdleMode.kBrake)); MotorErrors.reportError(spark.enableVoltageCompensation(12)); - MotorErrors.reportError(spark.setSmartCurrentLimit(config.currentLimit)); + MotorErrors.reportError(spark.setSmartCurrentLimit(config.currentLimitAmps)); MotorErrors.checkSparkMaxErrors(spark); diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java index c20e1332..52ab635b 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java @@ -46,7 +46,7 @@ public static interface TemperatureSparkMax { public static class Instance { - private int smartCurrentLimit = MotorConfig.NEO.currentLimit; + private int smartCurrentLimit = MotorConfig.NEO.currentLimitAmps; private double temperature = 30; private final int id; From 61c8c455b2bef4d3a0070998da14e7b6a7ff3289 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sun, 7 May 2023 01:19:03 -0700 Subject: [PATCH 10/11] remove spaces --- src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java index 52ab635b..b5756ef6 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java @@ -70,7 +70,7 @@ public REVLibError setSmartCurrentLimit(int limit) { smartCurrentLimit = limit; return REVLibError.kOk; } - + public int getDeviceId() { return id; } From c6ef41aed9b88db2c8b35472acf60c25317f9946 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 8 Jul 2023 23:14:42 -0700 Subject: [PATCH 11/11] fix race condition --- .../lib199/MotorErrorsTest.java | 124 +++++++++--------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java index 9cf40794..c991b392 100644 --- a/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java +++ b/src/test/java/org/carlmontrobotics/lib199/MotorErrorsTest.java @@ -5,6 +5,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeNoException; +import java.util.concurrent.atomic.AtomicBoolean; + import com.ctre.phoenix.ErrorCode; import com.revrobotics.REVLibError; import com.revrobotics.CANSparkMax; @@ -78,16 +80,6 @@ public int getDeviceId() { } - private static final Object asyncPeriodicNotifier = new Object(); - - static { - Lib199Subsystem.registerAsyncPeriodic(() -> { - synchronized(asyncPeriodicNotifier) { - asyncPeriodicNotifier.notifyAll(); - } - }); - } - @Test public void testOkErrors() { errStream.reset(); @@ -100,7 +92,7 @@ public void testOkErrors() { assertEquals(0, errStream.toByteArray().length); MotorErrors.reportErrors((REVLibError)null, null); assertEquals(0, errStream.toByteArray().length); - + // Ok Status MotorErrors.reportError(ErrorCode.OK); assertEquals(0, errStream.toByteArray().length); @@ -178,73 +170,87 @@ private void doTestReportSparkMaxTemp(int id) { String smartDashboardKey = "Port " + id + " Spark Max Temp"; MotorErrors.reportSparkMaxTemp((CANSparkMax)spark, 40); - spark.setTemperature(20); - spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); - assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); - assertEquals(50, spark.getSmartCurrentLimit()); - - spark.setTemperature(20); - spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); - assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); - assertEquals(50, spark.getSmartCurrentLimit()); - - if(MotorErrors.kOverheatTripCount > 1) { - spark.setTemperature(51); + try(AutoCloseable asyncBlock = blockAsyncPeriodic()) { + spark.setTemperature(20); spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); - assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + MotorErrors.doReportSparkMaxTemp(); + assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); spark.setTemperature(20); spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); + MotorErrors.doReportSparkMaxTemp(); assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); assertEquals(50, spark.getSmartCurrentLimit()); - } - assertEquals(0, errStream.size()); + if(MotorErrors.kOverheatTripCount > 1) { + spark.setTemperature(51); + spark.setSmartCurrentLimit(50); + MotorErrors.doReportSparkMaxTemp(); + assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + assertEquals(50, spark.getSmartCurrentLimit()); + + spark.setTemperature(20); + spark.setSmartCurrentLimit(50); + MotorErrors.doReportSparkMaxTemp(); + assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + assertEquals(50, spark.getSmartCurrentLimit()); + } - for(int i = 0; i < MotorErrors.kOverheatTripCount; i++) { - assertEquals(50, spark.getSmartCurrentLimit()); assertEquals(0, errStream.size()); + for(int i = 0; i < MotorErrors.kOverheatTripCount; i++) { + assertEquals(50, spark.getSmartCurrentLimit()); + assertEquals(0, errStream.size()); + + spark.setTemperature(51); + spark.setSmartCurrentLimit(50); + MotorErrors.doReportSparkMaxTemp(); + assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + } + + assertNotEquals(0, errStream.size()); + errStream.reset(); + spark.setTemperature(51); spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); + MotorErrors.doReportSparkMaxTemp(); assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); - } + assertEquals(1, spark.getSmartCurrentLimit()); - assertNotEquals(0, errStream.size()); - errStream.reset(); - - spark.setTemperature(51); - spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); - assertEquals(51, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); - assertEquals(1, spark.getSmartCurrentLimit()); - - spark.setTemperature(20); - spark.setSmartCurrentLimit(50); - runAsyncPeriodic(); - assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); - assertEquals(1, spark.getSmartCurrentLimit()); + spark.setTemperature(20); + spark.setSmartCurrentLimit(50); + MotorErrors.doReportSparkMaxTemp(); + assertEquals(20, SmartDashboard.getNumber(smartDashboardKey, 0), 0.01); + assertEquals(1, spark.getSmartCurrentLimit()); - assertEquals(0, errStream.size()); + assertEquals(0, errStream.size()); + } catch(Exception e) { + assumeNoException(e); + } } - // Ensures an update to the asynchronous periodic thread is run - private void runAsyncPeriodic() { - try { - synchronized(asyncPeriodicNotifier) { - // Run twice because we don't know in what order we're called, so make sure all periodic methods are run twice - asyncPeriodicNotifier.wait(); - asyncPeriodicNotifier.wait(); + // Blocks the Lib199Subsystem's async thread until closed + private AutoCloseable blockAsyncPeriodic() { + AtomicBoolean block = new AtomicBoolean(true); + Object lock = new Object(); + Lib199Subsystem.registerAsyncPeriodic(() -> { + synchronized(lock) { + while(block.get()) { + try { + lock.wait(); + } catch(InterruptedException e) { + assumeNoException(e); + } + } } - } catch(InterruptedException e) { - assumeNoException(e); - } + }); + return () -> { + block.set(false); + synchronized(lock) { + lock.notifyAll(); + } + }; } }