Pose Estimation with Limelight (MegaTag2) and PhotonVision
Detecting a tag is one thing; getting a reliable field pose from it is another. Both ecosystems provide higher-level pose estimation.
Limelight MegaTag2
Section titled “Limelight MegaTag2”A single AprilTag seen from far away or at an angle can be ambiguous — there are two mathematically valid orientations, and the wrong one throws your pose off badly. Limelight’s MegaTag2 (2024+) solves this by assuming you already know the robot’s heading (from your gyro) and using it to disambiguate, giving excellent single-tag results at any distance.
The workflow:
- Feed the gyro heading every loop:
LimelightHelpers.SetRobotOrientation("limelight", yawDegrees, 0, 0, 0, 0, 0); - Read the pose estimate:
LimelightHelpers.PoseEstimate mt2 = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("limelight");For 2024 and beyond, always use the botpose_orb_wpiblue variant (the MegaTag2 helper above) so the result is in the standard blue-origin coordinate system. Each estimate carries a timestamp and a tag count. Reject obviously bad data — for example, ignore updates when tagCount == 0 or when the robot is spinning faster than 720 deg/s (MegaTag2 relies on a trustworthy heading — Limelight’s own example rejects updates above 720 deg/s).
PhotonVision PhotonPoseEstimator
Section titled “PhotonVision PhotonPoseEstimator”PhotonLib provides PhotonPoseEstimator , which combines all tags visible at one timestamp into a single field-relative pose. You construct it with the AprilTag field layout and the robot-to-camera transform. Each loop you call a strategy method — e.g. estimateCoprocMultiTagPose(result), which combines all visible tags into one solution on the coprocessor — and get an Optional<EstimatedRobotPose> containing the pose and the timestamp. (Older PhotonLib passed a PoseStrategy such as MULTI_TAG_PNP_ON_COPROCESSOR to the constructor and called a generic update(); current PhotonLib uses these per-strategy methods.)
Common ground
Section titled “Common ground”Both tools converge on the same output your robot code wants: a Pose2d (or 3D pose), a timestamp, and a sense of confidence (more/closer tags = more trustworthy). That confidence is the bridge to the final lesson — fusing vision with odometry. Whatever tool you pick, validate it by placing the robot at a known spot on the field and confirming the reported pose matches a tape-measure check.
Key takeaways
Section titled “Key takeaways”- MegaTag2 uses your gyro heading to eliminate single-tag ambiguity; feed SetRobotOrientation every loop and read botpose_orb_wpiblue.
- PhotonVision’s PhotonPoseEstimator fuses all visible tags (multi-tag PnP) into one timestamped field pose.
- Both produce a Pose2d + timestamp + confidence, and both should be validated against a known field position.
This lesson was adapted from learnfrc.com.
