Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
585b37c
figuring out limelight this is all in progress
koolpoolo Sep 13, 2025
579b2b1
added things that made sense
Kooolpool Sep 13, 2025
acb6e8a
added pipeline stuff and formated limelight helpers file
koolpoolo Sep 15, 2025
dc96b91
converted it
koolpoolo Sep 21, 2025
8f20097
converted limelight code and made it better
koolpoolo Sep 24, 2025
db1b9b3
made it better for logging
koolpoolo Oct 14, 2025
cc2a577
added LLCamera class for better limelight access
koolpoolo Oct 24, 2025
3bc78a4
made raw fiducial use better
koolpoolo Oct 31, 2025
828e6a3
spotless
koolpoolo Oct 31, 2025
9e70db3
got rid of ambiguity if
RobototesProgrammers Nov 7, 2025
9ee7d00
watch me sigma
RobototesProgrammers Nov 7, 2025
700731b
m
RobototesProgrammers Nov 7, 2025
7e9d4bc
coverting to a bad pose system bc we shouldn't limit our data
koolpoolo Nov 8, 2025
8f82335
added the way advantage kit weighs poses so we can compare
koolpoolo Nov 9, 2025
853bcf7
fixes
RobototesProgrammers Nov 14, 2025
340e7cb
spotless
RobototesProgrammers Nov 14, 2025
29c3f27
added comments
RobototesProgrammers Nov 14, 2025
85e463e
spotless
RobototesProgrammers Nov 14, 2025
840336d
got rid of condition
RobototesProgrammers Nov 14, 2025
d1160b4
made it set to the zero pipeline when it inits
RobototesProgrammers Nov 14, 2025
f23a3a6
made april tag filterer better
RobototesProgrammers Nov 14, 2025
872a979
spotless
RobototesProgrammers Nov 14, 2025
c41280c
Got rid of getting needing to put in name for get TY
koolpoolo Nov 21, 2025
ed806e5
Made name final
koolpoolo Nov 21, 2025
8a24ada
pr fixes
koolpoolo Nov 25, 2025
a1ba94b
spotless
koolpoolo Nov 25, 2025
1516d26
changed widget location
koolpoolo Nov 25, 2025
7f95b2e
remove static
koolpoolo Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/frc/robot/Hardware.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ public class Hardware {
public static final String PHOTON_IP = "10.24.12.11";
public static final String LEFT_CAM = "Arducam_OV9782L";
public static final String RIGHT_CAM = "Arducam_OV9281R";
public static final String LEFT_LIMELIGHT = "left_limelight";
public static final String RIGHT_LIMELIGHT = "right_limelight";
}
8 changes: 7 additions & 1 deletion src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import frc.robot.subsystems.auto.AutoLogic;
import frc.robot.subsystems.auto.AutonomousField;
import frc.robot.util.BuildInfo;
import frc.robot.util.LimelightHelpers;
import frc.robot.util.MatchTab;
import frc.robot.util.RobotType;

Expand Down Expand Up @@ -118,7 +119,12 @@ public void robotPeriodic() {
}

@Override
public void disabledInit() {}
public void disabledInit() {
if (subsystems.visionSubsystem != null) {
LimelightHelpers.setPipelineIndex(Hardware.LEFT_LIMELIGHT, 0);
LimelightHelpers.setPipelineIndex(Hardware.RIGHT_LIMELIGHT, 0);
}
}

@Override
public void disabledPeriodic() {}
Expand Down
306 changes: 120 additions & 186 deletions src/main/java/frc/robot/subsystems/VisionSubsystem.java

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions src/main/java/frc/robot/util/BetterPoseEstimate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package frc.robot.util;

import edu.wpi.first.math.geometry.Pose3d;
import frc.robot.util.LimelightHelpers.RawFiducial;

public class BetterPoseEstimate {
public Pose3d pose3d;
public double timestampSeconds;
public double latency;
public int tagCount;
public double tagSpan;
public double avgTagDist;
public double avgTagArea;

public RawFiducial[] rawFiducials;
public boolean isMegaTag2;

/** Instantiates a PoseEstimate object with default values */
public BetterPoseEstimate() {
this.pose3d = new Pose3d();
this.timestampSeconds = 0;
this.latency = 0;
this.tagCount = 0;
this.tagSpan = 0;
this.avgTagDist = 0;
this.avgTagArea = 0;
this.rawFiducials = new RawFiducial[] {};
this.isMegaTag2 = false;
}

public BetterPoseEstimate(
Pose3d pose3d,
double timestampSeconds,
double latency,
int tagCount,
double tagSpan,
double avgTagDist,
double avgTagArea,
RawFiducial[] rawFiducials,
boolean isMegaTag2) {

this.pose3d = pose3d;
this.timestampSeconds = timestampSeconds;
this.latency = latency;
this.tagCount = tagCount;
this.tagSpan = tagSpan;
this.avgTagDist = avgTagDist;
this.avgTagArea = avgTagArea;
this.rawFiducials = rawFiducials;
this.isMegaTag2 = isMegaTag2;
}
}
135 changes: 135 additions & 0 deletions src/main/java/frc/robot/util/LLCamera.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package frc.robot.util;

