diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/AprilTagMapPoseHelper.java b/limelight/src/main/java/com/team2813/lib2813/limelight/AprilTagMapPoseHelper.java index e58a0892..f629e246 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/AprilTagMapPoseHelper.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/AprilTagMapPoseHelper.java @@ -1,5 +1,5 @@ /* -Copyright 2025 Prospect Robotics SWENext Club +Copyright 2025-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -69,7 +69,7 @@ public List getVisibleTagPoses(Set ids) { return List.of(); } return retriever.getFiducialMap().values().stream() - .filter(fidicual -> ids.contains(fidicual.getId())) + .filter(fiducial -> ids.contains(fiducial.getId())) .map(Fiducial::getPosition) .toList(); } diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/BotPoseEstimate.java b/limelight/src/main/java/com/team2813/lib2813/limelight/BotPoseEstimate.java index 574b9238..848c6ef9 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/BotPoseEstimate.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/BotPoseEstimate.java @@ -1,5 +1,5 @@ /* -Copyright 2025 Prospect Robotics SWENext Club +Copyright 2025-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,10 +25,5 @@ * @param timestampSeconds The timestamp, in seconds, using the drivetrain clock * @param visibleAprilTags All April Tags that are visible from the vision source. */ -public record BotPoseEstimate(Pose2d pose, double timestampSeconds, Set visibleAprilTags) { - - @Deprecated - public BotPoseEstimate(Pose2d pose, double timestampSeconds) { - this(pose, timestampSeconds, Set.of()); - } -} +public record BotPoseEstimate( + Pose2d pose, double timestampSeconds, Set visibleAprilTags) {} diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/DataCollection.java b/limelight/src/main/java/com/team2813/lib2813/limelight/DataCollection.java index 151fc051..a0fd0147 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/DataCollection.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/DataCollection.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -60,9 +60,7 @@ public BodySubscriber apply(ResponseInfo responseInfo) { return BodySubscribers.mapping( BodyHandlers.ofString(Charset.defaultCharset()).apply(responseInfo), - body -> { - return new Result(new JSONObject(body), responseTimestamp); - }); + body -> new Result(new JSONObject(body), responseTimestamp)); } } diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/Limelight.java b/limelight/src/main/java/com/team2813/lib2813/limelight/Limelight.java index 31823f3d..5c7f4db0 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/Limelight.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/Limelight.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,14 +15,11 @@ */ package com.team2813.lib2813.limelight; -import edu.wpi.first.math.geometry.Pose3d; import edu.wpi.first.wpilibj.Filesystem; -import java.io.*; -import java.util.List; -import java.util.Optional; -import java.util.OptionalDouble; -import java.util.Set; -import org.json.JSONObject; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; public interface Limelight { @@ -35,20 +32,6 @@ static Limelight getDefaultLimelight() { return RestLimelight.getDefaultLimelight(); } - /** - * @deprecated use methods in {@link LocationalData} that return a {@link BotPoseEstimate}. - */ - @Deprecated - OptionalDouble getTimestamp(); - - /** - * Returns {@code true} if the limelight has identified a target. - * - * @deprecated use {@link LocationalData#hasTarget()} - */ - @Deprecated - boolean hasTarget(); - /** Gets an object for getting locational data. */ LocationalData getLocationalData(); @@ -59,7 +42,7 @@ static Limelight getDefaultLimelight() { * may also upload the field map to the Limelight if desired. This will likely be a slow * operation, and should not be regularly called. * - * @param filepath The path to the file from the deploy directory (using UNIX file seperators) + * @param filepath The path to the file from the deploy directory (using UNIX file separators) * @param updateLimelight If the limelight should be updated with this field map * @throws IOException If the given filepath does not exist in the deploy directory or could not * be read @@ -70,26 +53,4 @@ default void setFieldMap(String filepath, boolean updateLimelight) throws IOExce setFieldMap(stream, updateLimelight); } } - - /** - * Gets the locations of the given AprilTags. - * - * @deprecated use {@link LocationalData#getVisibleAprilTagPoses()} - */ - @Deprecated - List getLocatedAprilTags(Set visibleTags); - - /** - * @deprecated use {@link LocationalData#getCaptureLatency()} - */ - @Deprecated - OptionalDouble getCaptureLatency(); - - /** - * Gets the most recent JSON from the Limelight. Does not work for all implementations. - * - * @deprecated use {@link LocationalData#isValid()}. - */ - @Deprecated - Optional getJsonDump(); } diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/LimelightHelpers.java b/limelight/src/main/java/com/team2813/lib2813/limelight/LimelightHelpers.java index 27e51bfc..7696ce78 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/LimelightHelpers.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/LimelightHelpers.java @@ -1,5 +1,5 @@ /* -Copyright 2025 Prospect Robotics SWENext Club +Copyright 2025-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -919,16 +919,10 @@ public static String[] getLimelightNTStringArray(String tableName, String entryN return getLimelightNTTableEntry(tableName, entryName).getStringArray(new String[0]); } - public static URL getLimelightURLString(String tableName, String request) { + public static URL getLimelightURLString(String tableName, String request) + throws MalformedURLException { String urlString = "http://" + sanitizeName(tableName) + ".local:5807/" + request; - URL url; - try { - url = new URL(urlString); - return url; - } catch (MalformedURLException e) { - System.err.println("bad LL URL"); - } - return null; + return new URL(urlString); } ///// @@ -1658,8 +1652,8 @@ public static CompletableFuture takeSnapshot(String tableName, String s } private static boolean SYNCH_TAKESNAPSHOT(String tableName, String snapshotName) { - URL url = getLimelightURLString(tableName, "capturesnapshot"); try { + URL url = getLimelightURLString(tableName, "capturesnapshot"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); if (snapshotName != null && !snapshotName.isEmpty()) { @@ -1672,6 +1666,8 @@ private static boolean SYNCH_TAKESNAPSHOT(String tableName, String snapshotName) } else { System.err.println("Bad LL Request"); } + } catch (MalformedURLException e) { + System.err.println("bad Limelight URL: " + e.getMessage()); } catch (IOException e) { System.err.println(e.getMessage()); } diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/LocationalData.java b/limelight/src/main/java/com/team2813/lib2813/limelight/LocationalData.java index dcf02541..d08ed393 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/LocationalData.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/LocationalData.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import java.util.Map; import java.util.Optional; import java.util.OptionalDouble; -import java.util.Set; /** * Get positional data from limelight @@ -69,47 +68,16 @@ public interface LocationalData { * *

Per the Limelight docs, this is the time between the end of the exposure of the middle row * to the beginning of the tracking loop. - * - * @deprecated Use {@link #getBotPoseEstimateBlue()} or {@link #getBotPoseEstimateRed()} */ - @Deprecated OptionalDouble getCaptureLatency(); /** * Targeting latency in milliseconds. * *

Per the Limelight docs, this is the time consumed by the tracking loop this frame. - * - * @deprecated Use {@link #getBotPoseEstimateBlue()} or {@link #getBotPoseEstimateRed()} */ - @Deprecated OptionalDouble getTargetingLatency(); - /** - * @deprecated use methods that return a {@link BotPoseEstimate}. - */ - @Deprecated - OptionalDouble getTimestamp(); - - @Deprecated - default OptionalDouble lastMSDelay() { - OptionalDouble a = getCaptureLatency(); - OptionalDouble b = getTargetingLatency(); - if (a.isPresent() && b.isPresent()) { - return OptionalDouble.of(a.getAsDouble() + b.getAsDouble()); - } - return OptionalDouble.empty(); - } - - /** - * Gets the set of all visible tags - * - * @return The visible tags - * @deprecated use {@link #getVisibleAprilTagPoses()} - */ - @Deprecated - Set getVisibleTags(); - /** Gets the visible AprilTags as a map from ID to position. */ Map getVisibleAprilTagPoses(); } diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/NetworkTablesLimelight.java b/limelight/src/main/java/com/team2813/lib2813/limelight/NetworkTablesLimelight.java index daeefe7b..b215990b 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/NetworkTablesLimelight.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/NetworkTablesLimelight.java @@ -1,5 +1,5 @@ /* -Copyright 2025 Prospect Robotics SWENext Club +Copyright 2025-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,12 +23,12 @@ import edu.wpi.first.math.geometry.Pose3d; import java.io.IOException; import java.io.InputStream; -import java.util.*; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import java.util.OptionalDouble; -import java.util.stream.Collectors; -import org.json.JSONObject; +import java.util.Set; class NetworkTablesLimelight implements Limelight { private static final double[] ZEROS = new double[6]; @@ -40,16 +40,6 @@ class NetworkTablesLimelight implements Limelight { aprilTagMapPoseHelper = new AprilTagMapPoseHelper(new LimelightClient(limelightName)); } - @Override - public OptionalDouble getTimestamp() { - return getLocationalData().getTimestamp(); - } - - @Override - public boolean hasTarget() { - return getLocationalData().hasTarget(); - } - @Override public void setFieldMap(InputStream stream, boolean updateLimelight) throws IOException { // The updateLimelight assumes we have the hostname of the limelight, which we don't. For now, @@ -57,21 +47,6 @@ public void setFieldMap(InputStream stream, boolean updateLimelight) throws IOEx aprilTagMapPoseHelper.setFieldMap(stream, false); } - @Override - public List getLocatedAprilTags(Set visibleTags) { - return aprilTagMapPoseHelper.getVisibleTagPoses(visibleTags); - } - - @Override - public Optional getJsonDump() { - return Optional.empty(); - } - - @Override - public OptionalDouble getCaptureLatency() { - return getLocationalData().getCaptureLatency(); - } - @Override public LocationalData getLocationalData() { LimelightHelpers.LimelightResults results = LimelightHelpers.getLatestResults(limelightName); @@ -109,7 +84,7 @@ private Map getVisibleAprilTagPoses(LimelightResults results) { return unmodifiableMap(map); } - private class NTLocationalData implements LocationalData { + private static class NTLocationalData implements LocationalData { private final LimelightResults results; private final Optional poseEstimate; private final Optional redPoseEstimate; @@ -179,18 +154,6 @@ public OptionalDouble getTargetingLatency() { return OptionalDouble.of(results.latency_pipeline); } - @Override - public OptionalDouble getTimestamp() { - return OptionalDouble.of(results.timestamp_LIMELIGHT_publish); - } - - @Override - public Set getVisibleTags() { - return Arrays.stream(results.targets_Fiducials) - .map(fiducial -> (int) fiducial.fiducialID) - .collect(Collectors.toUnmodifiableSet()); - } - @Override public Map getVisibleAprilTagPoses() { return aprilTags; diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/RestLimelight.java b/limelight/src/main/java/com/team2813/lib2813/limelight/RestLimelight.java index 0be768f4..29bc8683 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/RestLimelight.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/RestLimelight.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ import static com.team2813.lib2813.limelight.JSONHelper.*; import static com.team2813.lib2813.limelight.Optionals.unboxDouble; -import static com.team2813.lib2813.limelight.Optionals.unboxLong; import static java.util.Collections.*; import edu.wpi.first.math.geometry.Pose3d; @@ -63,20 +62,6 @@ void runThread() { collectionThread.run(); } - @Override - public Optional getJsonDump() { - return collectionThread.getMostRecent().map(DataCollection.Result::json); - } - - public OptionalDouble getCaptureLatency() { - return getLocationalData().getCaptureLatency(); - } - - @Override - public OptionalDouble getTimestamp() { - return getLocationalData().getTimestamp(); - } - /** * Sets the field map for the limelight. Additionally, this may also upload the field map to the * Limelight if desired. This will likely be a slow operation, and should not be regularly called. @@ -89,11 +74,6 @@ public void setFieldMap(InputStream stream, boolean updateLimelight) throws IOEx aprilTagMapPoseHelper.setFieldMap(stream, updateLimelight); } - @Override - public List getLocatedAprilTags(Set visibleTags) { - return aprilTagMapPoseHelper.getVisibleTagPoses(visibleTags); - } - private static Function not(Function fnc) { return (t) -> !fnc.apply(t); } @@ -105,7 +85,7 @@ public boolean hasTarget() { public LocationalData getLocationalData() { Optional locationalData = collectionThread.getMostRecent().map(RestLocationalData::new); - return locationalData.orElse(StubLocationalData.VALID); + return locationalData.orElse(StubLocationalData.INVALID); } private void clean() { @@ -198,11 +178,6 @@ private Optional parseArr(JSONArray arr) { new Pose3d(arr.getDouble(0), arr.getDouble(1), arr.getDouble(2), rotation)); } - @Override - public OptionalDouble getTimestamp() { - return unboxDouble(getDouble(root, "ts")); - } - @Override public OptionalDouble getCaptureLatency() { return unboxDouble(getDouble(root, "cl")); @@ -257,28 +232,6 @@ private BotPoseEstimate toBotPoseEstimate(Pose3d pose) { pose.toPose2d(), timestampSeconds, getVisibleAprilTagPoses().keySet()); } - /** Gets the id of the targeted tag. */ - OptionalLong getTagID() { - return unboxLong(getLong(root, "pID")); - } - - @Override - public Set getVisibleTags() { - return getArr(root, "Fiducial") - .map( - arr -> { - Set ints = new HashSet<>(); - for (int i = 0; i < arr.length(); i++) { - JSONObject obj = arr.optJSONObject(i); - if (obj != null && obj.has("fID")) { - ints.add(obj.getInt("fID")); - } - } - return unmodifiableSet(ints); - }) - .orElseGet(Set::of); - } - @Override public Map getVisibleAprilTagPoses() { return getArr(root, "Fiducial") diff --git a/limelight/src/main/java/com/team2813/lib2813/limelight/StubLocationalData.java b/limelight/src/main/java/com/team2813/lib2813/limelight/StubLocationalData.java index 28505cdf..6c6c110f 100644 --- a/limelight/src/main/java/com/team2813/lib2813/limelight/StubLocationalData.java +++ b/limelight/src/main/java/com/team2813/lib2813/limelight/StubLocationalData.java @@ -1,5 +1,5 @@ /* -Copyright 2025 Prospect Robotics SWENext Club +Copyright 2025-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -79,21 +79,6 @@ public OptionalDouble getTargetingLatency() { return OptionalDouble.empty(); } - @Override - public OptionalDouble getTimestamp() { - return OptionalDouble.empty(); - } - - @Override - public OptionalDouble lastMSDelay() { - return OptionalDouble.empty(); - } - - @Override - public Set getVisibleTags() { - return Set.of(); - } - @Override public Map getVisibleAprilTagPoses() { return Collections.emptyMap(); diff --git a/limelight/src/test/java/com/team2813/lib2813/limelight/LimelightTestCase.java b/limelight/src/test/java/com/team2813/lib2813/limelight/LimelightTestCase.java index 7447cb49..3a0c5c57 100644 --- a/limelight/src/test/java/com/team2813/lib2813/limelight/LimelightTestCase.java +++ b/limelight/src/test/java/com/team2813/lib2813/limelight/LimelightTestCase.java @@ -1,5 +1,5 @@ /* -Copyright 2024-2025 Prospect Robotics SWENext Club +Copyright 2024-2026 Prospect Robotics SWENext Club Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalDouble; @@ -44,9 +43,17 @@ abstract class LimelightTestCase { @Test - public final void emptyValues() { + public final void noData() { Limelight limelight = createLimelight(); - assertWithMessage("JSON should be empty").that(limelight.getCaptureLatency()).isEmpty(); + + LocationalData locationalData = limelight.getLocationalData(); + assertThat(locationalData.isValid()).isFalse(); + assertThat(locationalData.getBotpose()).isEmpty(); + assertThat(locationalData.getBotPoseEstimate()).isEmpty(); + assertThat(locationalData.getBotPoseEstimateBlue()).isEmpty(); + assertThat(locationalData.getBotposeBlue()).isEmpty(); + assertThat(locationalData.getBotposeRed()).isEmpty(); + assertThat(locationalData.getBotPoseEstimateRed()).isEmpty(); } @Test @@ -59,10 +66,11 @@ public final void invalidDataTest() throws Exception { LocationalData locationalData = limelight.getLocationalData(); assertThat(locationalData.isValid()).isFalse(); assertThat(locationalData.getBotpose()).isEmpty(); - OptionalDouble actualCaptureLatency = locationalData.getCaptureLatency(); - assertThat(actualCaptureLatency).isEmpty(); - OptionalDouble actualTargetingLatency = locationalData.getTargetingLatency(); - assertThat(actualTargetingLatency).isEmpty(); + assertThat(locationalData.getBotPoseEstimate()).isEmpty(); + assertThat(locationalData.getBotPoseEstimateBlue()).isEmpty(); + assertThat(locationalData.getBotposeBlue()).isEmpty(); + assertThat(locationalData.getBotposeRed()).isEmpty(); + assertThat(locationalData.getBotPoseEstimateRed()).isEmpty(); } @Test @@ -75,13 +83,10 @@ public final void absentTest1() throws Exception { LocationalData locationalData = limelight.getLocationalData(); assertThat(locationalData.isValid()).isTrue(); assertThat(locationalData.getBotpose()).isEmpty(); - OptionalDouble actualCaptureLatency = locationalData.getCaptureLatency(); - double expectedCaptureLatencyMs = 37.40; - assertAlmostEqual(expectedCaptureLatencyMs, actualCaptureLatency, 0.005); - OptionalDouble actualTargetingLatency = locationalData.getTargetingLatency(); - double expectedTargetingLatencyMs = 38.95; - assertAlmostEqual(expectedTargetingLatencyMs, actualTargetingLatency, 0.005); + assertThat(locationalData.getBotPoseEstimate()).isEmpty(); assertThat(locationalData.getBotPoseEstimateBlue()).isEmpty(); + assertThat(locationalData.getBotposeBlue()).isEmpty(); + assertThat(locationalData.getBotposeRed()).isEmpty(); assertThat(locationalData.getBotPoseEstimateRed()).isEmpty(); } @@ -95,13 +100,10 @@ public final void absentTest2() throws Exception { LocationalData locationalData = limelight.getLocationalData(); assertThat(locationalData.isValid()).isTrue(); assertThat(locationalData.getBotpose()).isEmpty(); - OptionalDouble actualCaptureLatency = locationalData.getCaptureLatency(); - double expectedCaptureLatencyMs = 37.40; - assertAlmostEqual(expectedCaptureLatencyMs, actualCaptureLatency, 0.005); - OptionalDouble actualTargetingLatency = locationalData.getTargetingLatency(); - double expectedTargetingLatencyMs = 54.64; - assertAlmostEqual(expectedTargetingLatencyMs, actualTargetingLatency, 0.005); + assertThat(locationalData.getBotPoseEstimate()).isEmpty(); assertThat(locationalData.getBotPoseEstimateBlue()).isEmpty(); + assertThat(locationalData.getBotposeBlue()).isEmpty(); + assertThat(locationalData.getBotposeRed()).isEmpty(); assertThat(locationalData.getBotPoseEstimateRed()).isEmpty(); } @@ -219,15 +221,6 @@ public final void getBotposeRed() throws Exception { assertThat(actualPose).isWithin(0.005).of(expectedPose); } - @Test - public final void getVisibleTags() throws Exception { - JSONObject obj = readJSON("BotposeBlueRedTest.json"); - setJson(obj); - Limelight limelight = createLimelight(); - assertHasTarget(limelight); - assertThat(limelight.getLocationalData().getVisibleTags()).containsExactly(20); - } - @Test public final void getVisibleAprilTagPoses() throws Exception { JSONObject obj = readJSON("BotposeBlueRedTest.json"); @@ -254,20 +247,6 @@ public final void getVisibleAprilTagPoses() throws Exception { assertThat(locationalData.getBotPoseEstimateRed().get().visibleAprilTags()).isEqualTo(tags); } - @Test - public final void visibleTagLocation() throws Exception { - JSONObject obj = readJSON("BotposeBlueRedTest.json"); - setJson(obj); - Limelight limelight = createLimelight(); - uploadFieldMap(limelight); - - Set visibleTags = limelight.getLocationalData().getVisibleTags(); - List aprilTags = limelight.getLocatedAprilTags(visibleTags); - assertThat(aprilTags).hasSize(1); - Pose3d pose = aprilTags.get(0); - assertThat(pose.getTranslation()).isWithin(0.005).of(new Translation3d(-3.87, 0.72, 0.31)); - } - protected abstract Limelight createLimelight(); protected abstract void setJson(JSONObject json); @@ -292,7 +271,9 @@ private JSONObject readJSON(String fileName) throws IOException { } private void assertHasTarget(Limelight limelight) { - assertWithMessage("Should have target").that(limelight.hasTarget()).isTrue(); + assertWithMessage("Should have target") + .that(limelight.getLocationalData().hasTarget()) + .isTrue(); assertWithMessage("Should have target") .that(limelight.getLocationalData().hasTarget()) .isTrue();