|
13 | 13 | import java.util.List; |
14 | 14 | import java.util.Optional; |
15 | 15 | import java.util.function.Supplier; |
16 | | -import java.util.stream.Stream; |
17 | 16 | import org.photonvision.EstimatedRobotPose; |
18 | 17 | import org.photonvision.PhotonCamera; |
| 18 | +import org.photonvision.targeting.PhotonTrackedTarget; |
19 | 19 |
|
20 | 20 | /** |
21 | 21 | * Publishes timestamped pose estimates from a camera. |
@@ -76,32 +76,39 @@ public PhotonVisionPosePublisher(PhotonCamera camera, AprilTagFieldLayout aprilT |
76 | 76 | * @param poseEstimates The estimated locations (with the blue driver station as the origin). |
77 | 77 | */ |
78 | 78 | public void publish(List<EstimatedRobotPose> poseEstimates) { |
79 | | - robotPosePublisher.publish( |
| 79 | + // Publish all the estimated robot positions. |
| 80 | + List<TimestampedValue<Pose3d>> robotPoses = |
| 81 | + poseEstimates.stream().map(this::getRobotPoseFromEstimatedRobotPose).toList(); |
| 82 | + robotPosePublisher.publish(robotPoses); |
| 83 | + |
| 84 | + // Publish the location of the AprilTag used for the above estimated positions. |
| 85 | + List<TimestampedValue<Pose3d>> aprilTagPoses = |
80 | 86 | poseEstimates.stream() |
81 | | - .map(PhotonVisionPosePublisher::toRobotPoseTimestampedValue) |
82 | | - .toList()); |
83 | | - aprilTagPosePublisher.publish( |
84 | | - poseEstimates.stream().flatMap(this::toAprilTagPoseTimestampedValue).toList()); |
| 87 | + .map(this::getBestVisibleAprilTag) |
| 88 | + .flatMap(Optional::stream) // Convert Stream<Optional<V>> -> Stream<V> |
| 89 | + .toList(); |
| 90 | + aprilTagPosePublisher.publish(aprilTagPoses); |
85 | 91 | } |
86 | 92 |
|
87 | | - private static TimestampedValue<Pose3d> toRobotPoseTimestampedValue(EstimatedRobotPose pose) { |
| 93 | + /** Gets the robot pose from the EstimatedRobotPose and convert to a timestamped value. */ |
| 94 | + private TimestampedValue<Pose3d> getRobotPoseFromEstimatedRobotPose(EstimatedRobotPose pose) { |
88 | 95 | return TimestampedValue.withFpgaTimestamp( |
89 | 96 | pose.timestampSeconds, Units.Seconds, pose.estimatedPose); |
90 | 97 | } |
91 | 98 |
|
92 | | - private Stream<TimestampedValue<Pose3d>> toAprilTagPoseTimestampedValue(EstimatedRobotPose pose) { |
93 | | - if (pose.targetsUsed.isEmpty()) { |
94 | | - return Stream.empty(); |
| 99 | + /** Gets the highest-quality AprilTag used to estimate the position of the robot. */ |
| 100 | + private Optional<TimestampedValue<Pose3d>> getBestVisibleAprilTag( |
| 101 | + EstimatedRobotPose estimatedRobotPose) { |
| 102 | + List<PhotonTrackedTarget> visibleAprilTags = estimatedRobotPose.targetsUsed; |
| 103 | + if (visibleAprilTags.isEmpty()) { |
| 104 | + return Optional.empty(); |
95 | 105 | } |
96 | 106 |
|
97 | | - // Find the pose of the "best" AprilTag used for pose estimation and convert it to a timestamped |
98 | | - // value. |
99 | 107 | Optional<Pose3d> poseOfBestAprilTag = |
100 | | - aprilTagFieldLayout.getTagPose(pose.targetsUsed.get(0).fiducialId); |
101 | | - return poseOfBestAprilTag |
102 | | - .map( |
103 | | - tagPose -> |
104 | | - TimestampedValue.withFpgaTimestamp(pose.timestampSeconds, Units.Seconds, tagPose)) |
105 | | - .stream(); |
| 108 | + aprilTagFieldLayout.getTagPose(visibleAprilTags.get(0).fiducialId); |
| 109 | + return poseOfBestAprilTag.map( |
| 110 | + aprilTagPose -> |
| 111 | + TimestampedValue.withFpgaTimestamp( |
| 112 | + estimatedRobotPose.timestampSeconds, Units.Seconds, aprilTagPose)); |
106 | 113 | } |
107 | 114 | } |
0 commit comments