Detecting a tag is one thing; getting a reliable field pose from it is another. Both ecosystems provide higher-level pose estimation.
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
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
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
- 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.
Go deeper
Lesson quiz
RequiredAnswer all 3 questions correctly to complete this lesson.
01.What key assumption does Limelight's MegaTag2 make that MegaTag1 does not?
02.To use MegaTag2 correctly, what must robot code do each loop before reading the pose estimate?
03.In PhotonVision, what does the Coprocessor MultiTag pose strategy do?
Answer every question to submit.
All 51 lessons in Programming, Controls & Sensors
- Not started:Mini-Project: A Closed-Loop Elevator with Motion Magic
- Not started:Mini-Project: A Velocity-Controlled Shooter on REVLib
- Not started:Mini-Project: A Teleop Swerve Drive Subsystem
- Not started:Mini-Project: An Autonomous Routine with PathPlanner
- Not started:Mini-Project: Vision-Aligned Scoring with Limelight
- Not started:State-Space Control and Kalman Filtering
- Not started:Log Replay Architecture with AdvantageKit
- Not started:Advanced Pose Estimation: Multi-Tag Fusion and Standard Deviations
- Not started:Robot Coordination, Alerts, and Operator Feedback
- Not started:Case Study: Hardening Software Before an Event