Vision Fusion & Filtration
In the FRC 2026: REBUILT game, absolute field localization is a journey of Discovery. MARSLib’s MARSVision subsystem represents the peak of technical Innovation—combining data from multiple cameras and strictly filtering out “hallucinations” to ensure your robot always knows exactly where it belongs. This level of precision is what enables championship-grade Impact during the most chaotic moments of a match.
1 Strict Rejection Filters
Section titled “1 Strict Rejection Filters”Vision poses are frequently wrong during high-speed gameplay. Before a measurement reaches the Pose Estimator, it must survive five strict boundary checks:
-
Z-Height Hallucinations: If the pose estimates the robot is flying (Z > 0.5m), it’s rejected.
-
Out of Bounds: If the pose is tracked outside the physical field, it’s rejected.
-
Motion Blur: If the gyro reports > 120°/s yaw rate, vision is entirely blocked.
-
Beaching (Pitch/Roll): If you ride over an obstacle and tilt > 15°, the pose is rejected.
-
Ambiguity: Low quality single-tag solutions are discarded.
2 Quadratic StdDev Scaling
Section titled “2 Quadratic StdDev Scaling”Vision poses should mathematically never be trusted equally. A pose from 6 meters away is tiny on the camera sensor—1 pixel of error dramatically shifts the calculated location.
MARSLib enforces Quadratic StdDev Scaling. Trust in vision decays exponentially at long range, stopping the robot from making violent odometry correction jumps based on far-away tags.
3 Simulating Imperfection
Section titled “3 Simulating Imperfection”To ensure tuning works globally, the AprilTagVisionIOSim in MARSLib purposefully injects:
-
Gaussian Noise: StdDev matched jitter scaled by distance.
-
Dropped Frames: A 5% chance every frame that no pose is returned.
-
Latency: Simulates a 10ms-30ms phase delay offset.
4 Limelight Setup (10 min)
Section titled “4 Limelight Setup (10 min)”1. Physical Installation & Network:
- Mount camera slightly upward (10-15 degrees), 12-24 inches off ground.
- Connect computer to
limelight-<team>, go tohttp://10.0.0.1 - Set your FRC team number in Settings.
2. Configure AprilTag Pipeline:
- Pipeline:
0 - Exposure:
25 - Brightness:
50 - Gain:
50
3. Robot Code:
// MARSLib wrapperprivate final LimeLight limelight = new LimeLight();
public void periodic() { if (limelight.getIsTargetFound()) { SmartDashboard.putNumber("TargetX", limelight.getTx()); }}5 PhotonVision Setup (15 min)
Section titled “5 PhotonVision Setup (15 min)”1. Installation:
- Flash PhotonVision image to Raspberry Pi or OrangePi using BalenaEtcher.
- Connect computer to
PhotonVisionnetwork, go tohttp://10.0.0.1
2. Configure AprilTag Pipeline:
- Tag family:
k16h5(or36h11for newer seasons) - Exposure:
15 - Brightness:
50 - Gain:
30
3. Robot Code:
// MARSLib IO Abstractionprivate final PhotonPoseEstimator poseEstimator;
public void addVisionMeasurements() { vision.getBestTarget().ifPresent(target -> { var pose = poseEstimator.update(); pose.ifPresent(p -> odometry.addVisionMeasurement(p.estimatedPose.toPose2d(), p.timestampSeconds)); });}6 Performance Fast-Paths
Section titled “6 Performance Fast-Paths”Keep vision updates fast:
// Update vision at 50Hz (not faster!)@Overridepublic void periodic() { double now = Timer.getFPGATimestamp();
// Only process measurements every 20ms if (now - lastUpdate > 0.02) { addVisionMeasurements(); lastUpdate = now; }}📖 Further Reading & External Resources
Section titled “📖 Further Reading & External Resources”-
Limelight MegaTag 2.0 Breakdown - Understanding how FRC 1690 style IMU yaw-seeding rejects rapid AprilTag noise variations.
-
PhotonVision Hardware Guide - Best practices for illuminating targets globally.