FRC Programming with Limelight Lib (WPILib Java & C++)
- https://github.com/LimelightVision/limelightlib-wpijava
- https://github.com/LimelightVision/limelightlib-wpicpp
JavaDocs: https://limelightlib-wpijava-reference.limelightvision.io
Usage
This is a single-file library. All you need to do is copy the LimelightHelpers.java file from the latest release (https://github.com/LimelightVision/limelightlib-wpijava/releases) into your Java project's "robot" folder. You don't need to create any objects for your Limelights - the library is simple and functional to maximize ease of use and reliability.
Tips for Success
- Start simple! Many successful FRC teams use basic approaches effectively. For example, Team 2056 in 2024 used a standard 90FPS color pipeline instead of neural networks for game piece tracking.
- Think about what you actually need: Do you need full field localization, or would simple target centering work (e.g.,
driveSpeed = result.getTx() * 0.03
)?
Key Concepts
1. Basic Usage
Every method accepts a Limelight name parameter. Leave it blank or null to use "limelight":
// Basic targeting data
double tx = LimelightHelpers.getTX(""); // Horizontal offset from crosshair to target in degrees
double ty = LimelightHelpers.getTY(""); // Vertical offset from crosshair to target in degrees
double ta = LimelightHelpers.getTA(""); // Target area (0% to 100% of image)
boolean hasTarget = LimelightHelpers.getTV(""); // Do you have a valid target?
double txnc = LimelightHelpers.getTXNC(""); // Horizontal offset from principal pixel/point to target in degrees
double tync = LimelightHelpers.getTYNC(""); // Vertical offset from principal pixel/point to target in degrees
2. Pipeline Management
Pipelines are like instantly-swappable programs that change how Limelight processes images. You can set up 10 different pipelines in the web interface:
// Switch to pipeline 0
LimelightHelpers.setPipelineIndex("", 0);
3. LED Control
For Limelights with bright illumination LEDS, you can control the LEDs for different situations:
// Let the current pipeline control the LEDs
LimelightHelpers.setLEDMode_PipelineControl("");
// Force LEDs on/off/blink
LimelightHelpers.setLEDMode_ForceOn("");
LimelightHelpers.setLEDMode_ForceOff("");
LimelightHelpers.setLEDMode_ForceBlink("");
4. Field Localization With MegaTag
(See the MegaTag documentation and the Swerve Pose Estimation Tutorial for more details.)
// In your periodic function:
LimelightHelpers.PoseEstimate limelightMeasurement = LimelightHelpers.getBotPoseEstimate_wpiBlue("limelight");
if (limelightMeasurement.tagCount >= 2) { // Only trust measurement if we see multiple tags
m_poseEstimator.setVisionMeasurementStdDevs(VecBuilder.fill(0.7, 0.7, 9999999));
m_poseEstimator.addVisionMeasurement(
limelightMeasurement.pose,
limelightMeasurement.timestampSeconds
);
}
5. Field Localization With MegaTag2
(See the MegaTag2 documentation and the Swerve Pose Estimation Tutorial for more details.)
MegaTag2 enhances localization accuracy by fusing robot orientation data with vision. By providing gyro data, you help MegaTag2 constrain the localization problem and provide excellent results even if only a single tag is visible:
// First, tell Limelight your robot's current orientation
double robotYaw = m_gyro.getYaw();
LimelightHelpers.SetRobotOrientation("", robotYaw, 0.0, 0.0, 0.0, 0.0, 0.0);
// Get the pose estimate
LimelightHelpers.PoseEstimate limelightMeasurement = LimelightHelpers.getBotPoseEstimate_wpiBlue("");
// Add it to your pose estimator
m_poseEstimator.setVisionMeasurementStdDevs(VecBuilder.fill(.5, .5, 9999999));
m_poseEstimator.addVisionMeasurement(
limelightMeasurement.pose,
limelightMeasurement.timestampSeconds
);