AprilTags are the fiducial markers placed around the FRC field. By detecting them with a camera, your robot can compute its own position on the field — enabling automated alignment, reliable autos, and shot-aiming. The 2026 REBUILT field uses the 36h11 tag family (IDs 1-32), with 8.125-inch tags on the Hub, Tower Wall, Outpost, and Trenches.
The architecture. Image processing is too heavy for the roboRIO, so it runs on a coprocessor — commonly an Orange Pi or Raspberry Pi running PhotonVision — connected by Ethernet to the radio. The camera (e.g. an Arducam OV9281 global-shutter or a Limelight) feeds PhotonVision, which detects tags and publishes results over NetworkTables. Your robot code reads them with the PhotonLib vendor library.
Calibrate first — this is non-negotiable for 3D. To get a tag's 3D pose you must calibrate the camera at the resolution you will run. In PhotonVision you photograph a ChArUco/chessboard board from many angles and distances. Calibration solves for focal length, optical center, and distortion. Skipping or rushing this is a top cause of garbage pose data.
Use the right field layout. For 2026 there are two official field layouts — the welded layout (which PhotonVision ships with) and the AndyMark layout. Select the one matching the event field, both on the coprocessor and in your pose-estimation setup, or every pose will be subtly wrong (the AndyMark vs welded difference can be ~0.5 inch).
MultiTag and pose estimation. Enabling MultiTag estimation lets PhotonVision combine all visible tags using the field-layout JSON to produce one robust camera-to-field pose. In code, PhotonPoseEstimator turns pipeline results into a robot pose. The professional move is to fuse vision into a SwerveDrivePoseEstimator (or DifferentialDrivePoseEstimator) with addVisionMeasurement(). Conceptually:
// Pull unread results, run the estimator, push valid poses in.
for (var result : camera.getAllUnreadResults()) {
Optional<EstimatedRobotPose> est = photonEstimator.update(result);
est.ifPresent(e ->
poseEstimator.addVisionMeasurement(
e.estimatedPose.toPose2d(), e.timestampSeconds));
}
The exact PhotonLib API moves between seasons — recent versions deprecated getLatestResult() in favor of getAllUnreadResults() and added strategy-specific estimate methods — so check the current PhotonVision docs for your installed version. The fusion idea is stable: blend fast wheel/gyro odometry with absolute vision corrections, so odometry gives smooth high-rate position while vision periodically snaps out accumulated drift. Tune the trust (standard deviations) so noisy single-tag readings don't yank the pose around.
The REBUILT payoff: a robot that knows its field pose can auto-align to the Hub for consistent Fuel shots and run repeatable autos that don't drift over the 20-second period. Create one PhotonPoseEstimator per camera; multiple cameras give more frequent corrections and fewer blind spots.
Key takeaways
- Run PhotonVision on a coprocessor (Pi/Orange Pi) reading 36h11 AprilTags; the roboRIO consumes results via PhotonLib over NetworkTables
- Calibrate the camera at your run resolution and select the correct 2026 field layout (welded vs AndyMark) on both coprocessor and pose estimator
- Fuse vision into a WPILib pose estimator with addVisionMeasurement(); the PhotonLib result API shifts by season (getAllUnreadResults replaced getLatestResult), so verify against your version's docs
Go deeper
Lesson quiz
RequiredAnswer all 3 questions correctly to complete this lesson.
01.What is the main advantage of PhotonVision's MultiTag localization?
02.What must be done before using 3D AprilTag tracking in PhotonVision?
03.What does PhotonPoseEstimator provide to the robot's pose estimation?
Answer every question to submit.
All 28 lessons in Getting Started with FRC
- Not started:Project 1 — Make a NEO Spin with the REV Hardware Client
- Not started:Project 2 — Deploy a Real Arcade-Drive Program
- Not started:Project 3 — Refactor into a Command-Based Drive Subsystem
- Not started:Project 4 — Build a Fuel Launcher for REBUILT
- Not started:Project 5 — A One-Button Autonomous Routine
- Not started:The Connection Chain: When the Driver Station Won't Connect
- Not started:Brownouts: Why the Robot Goes Limp Mid-Match
- Not started:CAN Bus Gremlins: Missing and Conflicting Devices
- Not started:Software Gotchas: Inverted Drives, Scheduler Stalls, and Reading the RioLog
- Not started:Inspection-Day Failures: Bumpers, Size, and Weight
- Not started:Closed-Loop Control: PID + Feedforward for a Consistent Shot
- Not started:Swerve Drive: Omnidirectional Movement with YAGSL
- Not started:AprilTag Vision: Knowing Where You Are with PhotonVision
- Not started:Data-Driven Strategy: Scouting, EPA/OPR, and Alliance Selection
- Not started:Choosing Your Hardware Ecosystem: REV vs CTRE