1
1
package frc .robot ;
2
2
3
+ import edu .wpi .first .apriltag .AprilTagFieldLayout ;
3
4
import edu .wpi .first .math .geometry .*;
4
5
import edu .wpi .first .math .util .Units ;
5
- import java .util .ArrayList ;
6
- import java .util .HashMap ;
7
- import java .util .List ;
8
- import java .util .Map ;
6
+ import java .io .IOException ;
7
+ import java .util .*;
8
+ import lombok .Getter ;
9
9
10
10
/**
11
11
* Contains various field dimensions and useful reference points. All units are in meters and poses
12
12
* have a blue alliance origin.
13
13
*/
14
14
public class FieldConstants {
15
- public static final double fieldLength = Units .inchesToMeters (690.876 );
16
- public static final double fieldWidth = Units .inchesToMeters (317 );
15
+ public static AprilTagFieldLayout fieldLayout = AprilTagLayoutType .OFFICIAL .getFieldLayout ();
16
+
17
+ public static final double fieldLength =
18
+ AprilTagLayoutType .OFFICIAL .getFieldLayout ().getFieldLength ();
19
+ public static final double fieldWidth =
20
+ AprilTagLayoutType .OFFICIAL .getFieldLayout ().getFieldWidth ();
17
21
public static final double startingLineX =
18
22
Units .inchesToMeters (299.438 ); // Measured from the inside of starting line
19
23
20
24
public static class Processor {
21
25
public static final Pose2d centerFace =
22
- new Pose2d (Units .inchesToMeters (235.726 ), 0 , Rotation2d .fromDegrees (90 ));
26
+ new Pose2d (
27
+ AprilTagLayoutType .OFFICIAL .getFieldLayout ().getTagPose (16 ).get ().getX (),
28
+ 0 ,
29
+ Rotation2d .fromDegrees (90 ));
23
30
}
24
31
25
32
public static class Barge {
@@ -36,73 +43,76 @@ public static class Barge {
36
43
}
37
44
38
45
public static class CoralStation {
39
- public static final Pose2d leftCenterFace =
40
- new Pose2d (
41
- Units .inchesToMeters (33.526 ),
42
- Units .inchesToMeters (291.176 ),
43
- Rotation2d .fromDegrees (90 - 144.011 ));
46
+ public static final double stationLength = Units .inchesToMeters (79.750 );
44
47
public static final Pose2d rightCenterFace =
45
48
new Pose2d (
46
49
Units .inchesToMeters (33.526 ),
47
50
Units .inchesToMeters (25.824 ),
48
51
Rotation2d .fromDegrees (144.011 - 90 ));
52
+ public static final Pose2d leftCenterFace =
53
+ new Pose2d (
54
+ rightCenterFace .getX (),
55
+ fieldWidth - rightCenterFace .getY (),
56
+ Rotation2d .fromRadians (-rightCenterFace .getRotation ().getRadians ()));
57
+ }
58
+
59
+ public enum ReefLevel {
60
+ L1 (Units .inchesToMeters (25.0 ), 0 ),
61
+ L2 (Units .inchesToMeters (31.875 - Math .cos (Math .toRadians (35.0 )) * 0.625 ), -35 ),
62
+ L3 (Units .inchesToMeters (47.625 - Math .cos (Math .toRadians (35.0 )) * 0.625 ), -35 ),
63
+ L4 (Units .inchesToMeters (72 ), -90 );
64
+
65
+ public final double height ;
66
+ public final double pitch ;
67
+
68
+ ReefLevel (double height , double pitch ) {
69
+ this .height = height ;
70
+ this .pitch = pitch ; // Degrees
71
+ }
72
+
73
+ public static ReefLevel fromLevel (int level ) {
74
+ return Arrays .stream (values ())
75
+ .filter (height -> height .ordinal () == level )
76
+ .findFirst ()
77
+ .orElse (L4 );
78
+ }
49
79
}
50
80
51
81
public static class Reef {
82
+ public static final double faceLength = Units .inchesToMeters (36.792600 );
52
83
public static final Translation2d center =
53
- new Translation2d (Units .inchesToMeters (176.746 ), Units . inchesToMeters ( 158.501 ) );
84
+ new Translation2d (Units .inchesToMeters (176.746 ), fieldWidth / 2.0 );
54
85
public static final double faceToZoneLine =
55
86
Units .inchesToMeters (12 ); // Side of the reef to the inside of the reef zone line
56
87
57
88
public static final Pose2d [] centerFaces =
58
89
new Pose2d [6 ]; // Starting facing the driver station in clockwise order
59
- public static final List <Map <ReefHeight , Pose3d >> branchPositions =
90
+ public static final List <Map <ReefLevel , Pose3d >> branchPositions =
60
91
new ArrayList <>(); // Starting at the right branch facing the driver station in clockwise
92
+ public static final List <Map <ReefLevel , Pose2d >> branchPositions2d = new ArrayList <>();
61
93
62
94
static {
63
95
// Initialize faces
64
- centerFaces [0 ] =
65
- new Pose2d (
66
- Units .inchesToMeters (144.003 ),
67
- Units .inchesToMeters (158.500 ),
68
- Rotation2d .fromDegrees (180 ));
69
- centerFaces [1 ] =
70
- new Pose2d (
71
- Units .inchesToMeters (160.373 ),
72
- Units .inchesToMeters (186.857 ),
73
- Rotation2d .fromDegrees (120 ));
74
- centerFaces [2 ] =
75
- new Pose2d (
76
- Units .inchesToMeters (193.116 ),
77
- Units .inchesToMeters (186.858 ),
78
- Rotation2d .fromDegrees (60 ));
79
- centerFaces [3 ] =
80
- new Pose2d (
81
- Units .inchesToMeters (209.489 ),
82
- Units .inchesToMeters (158.502 ),
83
- Rotation2d .fromDegrees (0 ));
84
- centerFaces [4 ] =
85
- new Pose2d (
86
- Units .inchesToMeters (193.118 ),
87
- Units .inchesToMeters (130.145 ),
88
- Rotation2d .fromDegrees (-60 ));
89
- centerFaces [5 ] =
90
- new Pose2d (
91
- Units .inchesToMeters (160.375 ),
92
- Units .inchesToMeters (130.144 ),
93
- Rotation2d .fromDegrees (-120 ));
96
+ var aprilTagLayout = AprilTagLayoutType .OFFICIAL .getFieldLayout ();
97
+ centerFaces [0 ] = aprilTagLayout .getTagPose (18 ).get ().toPose2d ();
98
+ centerFaces [1 ] = aprilTagLayout .getTagPose (19 ).get ().toPose2d ();
99
+ centerFaces [2 ] = aprilTagLayout .getTagPose (20 ).get ().toPose2d ();
100
+ centerFaces [3 ] = aprilTagLayout .getTagPose (21 ).get ().toPose2d ();
101
+ centerFaces [4 ] = aprilTagLayout .getTagPose (22 ).get ().toPose2d ();
102
+ centerFaces [5 ] = aprilTagLayout .getTagPose (17 ).get ().toPose2d ();
94
103
95
104
// Initialize branch positions
96
105
for (int face = 0 ; face < 6 ; face ++) {
97
- Map <ReefHeight , Pose3d > fillRight = new HashMap <>();
98
- Map <ReefHeight , Pose3d > fillLeft = new HashMap <>();
99
- for (var level : ReefHeight .values ()) {
106
+ Map <ReefLevel , Pose3d > fillRight = new HashMap <>();
107
+ Map <ReefLevel , Pose3d > fillLeft = new HashMap <>();
108
+ Map <ReefLevel , Pose2d > fillRight2d = new HashMap <>();
109
+ Map <ReefLevel , Pose2d > fillLeft2d = new HashMap <>();
110
+ for (var level : ReefLevel .values ()) {
100
111
Pose2d poseDirection = new Pose2d (center , Rotation2d .fromDegrees (180 - (60 * face )));
101
112
double adjustX = Units .inchesToMeters (30.738 );
102
113
double adjustY = Units .inchesToMeters (6.469 );
103
114
104
- fillRight .put (
105
- level ,
115
+ var rightBranchPose =
106
116
new Pose3d (
107
117
new Translation3d (
108
118
poseDirection
@@ -115,9 +125,8 @@ public static class Reef {
115
125
new Rotation3d (
116
126
0 ,
117
127
Units .degreesToRadians (level .pitch ),
118
- poseDirection .getRotation ().getRadians ())));
119
- fillLeft .put (
120
- level ,
128
+ poseDirection .getRotation ().getRadians ()));
129
+ var leftBranchPose =
121
130
new Pose3d (
122
131
new Translation3d (
123
132
poseDirection
@@ -130,74 +139,44 @@ public static class Reef {
130
139
new Rotation3d (
131
140
0 ,
132
141
Units .degreesToRadians (level .pitch ),
133
- poseDirection .getRotation ().getRadians ())));
142
+ poseDirection .getRotation ().getRadians ()));
143
+
144
+ fillRight .put (level , rightBranchPose );
145
+ fillLeft .put (level , leftBranchPose );
146
+ fillRight2d .put (level , rightBranchPose .toPose2d ());
147
+ fillLeft2d .put (level , leftBranchPose .toPose2d ());
134
148
}
135
- branchPositions .add ((face * 2 ) + 1 , fillRight );
136
- branchPositions .add ((face * 2 ) + 2 , fillLeft );
149
+ branchPositions .add (fillRight );
150
+ branchPositions .add (fillLeft );
151
+ branchPositions2d .add (fillRight2d );
152
+ branchPositions2d .add (fillLeft2d );
137
153
}
138
154
}
139
155
}
140
156
141
157
public static class StagingPositions {
142
158
// Measured from the center of the ice cream
143
- public static final Pose2d leftIceCream =
144
- new Pose2d (Units .inchesToMeters (48 ), Units .inchesToMeters (230.5 ), new Rotation2d ());
159
+ public static final double separation = Units .inchesToMeters (72.0 );
145
160
public static final Pose2d middleIceCream =
146
- new Pose2d (Units .inchesToMeters (48 ), Units .inchesToMeters (158.5 ), new Rotation2d ());
161
+ new Pose2d (Units .inchesToMeters (48 ), fieldWidth / 2.0 , new Rotation2d ());
162
+ public static final Pose2d leftIceCream =
163
+ new Pose2d (Units .inchesToMeters (48 ), middleIceCream .getY () + separation , new Rotation2d ());
147
164
public static final Pose2d rightIceCream =
148
- new Pose2d (Units .inchesToMeters (48 ), Units . inchesToMeters ( 86.5 ) , new Rotation2d ());
165
+ new Pose2d (Units .inchesToMeters (48 ), middleIceCream . getY () - separation , new Rotation2d ());
149
166
}
150
167
151
- public enum ReefHeight {
152
- L4 (Units .inchesToMeters (72 ), -90 ),
153
- L3 (Units .inchesToMeters (47.625 ), -35 ),
154
- L2 (Units .inchesToMeters (31.875 ), -35 ),
155
- L1 (Units .inchesToMeters (18 ), 0 );
168
+ @ Getter
169
+ public enum AprilTagLayoutType {
170
+ OFFICIAL ("2025-reefscape-welded.json" );
156
171
157
- ReefHeight (double height , double pitch ) {
158
- this .height = height ;
159
- this .pitch = pitch ; // in degrees
160
- }
172
+ private final AprilTagFieldLayout fieldLayout ;
161
173
162
- public final double height ;
163
- public final double pitch ;
174
+ private AprilTagLayoutType (String file ) {
175
+ try {
176
+ fieldLayout = AprilTagFieldLayout .loadFromResource (file );
177
+ } catch (IOException exception ) {
178
+ throw new RuntimeException ("Failed to load AprilTagLayoutType: " + file , exception );
179
+ }
180
+ }
164
181
}
165
-
166
- // TODO
167
- // public static final double aprilTagWidth = Units.inchesToMeters(6.50);
168
- // public static final AprilTagLayoutType defaultAprilTagType = AprilTagLayoutType.OFFICIAL;
169
- // public static final int aprilTagCount = 22;
170
- //
171
- // @Getter
172
- // public enum AprilTagLayoutType {
173
- // OFFICIAL("2025-official");
174
- //
175
- // AprilTagLayoutType(String name) {
176
- // if (Constants.disableHAL) {
177
- // layout = null;
178
- // } else {
179
- // try {
180
- // layout =
181
- // new AprilTagFieldLayout(
182
- // Path.of(Filesystem.getDeployDirectory().getPath(), "apriltags", name +
183
- // ".json"));
184
- // } catch (IOException e) {
185
- // throw new RuntimeException(e);
186
- // }
187
- // }
188
- // if (layout == null) {
189
- // layoutString = "";
190
- // } else {
191
- // try {
192
- // layoutString = new ObjectMapper().writeValueAsString(layout);
193
- // } catch (JsonProcessingException e) {
194
- // throw new RuntimeException(
195
- // "Failed to serialize AprilTag layout JSON " + toString() + "for Northstar");
196
- // }
197
- // }
198
- // }
199
- //
200
- // private final AprilTagFieldLayout layout;
201
- // private final String layoutString;
202
- // }
203
182
}
0 commit comments