Skip to content

Conversation

jasondaming
Copy link
Member

Summary

Creates a new comprehensive article documenting AprilTagFieldLayout usage, including loading layouts, getting tag poses, using setOrigin(), and avoiding common pitfalls.

Changes

  • New file: apriltag-field-layout.rst with complete AprilTagFieldLayout documentation
  • Covers loading pre-made field layouts and custom layouts
  • Documents getting tag poses by ID with examples
  • Explains setOrigin() for flipping coordinates between alliances
  • Documents common pitfalls (wrong coordinate system, incorrect alliance origin)
  • Includes code examples in Java, C++, and Python
  • Modified: index.rst to include new article in toctree

Fixes #2253

Creates new article documenting AprilTagFieldLayout usage including loading layouts, getting tag poses, using setOrigin(), and common pitfalls. Covers both premade field layouts and custom layouts.

Fixes wpilibsuite#2253

## Setting the Origin

One of the most common sources of confusion is the **origin location**. FRC fields are symmetric, with identical tag layouts on both the red and blue alliance sides. The field layout needs to know which alliance you're on to give you correct positions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes fields are rotationally symmetric -- in that the field can be rotated 180 degrees and the tags are in the same physical positions. 2025:

image

But sometimes fields have mirror symmetry (2024):

image

I wouldn't normally be such a pedant about this but in this particular context it's useful to know.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely correct!

// In robotInit() or robotPeriodic():
var alliance = DriverStation.getAlliance();
if (alliance.isPresent()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expand this example to handle the else case, so that you're always calling setOrigin() explicitly. Applies to all 3 language examples.

- Clarified field symmetry description (rotational vs mirror)
- Added else case to setOrigin() examples to always explicitly set origin
- Defaults to blue alliance when not connected to FMS
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.apriltag.AprilTagFieldLayout.OriginPosition;
// In robotInit() or robotPeriodic():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't put this in robotInit only. Isn't there already docs on getting alliance color safetly?

)
```

## Loading Custom Layouts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it needs more details to be useful. What is the spec for the file? How does it get to robot (put in deploy directory). Besides manually editing a file, how could you make one (use WPICal), etc.


The ``AprilTagFieldLayout`` class helps robots understand where AprilTags are located on the field. This is essential for using vision measurements with :doc:`pose estimators </docs/software/advanced-controls/state-space/state-space-pose-estimators>` to determine your robot's position.

## What is AprilTagFieldLayout?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like there should be a link to the coordinate system page somewhere

import edu.wpi.first.apriltag.AprilTagFields;
// Load the official field layout for the current year
AprilTagFieldLayout fieldLayout = AprilTagFieldLayout.loadField(AprilTagFields.k2024Crescendo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 2024?

#include <frc/apriltag/AprilTagFields.h>
// Load the official field layout for the current year
frc::AprilTagFieldLayout fieldLayout = frc::LoadAprilTagLayoutField(frc::AprilTagField::k2024Crescendo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this deprecated?

jasondaming and others added 3 commits October 13, 2025 20:24
Replace deprecated frc::LoadAprilTagLayoutField() with frc::AprilTagFieldLayout::LoadField() per the deprecation warning in the WPILib headers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Changes:
- Removed robotInit() from setOrigin() examples (alliance color not available during robotInit)
- Added note and link to alliancecolor.rst for getting alliance color safely
- Updated comments to suggest robotPeriodic(), autonomousInit(), or teleopInit()
- Expanded custom layouts section with:
  - JSON format specification and example
  - Deploy directory instructions
  - Multiple methods for creating layouts (manual, WPICalibrator, programmatic)
  - Code examples using Filesystem.getDeployDirectory()
- Added links to coordinate-system.rst in Common Pitfalls and See Also sections

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Changed from k2024Crescendo to k2025ReefscapeWelded to reflect the current year (2025).

Added note explaining the two 2025 field layout options (Welded vs AndyMark) so teams can choose the correct one for their practice field.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add docs about AprilTagFieldLayout

3 participants