Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AprilTagFieldLayout JSON file and move class to edu.wpi.first.apriltag #4578

Merged
merged 14 commits into from
Nov 17, 2022

Conversation

pjreiniger
Copy link
Contributor

I think there is a pretty large benefit in having the april tags distributed with the code (obviously it wouldn't come bundled until the post-kickoff release, but that seems to work fine for glass / shuffleboard / pathweaver). I envision this will greatly reduce the number of "why doesn't the code find my file" if the user doesn't put it in their deploy folder. I see that frequently come up for pathweaver.

Now, the approach can be debated:

  1. Since AprilTagFieldLayout lives in wpilibc/j, bundle the file there. I think this would require duplicating the json file in both projects, which isn't impossible, but it feels icky

  2. (current pr) Make a new project that contains the field layout. This way you only have one copy of the file, but GradleRio will need to be updated to implicitly pull in the new dependency.

  3. (my favorite) Same as 2 but AprilTagFieldLayout moves to this new project as well, and breaks the DriverStation dependency (which also breaks deps on hal, ntcore, cscore, cameraserver. I mentioned this in the original PR.

  • I think breaking the dependency by renaming the function to setMirrored isn't that match of a mental hurdle. I can also envision some teams might not want to do that if they create separate paths for red / blue due to field build inconsistencies. Furthermore, if the game is like 2017 the field isn't rotationally symetrical, the logic in that function falls apart.
  • For non-robot use cases (maybe PhotonVision / doing something crazy on a co-processor / maybe you pull it into shuffleboard and draw tag locations on the field widget) The dependency split greatly reduces the amount of extra, seemingly unnecessary dependencies you need. The geometry portion of wpimath is pure java, so you can simply pull that in (even though that is 'bad behaviour')

The json file I'm using here is from the unnoficial apriltag layout mentioned on CD and used at a couple of offseasons. Once the dust settles on how / where you can decide if you want to leave the 2022 example in there for beta teams to use, or wait until kickoff and have 2023 be the first entry in the enum

@pjreiniger pjreiniger requested a review from a team as a code owner November 6, 2022 17:05
* @return The deserialized layout
* @throws IOException If the resource could not be loaded
*/
public static AprilTagFieldLayout loadFromResource(String resourcePath) throws IOException {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this and the predefined enum end up living together, I would also make a loadFromField function like I did for the field images

@calcmogul
Copy link
Member

calcmogul commented Nov 7, 2022

I think breaking the dependency by renaming the function to setMirrored isn't that match of a mental hurdle. I can also envision some teams might not want to do that if they create separate paths for red / blue due to field build inconsistencies. Furthermore, if the game is like 2017 the field isn't rotationally symetrical, the logic in that function falls apart.

The tags are all defined globally relative to the blue alliance, so all that alliance flag does is change where the origin is to be consistent between alliances (i.e., to the right of your alliance wall). It also reduces the amount of work for autonomous programmers in the typical case of a rotationally symmetric field. The tags have unique IDs, so there's no rotational symmetry to uphold with the tags themselves.

Copy link
Member

@calcmogul calcmogul left a comment

Choose a reason for hiding this comment

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

edu.wpi.first.apriltags has inconsistent pluralization with AprilTagFieldLayout's location of edu.wpi.first.wpilibj.apriltag.

@pjreiniger
Copy link
Contributor Author

The rotation stuff makes sense, but the real question is does that preclude the dependency chain break by renaming the function? It is absolutely wild to me that this simple library needs to pull in 4 extra shared libraries simply to get an enum value. Due to the static nature of the driver station you can't even cheat in java by using it without bringing the native stuff along since at the very least the HAL gets loaded immediately.

apriltags/CMakeLists.txt Outdated Show resolved Hide resolved
calcmogul
calcmogul previously approved these changes Nov 9, 2022
@pjreiniger
Copy link
Contributor Author

Does it make sense to move AprilTagLayout in here?

I'm guessing the approval without addressing setMirrored means the wpilibj et. al. deps are here to stay, but I think the AprilTag and AprilTagFieldLayout make more sense here. Then whatever you guys do for wrapping the real apriltag library can live along here as well.

I'd rather have this in the next beta than debate and miss it, but wanted to share my opinion.

@calcmogul
Copy link
Member

calcmogul commented Nov 9, 2022

This is an idealism vs pragmatism thing. Having an enum for alliance color makes dealing with the tag poses as easy as possible for users. Teams get shipped the entire library anyway, so it doesn't really matter if the class is lower in the dependency hierarchy.

With that said, an alternative would be for users to change their starting pose themselves based on what DriverStation.getAlliance() says, and removing that functionality from AprilTagFieldLayout (i.e., always assume tag poses are relative to blue alliance). They'd also have to rotate all their trajectories based on the alliance color.

@calcmogul
Copy link
Member

calcmogul commented Nov 12, 2022

After thinking about it more and discussing it on Chief Delphi, the coordinate system selection would probably be clearer if we renamed AprilTagFieldLayout.setAlliance(DriverStation.Alliance) to AprilTagFieldLayout.setOrigin(Pose3d) where Pose3d is a pose relative to the blue alliance wall right side. Static poses would be provided in the field layout class:

  • Pose3d kBlueAllianceWallRightSide;
  • Pose3d kRedAllianceWallRightSide{Translation2d{length, width, 0}, Rotation3d{zAxis, 180_deg}};

Users could use DriverStation.getAlliance() to pick a pose matching the color, making rotational symmetry exploitable.

if (DriverStation.getAlliance() == DriverStation.Alliance.kBlue) {
  fieldLayout.setOrigin(AprilTagFieldLayout.kBlueAllianceWallRightSide);
} else if (DriverStation.getAlliance() == DriverStation.Alliance.kRed) {
  fieldLayout.setOrigin(AprilTagFieldLayout.kRedAllianceWallRightSide);
}

This should at least be more intuitive than setMirrored(), but eliminate the library dependency on wpilibc/j.

@sciencewhiz
Copy link
Contributor

How likely is it that teams will want to modify the locations of the april tags based on specific field measurements?

@calcmogul
Copy link
Member

I think that'll depend on how accurately the field is constructed. Seems like measuring their true location directly would be difficult.

@pjreiniger
Copy link
Contributor Author

After thinking about it more

I like this idea. Leaves it open for extension. I implemented it slightly differently than mentioned, but it follows the same concept.

How likely is it that teams will want to modify the locations of the april tags based on specific field measurements?

I think your average team doesn't worry about this. This PR also does not prevent you from using the exiting functions to load from a file on disk. If you need that much fine grained control, I would recommend rolling your own altered pair of files. The big thing I was trying to achieve is to have a single source of truth, with easy access for the most common use cases

Copy link
Member

@calcmogul calcmogul left a comment

Choose a reason for hiding this comment

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

Besides minor docs nits, the API parts look good to me.

calcmogul
calcmogul previously approved these changes Nov 14, 2022
@calcmogul calcmogul changed the title [WIP] Add april tag field layout json file Add AprilTagFieldLayout JSON file and move class to edu.wpi.first.apriltag Nov 14, 2022
apriltags/build.gradle Outdated Show resolved Hide resolved
* This changes the GetTagPose(int) method to return the correct pose for your
* alliance.
*
* @param alliance The alliance to mirror poses for.
Copy link
Member

Choose a reason for hiding this comment

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

Is it a mirror or a 180 degree rotation?

Copy link
Member

Choose a reason for hiding this comment

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

The latter.

Copy link
Member

Choose a reason for hiding this comment

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

We should probably say that then.

Copy link
Member

@calcmogul calcmogul Nov 17, 2022

Choose a reason for hiding this comment

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

Specifically, it's a 180° rotation around the center of the field because the alliance stations are rotationally symmetric.

Copy link
Member

Choose a reason for hiding this comment

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

Let's PR this fix separately.

@PeterJohnson PeterJohnson merged commit 53904e7 into wpilibsuite:main Nov 17, 2022
@pjreiniger pjreiniger deleted the april_tag_field_layout branch December 4, 2023 08:53
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.

4 participants