Class Limelight

java.lang.Object
frc.spectrumLib.vision.Limelight

public class Limelight extends Object
Provides a high-level interface to a single Limelight camera for AprilTag-based pose estimation and basic targeting.

All methods are safe to call when the camera is not attached (isAttached() returns false); they return zero / false / empty values in that case.

NetworkTables reads are snapshotted per robot loop: the first getter to need a topic reads it once and every later getter in the same loop reuses that sample, so pose, tag count, raw fiducials and timestamp always describe the same camera frame. The owning subsystem must call invalidate() exactly once per loop before any getter. Returned LimelightHelpers.PoseEstimate and LimelightHelpers.RawFiducial instances are shared for the rest of the loop and must not be mutated.

Two pose estimation flavors are supported:

  • MegaTag1 is full 3-D pose estimation using one or more AprilTags.
  • MegaTag2 is a fused estimate that incorporates the robot heading supplied via setRobotOrientation(double).
  • Constructor Details

    • Limelight

      public Limelight(Limelight.LimelightConfig config)
      Constructs a Limelight wrapper from a fully populated Limelight.LimelightConfig.
      Parameters:
      config - the camera configuration
    • Limelight

      public Limelight(String name)
      Constructs a Limelight wrapper with a default configuration for the given camera name.
      Parameters:
      name - the network-table name of the camera
    • Limelight

      public Limelight(String name, boolean attached)
      Constructs a Limelight wrapper, explicitly setting whether the camera is attached.
      Parameters:
      name - the network-table name of the camera
      attached - true if the camera is physically present on the robot
    • Limelight

      public Limelight(String name, int pipeline)
      Constructs a Limelight wrapper and immediately sets its active pipeline.
      Parameters:
      name - the network-table name of the camera
      pipeline - the pipeline index to activate (refer to robot vision configuration for pipeline indexes)
    • Limelight

      public Limelight(String name, int pipeline, Limelight.LimelightConfig config)
      Constructs a Limelight wrapper with an explicit configuration and immediately sets its active pipeline.
      Parameters:
      name - the network-table name of the camera
      pipeline - the pipeline index to activate
      config - the fully populated Limelight.LimelightConfig to use
  • Method Details

    • invalidate

      public void invalidate()
      Clears the per-loop NetworkTables snapshot so the next getter re-reads the camera.

      Must be called exactly once per robot loop, before any pose/target getter, by the owning subsystem (see Vision.periodic()). Between calls, every getter on this object returns data from the same NetworkTables sample. Safe to call on a detached camera.

    • getName

      public String getName()
      Returns the network-table name of this camera.
      Returns:
      the camera name as configured in the LL dashboard
    • isAttached

      public boolean isAttached()
      Returns whether this camera is physically connected to the robot.
      Returns:
      true if attached
    • getHorizontalOffset

      public double getHorizontalOffset()
      Get the horizontal offset from crosshair to target
      Returns:
      Horizontal Offset From Crosshair To Target (LL1: -27 degrees to 27 degrees / LL2: -29.8 to 29.8 degrees)
    • getVerticalOffset

      public double getVerticalOffset()
      Get the vertical offset from crosshair to target
      Returns:
      Vertical Offset From Crosshair To Target in degrees (LL1: -20.5 degrees to 20.5 degrees / LL2: -24.85 to 24.85 degrees)
    • targetInView

      public boolean targetInView()
      Returns whether the LL has any valid targets (April tags or other vision targets)
      Returns:
      Whether the LL has any valid targets (April tags or other vision targets)
    • multipleTagsInView

      public boolean multipleTagsInView()
      Checks if the LL sees multiple tags
      Returns:
      whether the LL sees multiple tags or not
    • getTagCountInView

      public double getTagCountInView()
      Returns the number of AprilTags included in the current MegaTag1 pose estimate.
      Returns:
      number of tags contributing to the current pose estimate, or 0 if not attached or no estimate is available
    • getClosestTagID

      public double getClosestTagID()
      Gets the ID of the apriltag most centered in the LL's view.
      Returns:
      the tag ID of the apriltag most centered in the LL's view, or the tag chosen by the criteria set in the LL dashboard
    • getTargetSize

      public double getTargetSize()
      Returns the area of the primary target as a percentage of the camera image (0 to 100).
      Returns:
      target area percentage, or 0 if not attached
    • getMegaTag1_Pose3d

      public Pose3d getMegaTag1_Pose3d()
      Get the corresponding LL Pose3d (MEGATAG1) for the alliance in DriverStation.java
      Returns:
      the corresponding LL Pose3d (MEGATAG1) for the alliance in DriverStation.java
    • getMegaTag2_Pose2d

      public Pose2d getMegaTag2_Pose2d()
      Get the corresponding LL Pose2d (MEGATAG2) for the alliance in DriverStation.java
      Returns:
      the corresponding LL Pose2d (MEGATAG2) for the alliance in DriverStation.java
    • getMegaTag1_PoseEstimate

      public LimelightHelpers.PoseEstimate getMegaTag1_PoseEstimate()
      Returns the full MegaTag1 LimelightHelpers.PoseEstimate, including timestamp, tag count, and raw fiducials. Returns an empty estimate when not attached or when no estimate is available.
      Returns:
      the MegaTag1 pose estimate in the WPILib Blue origin frame
    • getMegaTag2_PoseEstimate

      public LimelightHelpers.PoseEstimate getMegaTag2_PoseEstimate()
      Returns the full MegaTag2 LimelightHelpers.PoseEstimate (heading-fused), including timestamp and tag count. Returns an empty estimate when not attached or when no estimate is available.
      Returns:
      the MegaTag2 pose estimate in the WPILib Blue origin frame
    • hasAccuratePose

      public boolean hasAccuratePose()
      Returns true when the pose estimate is considered accurate: multiple tags are visible and the combined target area exceeds a minimum threshold.
      Returns:
      true if the pose estimate meets the accuracy criteria
    • getDistanceToTagFromCamera

      public double getDistanceToTagFromCamera()
      Get the distance of the 2d vector from the camera to closest apriltag
      Returns:
      the distance of the 2d vector from the camera to closest apriltag
    • getRawFiducial

      public LimelightHelpers.RawFiducial[] getRawFiducial()
      Returns the raw fiducial data for all currently detected AprilTags.
      Returns:
      array of LimelightHelpers.RawFiducial entries from the MegaTag1 estimate; empty array if not attached or no estimate is available
    • getMegaTag1PoseTimestamp

      public double getMegaTag1PoseTimestamp()
      Returns the timestamp of the MEGATAG1 pose estimation from the Limelight camera.
      Returns:
      The timestamp of the pose estimation in seconds.
    • getMegaTag2PoseTimestamp

      public double getMegaTag2PoseTimestamp()
      Returns the timestamp of the MEGATAG2 pose estimation from the Limelight camera.
      Returns:
      The timestamp of the pose estimation in seconds.
    • getPoseLatency

      @Deprecated(forRemoval=true) public double getPoseLatency()
      Deprecated, for removal: This API element is subject to removal in a future version.
      Returns the latency of the pose estimation from the Limelight camera.
      Returns:
      The latency of the pose estimation in seconds.
    • getDistanceToTarget

      public double getDistanceToTarget(double targetHeight)
      get distance in meters to a target
      Parameters:
      targetHeight - meters
      Returns:
      distance in meters to a target
    • sendValidStatus

      public void sendValidStatus(String message)
      Marks this camera as actively integrating and updates the log status message.
      Parameters:
      message - a human-readable description of why integration is valid
    • sendInvalidStatus

      public void sendInvalidStatus(String message)
      Marks this camera as not integrating and updates the log status message.
      Parameters:
      message - a human-readable description of why integration is invalid
    • setLimelightPipeline

      public void setLimelightPipeline(int pipelineIndex)
      Sets the LL pipeline to the given index.
      Parameters:
      pipelineIndex - the pipeline index (refer to robot vision configuration for pipeline indexes)
    • setRobotOrientation

      public void setRobotOrientation(double degrees)
      Sets the robot orientation in degrees for the Limelight's internal IMU.

      Does not flush NetworkTables; the caller is responsible for a single flush after all per-loop writes (see Vision.periodic()).

    • updateCameraPose

      public void updateCameraPose(Pose3d pose)
    • pushConfiguredCameraPose

      public void pushConfiguredCameraPose()
      Writes this camera's configured mount pose (Limelight.LimelightConfig.withTranslation(double, double, double) and Limelight.LimelightConfig.withRotation(double, double, double)) to the camera over NetworkTables, making the code the source of truth for the offsets instead of the values typed into the web UI.

      The six values are stored in exactly the convention the camera wants: forward, right, up in metres, then roll, pitch, yaw in degrees. They go across unchanged. That is the same order and sign as the boxes in the web UI, so what is in VisionConfig can be read straight off against what a camera is showing.

      A Limelight keeps its own copy in flash and falls back to it on boot, so this has to be republished rather than written once: a camera that reboots mid-match otherwise silently reverts to whatever was last typed into it. See the resend loop in Vision.periodic().

      Does not flush NetworkTables; the caller flushes once after all per-loop writes.

    • setRobotOrientation

      public void setRobotOrientation(double degrees, double angularRate)
      Sets the robot orientation and yaw rate for the Limelight's internal IMU fusion (MegaTag2).

      Does not flush NetworkTables; the caller is responsible for a single flush after all per-loop writes (see Vision.periodic()).

      Parameters:
      degrees - robot heading in degrees (positive counter-clockwise)
      angularRate - current yaw rate in degrees per second
    • setIMUmode

      public void setIMUmode(int mode)
      Sets the IMU mode on the Limelight.
      Parameters:
      mode - the IMU mode index (refer to the LL documentation for valid values)
    • getTagTx

      public double getTagTx()
      Returns the X offset of the primary target in robot space (meters along the robot's left/right axis).
      Returns:
      target X translation in meters, or -99999 if not attached or no target in view
    • getTagTA

      public double getTagTA()
      Returns the area of the primary target as a percentage of the camera image.
      Returns:
      target area (0 to 100 %), or -99999 if not attached or no target in view
    • getTagRotationDegrees

      public double getTagRotationDegrees()
      Returns the Z-axis rotation of the primary target in robot space (yaw in radians, converted to degrees).
      Returns:
      target yaw rotation in degrees, or -99999 if not attached or no target in view
    • setLEDMode

      public void setLEDMode(boolean enabled)
      Sets the LED mode of the LL.
      Parameters:
      enabled - true to enable the LED mode, false to disable it
    • blinkLEDs

      public void blinkLEDs()
      Set LL LED's to blink
    • isCameraConnected

      public boolean isCameraConnected()
      Checks if the camera is connected by looking for a full botpose array from the camera.
    • printDebug

      public void printDebug()
      Prints the vision, estimated, and odometry pose to SmartDashboard
    • isIntegrating

      public boolean isIntegrating()
      Whether pose measurements from this camera are currently being integrated.
    • setIntegrating

      public void setIntegrating(boolean isIntegrating)
      Whether pose measurements from this camera are currently being integrated.
    • getCameraName

      public String getCameraName()
      Network-table name of this camera (mirrors Limelight.LimelightConfig.getName()).
    • getLogStatus

      public String getLogStatus()
      Human-readable string describing the current integration status, logged for diagnostics.
    • setLogStatus

      public void setLogStatus(String logStatus)
      Human-readable string describing the current integration status, logged for diagnostics.
    • getTagStatus

      public String getTagStatus()
      Human-readable string describing the currently visible tag(s), logged for diagnostics.
    • setTagStatus

      public void setTagStatus(String tagStatus)
      Human-readable string describing the currently visible tag(s), logged for diagnostics.
    • isIntegratedThisLoop

      public boolean isIntegratedThisLoop()
      Whether an estimate from this camera was fused into the pose estimator this loop.
    • setIntegratedThisLoop

      public void setIntegratedThisLoop(boolean integratedThisLoop)
      Whether an estimate from this camera was fused into the pose estimator this loop.
    • getLastEstimateAgeSeconds

      public double getLastEstimateAgeSeconds()
      Age in seconds (capture time to now) of the last estimate this camera produced this loop, or NaN if it produced none. A large value means the camera's timestamps are not trustworthy.
    • setLastEstimateAgeSeconds

      public void setLastEstimateAgeSeconds(double lastEstimateAgeSeconds)
      Age in seconds (capture time to now) of the last estimate this camera produced this loop, or NaN if it produced none. A large value means the camera's timestamps are not trustworthy.