import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.networktables.DoubleArrayEntry;
import edu.wpi.first.networktables.TimestampedDoubleArray;
import frc.robot.util.LimelightHelpers.RawDetection;
import frc.robot.util.LimelightHelpers.RawFiducial;

public class LLCamera {
private static String name;

public LLCamera(String name) {
LLCamera.name = name;
}
Comment on lines +10 to +14

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The name field is declared as static, which means it's shared across all instances of LLCamera. When you create two LLCamera objects (one for left_limelight and one for right_limelight), the second object's constructor will overwrite the name for both instances. This will cause both LLCamera objects to refer to the right_limelight, which is a significant bug.

To fix this, name should be an instance field.

Suggested change
private static String name;
public LLCamera(String name) {
LLCamera.name = name;
}
private final String name;
public LLCamera(String name) {
this.name = name;
}


public LLCamera() {
this("limelight");
}

public int getNumTargets() {
return LimelightHelpers.getTargetCount(name);
}

public boolean hasValidTarget() {
return LimelightHelpers.getTV(name);
}

public double getHoritontalOffset() {
return LimelightHelpers.getTX(name);
}

public double getVerticalOffset() {
return LimelightHelpers.getTY(name);
}

public double getTargetArea() {
return LimelightHelpers.getTA(name);
}

public RawFiducial[] getRawFiducials() {
return LimelightHelpers.getRawFiducials(name);
}

public RawDetection[] getRawDetections() {
return LimelightHelpers.getRawDetections(name);
}

public void setPipeline(int pipeline) {
LimelightHelpers.setPipelineIndex(name, pipeline);
}

public double getPipelineNumber() {
return LimelightHelpers.getCurrentPipelineIndex(name);
}

public String getPipeline() {
return LimelightHelpers.getCurrentPipelineType(name);
}

public Pose3d getPose3d() {
return LimelightHelpers.getBotPose3d_wpiBlue(name);
}

public BetterPoseEstimate getBetterPoseEstimate() {
return getBetterBotPoseEstimate_wpiBlue();
}

public BetterPoseEstimate getPoseEstimateMegatag2() {
return getBetterBotPoseEstimate_wpiBlue_Megatag2();
}

private BetterPoseEstimate getBetterBotPoseEstimate_wpiBlue() {
return getBetterBotPoseEstimate(name, "botpose_wpiblue", false);
}

private BetterPoseEstimate getBetterBotPoseEstimate_wpiBlue_Megatag2() {
return getBetterBotPoseEstimate(name, "botpose_orb_wpiblue", true);
}

private static BetterPoseEstimate getBetterBotPoseEstimate(
String limelightName, String entryName, boolean isMegaTag2) {
DoubleArrayEntry poseEntry =
LimelightHelpers.getLimelightDoubleArrayEntry(limelightName, entryName);
TimestampedDoubleArray tsValue = poseEntry.getAtomic();
double[] poseArray = tsValue.value;
long timestamp = tsValue.timestamp;

if (poseArray.length == 0) {
// Handle the case where no data is available
return null; // or some default PoseEstimate
}

var pose = LimelightHelpers.toPose3D(poseArray);
double latency = LimelightHelpers.extractArrayEntry(poseArray, 6);
int tagCount = (int) LimelightHelpers.extractArrayEntry(poseArray, 7);
double tagSpan = LimelightHelpers.extractArrayEntry(poseArray, 8);
double tagDist = LimelightHelpers.extractArrayEntry(poseArray, 9);
double tagArea = LimelightHelpers.extractArrayEntry(poseArray, 10);

// Convert server timestamp from microseconds to seconds and adjust for latency
double adjustedTimestamp = (timestamp / 1000000.0) - (latency / 1000.0);

RawFiducial[] rawFiducials = new RawFiducial[tagCount];
int valsPerFiducial = 7;
int expectedTotalVals = 11 + valsPerFiducial * tagCount;

if (poseArray.length != expectedTotalVals) {
// Don't populate fiducials
} else {
for (int i = 0; i < tagCount; i++) {
int baseIndex = 11 + (i * valsPerFiducial);
int id = (int) poseArray[baseIndex];
double txnc = poseArray[baseIndex + 1];
double tync = poseArray[baseIndex + 2];
double ta = poseArray[baseIndex + 3];
double distToCamera = poseArray[baseIndex + 4];
double distToRobot = poseArray[baseIndex + 5];
double ambiguity = poseArray[baseIndex + 6];
rawFiducials[i] = new RawFiducial(id, txnc, tync, ta, distToCamera, distToRobot, ambiguity);
}
}
BetterPoseEstimate poseEstimate =
new BetterPoseEstimate(
pose,
adjustedTimestamp,
latency,
tagCount,
tagSpan,
tagDist,
tagArea,
rawFiducials,
isMegaTag2);
return poseEstimate;
}
}
Loading