blob: 26188deb916885484efdc61250d4e3e58c7858c6 [file] [log] [blame]
Tyler Chatow37ecdcd2019-01-26 20:18:42 -08001#include "y2019/constants.h"
2
Tyler Chatowbf0609c2021-07-31 16:13:27 -07003#include <cinttypes>
Tyler Chatow37ecdcd2019-01-26 20:18:42 -08004#include <map>
5
6#if __has_feature(address_sanitizer)
7#include "sanitizer/lsan_interface.h"
8#endif
9
John Parkb859cf02019-11-20 19:52:05 -080010#include "absl/base/call_once.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070011#include "glog/logging.h"
12
Brian Silverman1463c092020-10-30 17:28:24 -070013#include "aos/network/team_number.h"
14#include "aos/stl_mutex/stl_mutex.h"
James Kuszmaulec635d22023-08-12 18:39:24 -070015#include "frc971/zeroing/absolute_encoder.h"
16#include "frc971/zeroing/pot_and_absolute_encoder.h"
Theo Bafrali00e42272019-02-12 01:07:46 -080017#include "y2019/control_loops/superstructure/elevator/integral_elevator_plant.h"
18#include "y2019/control_loops/superstructure/intake/integral_intake_plant.h"
19#include "y2019/control_loops/superstructure/stilts/integral_stilts_plant.h"
20#include "y2019/control_loops/superstructure/wrist/integral_wrist_plant.h"
James Kuszmaule2c71ea2019-03-04 08:14:21 -080021#include "y2019/vision/constants.h"
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080022
Stephan Pleinesf63bde82024-01-13 15:59:33 -080023namespace y2019::constants {
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080024
Theo Bafrali00e42272019-02-12 01:07:46 -080025using ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator;
26
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080027const int Values::kZeroingSampleSize;
James Kuszmaul09f564a2019-02-18 17:37:09 -080028constexpr size_t Values::kNumCameras;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080029
30namespace {
31
32const uint16_t kCompTeamNumber = 971;
33const uint16_t kPracticeTeamNumber = 9971;
Alex Perry5fb5ff22019-02-09 21:53:17 -080034const uint16_t kCodingRobotTeamNumber = 7971;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080035
Tyler Chatowa109af62019-10-23 21:19:52 -070036constexpr double FeetToMeters(double ft) { return 0.3048 * ft; }
37constexpr double InchToMeters(double in) { return 0.0254 * in; }
38constexpr double DegToRad(double deg) { return deg * M_PI / 180.0; }
James Kuszmaul22c5ab32019-02-09 14:45:58 -080039
James Kuszmaule2c71ea2019-03-04 08:14:21 -080040// Populates camera Pose information from the calibrated vision constants.
41void FillCameraPoses(
42 uint32_t teensy_processor_id,
43 ::std::array<Values::CameraCalibration, Values::kNumCameras> *cameras) {
44 ::std::array<int, 5> camera_ids =
45 vision::CameraSerialNumbers(teensy_processor_id);
46 for (size_t ii = 0; ii < camera_ids.size(); ++ii) {
47 const vision::CameraCalibration *calibration =
48 vision::GetCamera(camera_ids[ii]);
49 if (calibration != nullptr) {
50 vision::CameraGeometry geometry = calibration->geometry;
51 *cameras->at(ii).pose.mutable_pos() << geometry.location[0],
52 geometry.location[1], geometry.location[2];
53 cameras->at(ii).pose.set_theta(geometry.heading);
54 }
55 }
56}
57
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080058const Values *DoGetValuesForTeam(uint16_t team) {
59 Values *const r = new Values();
Alex Perry5fb5ff22019-02-09 21:53:17 -080060 Values::PotAndAbsConstants *const elevator = &r->elevator;
Theo Bafrali00e42272019-02-12 01:07:46 -080061 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
62 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator>
63 *const elevator_params = &(elevator->subsystem_params);
Alex Perry5fb5ff22019-02-09 21:53:17 -080064 Values::PotAndAbsConstants *const stilts = &r->stilts;
Theo Bafrali00e42272019-02-12 01:07:46 -080065 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
66 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator>
67 *const stilts_params = &(stilts->subsystem_params);
Alex Perry5fb5ff22019-02-09 21:53:17 -080068 Values::PotAndAbsConstants *const wrist = &r->wrist;
Theo Bafrali00e42272019-02-12 01:07:46 -080069 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
70 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator>
71 *const wrist_params = &(wrist->subsystem_params);
72 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
73 ::frc971::zeroing::AbsoluteEncoderZeroingEstimator> *const intake =
74 &r->intake;
Alex Perry5fb5ff22019-02-09 21:53:17 -080075
Theo Bafrali00e42272019-02-12 01:07:46 -080076 // Elevator constants.
Austin Schuh7f87b472019-02-15 23:20:57 -080077 elevator_params->zeroing_voltage = 3.0;
Theo Bafrali00e42272019-02-12 01:07:46 -080078 elevator_params->operating_voltage = 12.0;
James Kuszmaul31c45352024-01-14 18:07:42 -080079 elevator_params->zeroing_profile_params = {{}, 0.1, 1.0};
80 elevator_params->default_profile_params = {{}, 4.0, 13.0};
Theo Bafrali00e42272019-02-12 01:07:46 -080081 elevator_params->range = Values::kElevatorRange();
82 elevator_params->make_integral_loop =
83 &control_loops::superstructure::elevator::MakeIntegralElevatorLoop;
84 elevator_params->zeroing_constants.average_filter_size =
85 Values::kZeroingSampleSize;
86 elevator_params->zeroing_constants.one_revolution_distance =
Alex Perry5fb5ff22019-02-09 21:53:17 -080087 M_PI * 2.0 * constants::Values::kElevatorEncoderRatio();
Theo Bafrali00e42272019-02-12 01:07:46 -080088 elevator_params->zeroing_constants.zeroing_threshold = 0.005;
89 elevator_params->zeroing_constants.moving_buffer_size = 20;
90 elevator_params->zeroing_constants.allowable_encoder_error = 0.9;
Alex Perry5fb5ff22019-02-09 21:53:17 -080091
Theo Bafrali00e42272019-02-12 01:07:46 -080092 // Wrist constants.
93 wrist_params->zeroing_voltage = 4.0;
94 wrist_params->operating_voltage = 12.0;
James Kuszmaul31c45352024-01-14 18:07:42 -080095 wrist_params->zeroing_profile_params = {{}, 0.5, 2.0};
96 wrist_params->default_profile_params = {{}, 10.0, 40.0};
Theo Bafrali00e42272019-02-12 01:07:46 -080097 wrist_params->range = Values::kWristRange();
98 wrist_params->make_integral_loop =
99 &control_loops::superstructure::wrist::MakeIntegralWristLoop;
100 wrist_params->zeroing_constants.average_filter_size =
101 Values::kZeroingSampleSize;
102 wrist_params->zeroing_constants.one_revolution_distance =
Alex Perry5fb5ff22019-02-09 21:53:17 -0800103 M_PI * 2.0 * constants::Values::kWristEncoderRatio();
Theo Bafrali00e42272019-02-12 01:07:46 -0800104 wrist_params->zeroing_constants.zeroing_threshold = 0.0005;
105 wrist_params->zeroing_constants.moving_buffer_size = 20;
106 wrist_params->zeroing_constants.allowable_encoder_error = 0.9;
107
108 // Intake constants.
Austin Schuh7f87b472019-02-15 23:20:57 -0800109 intake->zeroing_voltage = 3.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800110 intake->operating_voltage = 12.0;
James Kuszmaul31c45352024-01-14 18:07:42 -0800111 intake->zeroing_profile_params = {{}, 0.5, 3.0};
112 intake->default_profile_params = {{}, 6.0, 30.0};
Theo Bafrali00e42272019-02-12 01:07:46 -0800113 intake->range = Values::kIntakeRange();
114 intake->make_integral_loop =
115 control_loops::superstructure::intake::MakeIntegralIntakeLoop;
116 intake->zeroing_constants.average_filter_size = Values::kZeroingSampleSize;
117 intake->zeroing_constants.one_revolution_distance =
118 M_PI * 2.0 * constants::Values::kIntakeEncoderRatio();
119 intake->zeroing_constants.zeroing_threshold = 0.0005;
120 intake->zeroing_constants.moving_buffer_size = 20;
121 intake->zeroing_constants.allowable_encoder_error = 0.9;
Austin Schuhc9c157a2019-02-19 13:36:22 -0800122 intake->zeroing_constants.middle_position = Values::kIntakeRange().middle();
Theo Bafrali00e42272019-02-12 01:07:46 -0800123
124 // Stilts constants.
Austin Schuh7f87b472019-02-15 23:20:57 -0800125 stilts_params->zeroing_voltage = 3.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800126 stilts_params->operating_voltage = 12.0;
James Kuszmaul31c45352024-01-14 18:07:42 -0800127 stilts_params->zeroing_profile_params = {{}, 0.1, 0.5};
128 stilts_params->default_profile_params = {{}, 0.15, 0.5};
Theo Bafrali00e42272019-02-12 01:07:46 -0800129 stilts_params->range = Values::kStiltsRange();
130 stilts_params->make_integral_loop =
131 &control_loops::superstructure::stilts::MakeIntegralStiltsLoop;
132 stilts_params->zeroing_constants.average_filter_size =
133 Values::kZeroingSampleSize;
134 stilts_params->zeroing_constants.one_revolution_distance =
135 M_PI * 2.0 * constants::Values::kStiltsEncoderRatio();
136 stilts_params->zeroing_constants.zeroing_threshold = 0.0005;
137 stilts_params->zeroing_constants.moving_buffer_size = 20;
138 stilts_params->zeroing_constants.allowable_encoder_error = 0.9;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800139
James Kuszmaul09f564a2019-02-18 17:37:09 -0800140 r->camera_noise_parameters = {.max_viewable_distance = 10.0,
James Kuszmaul074429e2019-03-23 16:01:49 -0700141 .heading_noise = 0.1,
142 .nominal_distance_noise = 0.15,
James Kuszmaul7f1a4082019-04-14 10:50:44 -0700143 .nominal_skew_noise = 0.75,
James Kuszmaul09f564a2019-02-18 17:37:09 -0800144 .nominal_height_noise = 0.01};
145
James Kuszmaule2c71ea2019-03-04 08:14:21 -0800146 // Deliberately make FOV a bit large so that we are overly conservative in
147 // our EKF.
148 for (auto &camera : r->cameras) {
James Kuszmaul074429e2019-03-23 16:01:49 -0700149 camera.fov = M_PI_2 * 1.5;
James Kuszmaule2c71ea2019-03-04 08:14:21 -0800150 }
151
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800152 switch (team) {
153 // A set of constants for tests.
154 case 1:
Theo Bafrali00e42272019-02-12 01:07:46 -0800155 elevator_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800156 elevator->potentiometer_offset = 0.0;
157
Theo Bafrali00e42272019-02-12 01:07:46 -0800158 intake->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800159
Theo Bafrali00e42272019-02-12 01:07:46 -0800160 wrist_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800161 wrist->potentiometer_offset = 0.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800162
163 stilts_params->zeroing_constants.measured_absolute_position = 0.0;
164 stilts->potentiometer_offset = 0.0;
James Kuszmaul09f564a2019-02-18 17:37:09 -0800165
James Kuszmaule2c71ea2019-03-04 08:14:21 -0800166 // For the simulation, just place cameras at the center of the robot with
167 // nominal angles (back/sides + 15 degree offset front cameras).
James Kuszmaul09f564a2019-02-18 17:37:09 -0800168 r->cameras[0].pose.set_theta(M_PI);
169 r->cameras[1].pose.set_theta(0.26);
170 r->cameras[2].pose.set_theta(-0.26);
171 r->cameras[3].pose.set_theta(M_PI_2);
172 r->cameras[4].pose.set_theta(-M_PI_2);
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800173 break;
174
175 case kCompTeamNumber:
Austin Schuh13d58302019-05-08 20:10:20 -0700176 elevator_params->zeroing_constants.measured_absolute_position = 0.145498;
Austin Schuh37c102e2019-03-17 18:13:50 -0700177 elevator->potentiometer_offset =
178 -0.075017 + 0.015837 + 0.009793 - 0.012017 + 0.019915 + 0.010126 +
Austin Schuh13d58302019-05-08 20:10:20 -0700179 0.005541 + 0.006088 - 0.039687 + 0.005843 + 0.009007 + 0.008604 -
180 0.004621 + 0.003305;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800181
Austin Schuh85d758b2019-06-29 17:35:26 -0700182 intake->zeroing_constants.measured_absolute_position = 1.273143;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800183
Austin Schuh85d758b2019-06-29 17:35:26 -0700184 wrist_params->zeroing_constants.measured_absolute_position = 0.155868;
Austin Schuh588e10b2021-06-20 14:52:33 -0700185 wrist->potentiometer_offset =
186 -4.257454 - 0.058039 + 0.270233 - 0.661464 + 0.872911951453577;
Theo Bafrali00e42272019-02-12 01:07:46 -0800187
Austin Schuh37c102e2019-03-17 18:13:50 -0700188 stilts_params->zeroing_constants.measured_absolute_position = 0.066843;
189 stilts->potentiometer_offset = -0.015760 + 0.011604 - 0.061213 + 0.006690;
Austin Schuh48d3a962019-03-17 18:12:32 -0700190 FillCameraPoses(vision::CompBotTeensyId(), &r->cameras);
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800191 break;
192
193 case kPracticeTeamNumber:
Tyler Chatowa109af62019-10-23 21:19:52 -0700194 elevator_params->zeroing_constants.measured_absolute_position = 0.131568;
195 elevator->potentiometer_offset = -0.022320 + 0.020567 - 0.022355 -
196 0.006497 + 0.019690 + 0.009151 -
197 0.007513 + 0.007311;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800198
Tyler Chatowa109af62019-10-23 21:19:52 -0700199 intake->zeroing_constants.measured_absolute_position =
200 1.928755 + 0.205352;
Austin Schuhed7f8632019-02-15 23:12:20 -0800201
Tyler Chatowa109af62019-10-23 21:19:52 -0700202 wrist_params->zeroing_constants.measured_absolute_position = 0.180039;
Sabina Davisfe2e7122019-03-08 20:45:54 -0800203 wrist->potentiometer_offset = -4.200894 - 0.187134;
Austin Schuhed7f8632019-02-15 23:12:20 -0800204
Tyler Chatowa109af62019-10-23 21:19:52 -0700205 stilts_params->zeroing_constants.measured_absolute_position = 0.050556;
206 stilts->potentiometer_offset =
207 -0.093820 + 0.0124 - 0.008334 + 0.004507 - 0.007973 + -0.001221;
James Kuszmaulfedc4612019-03-10 11:24:51 -0700208
209 FillCameraPoses(vision::PracticeBotTeensyId(), &r->cameras);
Alex Perry5fb5ff22019-02-09 21:53:17 -0800210 break;
211
212 case kCodingRobotTeamNumber:
Theo Bafrali00e42272019-02-12 01:07:46 -0800213 elevator_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800214 elevator->potentiometer_offset = 0.0;
215
Theo Bafrali00e42272019-02-12 01:07:46 -0800216 intake->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800217
Theo Bafrali00e42272019-02-12 01:07:46 -0800218 wrist_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800219 wrist->potentiometer_offset = 0.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800220
221 stilts_params->zeroing_constants.measured_absolute_position = 0.0;
222 stilts->potentiometer_offset = 0.0;
James Kuszmaul81df16a2019-03-03 17:17:34 -0800223
James Kuszmaule2c71ea2019-03-04 08:14:21 -0800224 FillCameraPoses(vision::CodeBotTeensyId(), &r->cameras);
225
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800226 break;
227
228 default:
Brian Silvermanf4d329c2021-11-04 19:32:10 -0700229 LOG(FATAL) << "unknown team: " << team;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800230 }
231
232 return r;
233}
234
Brian Silverman1463c092020-10-30 17:28:24 -0700235void DoGetValues(const Values **result) {
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800236 uint16_t team = ::aos::network::GetTeamNumber();
Brian Silvermanf4d329c2021-11-04 19:32:10 -0700237 LOG(INFO) << "creating a Constants for team: " << team;
John Parkb859cf02019-11-20 19:52:05 -0800238 *result = DoGetValuesForTeam(team);
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800239}
240
241} // namespace
242
243const Values &GetValues() {
John Park9372a682019-11-27 18:07:48 -0800244 static absl::once_flag once;
Brian Silverman1463c092020-10-30 17:28:24 -0700245 static const Values *result;
John Park9372a682019-11-27 18:07:48 -0800246 absl::call_once(once, DoGetValues, &result);
John Parkb859cf02019-11-20 19:52:05 -0800247 return *result;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800248}
249
250const Values &GetValuesForTeam(uint16_t team_number) {
Brian Silverman1463c092020-10-30 17:28:24 -0700251 static aos::stl_mutex mutex;
252 std::unique_lock<aos::stl_mutex> locker(mutex);
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800253
254 // IMPORTANT: This declaration has to stay after the mutex is locked to avoid
255 // race conditions.
256 static ::std::map<uint16_t, const Values *> values;
257
258 if (values.count(team_number) == 0) {
259 values[team_number] = DoGetValuesForTeam(team_number);
260#if __has_feature(address_sanitizer)
261 __lsan_ignore_object(values[team_number]);
262#endif
263 }
264 return *values[team_number];
265}
266
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800267constexpr size_t Field::kNumTargets;
268constexpr size_t Field::kNumObstacles;
269
270Field::Field() {
271 // TODO(james): These values need to re-verified. I got them by skimming the
272 // manual and they all seem to be pretty much correct.
273 //
274 // Note: Per //frc971/control_loops/pose.h, coordinate system is:
275 // -In meters
276 // -Origin at center of our driver's station wall
277 // -Positive X-axis pointing straight out from driver's station
278 // -Positive Y-axis pointing straight left from the driver's perspective
279 // -Positive Z-axis is straight up.
280 // -The angle of the target is such that the angle is the angle you would
281 // need to be facing to see it straight-on. I.e., if the target angle is
282 // pi / 2.0, then you would be able to see it face on by facing straight
283 // left from the driver's point of view (if you were standing in the right
284 // spot).
285 constexpr double kCenterFieldX = FeetToMeters(27.0) + InchToMeters(1.125);
286
Tyler Chatowa109af62019-10-23 21:19:52 -0700287 constexpr double kFarSideCargoBayX = kCenterFieldX - InchToMeters(20.875);
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800288 constexpr double kMidSideCargoBayX = kFarSideCargoBayX - InchToMeters(21.75);
289 constexpr double kNearSideCargoBayX = kMidSideCargoBayX - InchToMeters(21.75);
290 constexpr double kSideCargoBayY = InchToMeters(24 + 3 + 0.875);
291 constexpr double kSideCargoBayTheta = -M_PI_2;
292
293 constexpr double kFaceCargoBayX =
294 kCenterFieldX - InchToMeters(7 * 12 + 11.75 + 9);
295 constexpr double kFaceCargoBayY = InchToMeters(10.875);
296 constexpr double kFaceCargoBayTheta = 0.0;
297
298 constexpr double kRocketX = kCenterFieldX - FeetToMeters(8);
299 constexpr double kRocketY = InchToMeters((26 * 12 + 10.5) / 2.0);
300
301 constexpr double kRocketPortX = kRocketX;
302 constexpr double kRocketPortY = kRocketY - 0.70;
303 constexpr double kRocketPortTheta = M_PI_2;
304
305 // Half of portal + guess at width * cos(61.5 deg)
306 const double kRocketHatchXOffset = InchToMeters(14.634);
307 const double kRocketHatchY = kRocketPortY + InchToMeters(9.326);
308 const double kRocketNearX = kRocketX - kRocketHatchXOffset;
309 const double kRocketFarX = kRocketX + kRocketHatchXOffset;
310 constexpr double kRocketNearTheta = DegToRad(28.5);
311 constexpr double kRocketFarTheta = M_PI - kRocketNearTheta;
312
313 constexpr double kHpSlotY = InchToMeters((26 * 12 + 10.5) / 2.0 - 25.9);
314 constexpr double kHpSlotTheta = M_PI;
315
James Kuszmaule093f512019-03-20 06:14:05 -0700316 constexpr double kNormalZ = 0.80;
317 constexpr double kPortZ = 1.00;
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800318
James Kuszmaule093f512019-03-20 06:14:05 -0700319 constexpr double kDiscRadius = InchToMeters(19.0 / 2.0);
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800320
James Kuszmaule093f512019-03-20 06:14:05 -0700321 constexpr Target::GoalType kBothGoal = Target::GoalType::kBoth;
322 constexpr Target::GoalType kBallGoal = Target::GoalType::kBalls;
323 constexpr Target::GoalType kDiscGoal = Target::GoalType::kHatches;
324 constexpr Target::GoalType kNoneGoal = Target::GoalType::kNone;
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700325 using TargetType = Target::TargetType;
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800326
James Kuszmaule093f512019-03-20 06:14:05 -0700327 const Target far_side_cargo_bay(
328 {{kFarSideCargoBayX, kSideCargoBayY, kNormalZ}, kSideCargoBayTheta},
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700329 kDiscRadius, TargetType::kFarSideCargoBay, kBothGoal);
James Kuszmaule093f512019-03-20 06:14:05 -0700330 const Target mid_side_cargo_bay(
331 {{kMidSideCargoBayX, kSideCargoBayY, kNormalZ}, kSideCargoBayTheta},
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700332 kDiscRadius, TargetType::kMidSideCargoBay, kBothGoal);
James Kuszmaule093f512019-03-20 06:14:05 -0700333 const Target near_side_cargo_bay(
334 {{kNearSideCargoBayX, kSideCargoBayY, kNormalZ}, kSideCargoBayTheta},
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700335 kDiscRadius, TargetType::kNearSideCargoBay, kBothGoal);
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800336
James Kuszmaule093f512019-03-20 06:14:05 -0700337 const Target face_cargo_bay(
338 {{kFaceCargoBayX, kFaceCargoBayY, kNormalZ}, kFaceCargoBayTheta},
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700339 kDiscRadius, TargetType::kFaceCargoBay, kBothGoal);
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800340
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700341 // The rocket port, since it is only for balls, has no meaningful radius
342 // to work with (and is over-ridden with zero in target_selector).
James Kuszmaule093f512019-03-20 06:14:05 -0700343 const Target rocket_port(
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700344 {{kRocketPortX, kRocketPortY, kPortZ}, kRocketPortTheta}, 0.0,
345 TargetType::kRocketPortal, kBallGoal);
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800346
James Kuszmaule093f512019-03-20 06:14:05 -0700347 const Target rocket_near(
348 {{kRocketNearX, kRocketHatchY, kNormalZ}, kRocketNearTheta}, kDiscRadius,
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700349 TargetType::kNearRocket, kDiscGoal);
James Kuszmaule093f512019-03-20 06:14:05 -0700350 const Target rocket_far(
351 {{kRocketFarX, kRocketHatchY, kNormalZ}, kRocketFarTheta}, kDiscRadius,
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700352 TargetType::kFarRocket, kDiscGoal);
James Kuszmaule093f512019-03-20 06:14:05 -0700353
James Kuszmaul074429e2019-03-23 16:01:49 -0700354 const Target hp_slot({{0.0, kHpSlotY, kNormalZ}, kHpSlotTheta}, 0.00,
James Kuszmaul7d1ef442019-03-23 20:20:50 -0700355 TargetType::kHPSlot, kBothGoal);
James Kuszmaule093f512019-03-20 06:14:05 -0700356
357 const ::std::array<Target, 8> quarter_field_targets{
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800358 {far_side_cargo_bay, mid_side_cargo_bay, near_side_cargo_bay,
359 face_cargo_bay, rocket_port, rocket_near, rocket_far, hp_slot}};
360
361 // Mirror across center field mid-line (short field axis):
James Kuszmaule093f512019-03-20 06:14:05 -0700362 ::std::array<Target, 16> half_field_targets;
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800363 ::std::copy(quarter_field_targets.begin(), quarter_field_targets.end(),
364 half_field_targets.begin());
365 for (int ii = 0; ii < 8; ++ii) {
366 const int jj = ii + 8;
367 half_field_targets[jj] = quarter_field_targets[ii];
James Kuszmaule093f512019-03-20 06:14:05 -0700368 half_field_targets[jj].mutable_pose()->mutable_pos()->x() =
369 2.0 * kCenterFieldX - half_field_targets[jj].pose().rel_pos().x();
370 half_field_targets[jj].mutable_pose()->set_theta(aos::math::NormalizeAngle(
371 M_PI - half_field_targets[jj].pose().rel_theta()));
372 // Targets on the opposite side of the field can't be driven to.
373 half_field_targets[jj].set_goal_type(kNoneGoal);
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800374 }
375
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800376 // Mirror across x-axis (long field axis):
377 ::std::copy(half_field_targets.begin(), half_field_targets.end(),
James Kuszmaule093f512019-03-20 06:14:05 -0700378 targets_.begin());
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800379 for (int ii = 0; ii < 16; ++ii) {
380 const int jj = ii + 16;
James Kuszmaule093f512019-03-20 06:14:05 -0700381 targets_[jj] = half_field_targets[ii];
382 targets_[jj].mutable_pose()->mutable_pos()->y() *= -1;
383 targets_[jj].mutable_pose()->set_theta(-targets_[jj].pose().rel_theta());
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800384 }
385
386 // Define rocket obstacles as just being a single line that should block any
387 // cameras trying to see through the rocket up and down the field.
388 // This line is parallel to the driver's station wall and extends behind
389 // the portal.
390 Obstacle rocket_obstacle({{kRocketPortX, kRocketY, 0.0}, 0.0},
391 {{kRocketPortX, kRocketPortY + 0.01, 0.0}, 0.0});
392 // First, we mirror rocket obstacles across x-axis:
393 Obstacle rocket_obstacle2({{kRocketPortX, -kRocketY, 0.0}, 0.0},
394 {{kRocketPortX, -kRocketPortY - 0.01, 0.0}, 0.0});
395
396 // Define an obstacle for the Hab that extends striaght out a few feet from
397 // the driver's station wall.
398 // TODO(james): Does this actually block our view?
399 const double kHabL3X = FeetToMeters(4.0);
400 Obstacle hab_obstacle({}, {{kHabL3X, 0.0, 0.0}, 0.0});
401 ::std::array<Obstacle, 3> half_obstacles{
402 {rocket_obstacle, rocket_obstacle2, hab_obstacle}};
403 ::std::copy(half_obstacles.begin(), half_obstacles.end(), obstacles_.begin());
404
405 // Next, we mirror across the mid-line (short axis) to duplicate the
406 // rockets and hab to opposite side of the field.
407 for (int ii = 0; ii < 3; ++ii) {
408 const int jj = ii + 3;
409 obstacles_[jj] = half_obstacles[ii];
410 obstacles_[jj].mutable_pose1()->mutable_pos()->x() =
411 2.0 * kCenterFieldX - obstacles_[jj].mutable_pose1()->rel_pos().x();
412 obstacles_[jj].mutable_pose2()->mutable_pos()->x() =
413 2.0 * kCenterFieldX - obstacles_[jj].mutable_pose2()->rel_pos().x();
414 }
415
416 // Finally, define a rectangular cargo ship.
417 const double kCargoCornerX = kFaceCargoBayX + 0.1;
418 const double kCargoCornerY = kSideCargoBayY - 0.1;
419 ::std::array<Pose, 4> cargo_corners{
420 {{{kCargoCornerX, kCargoCornerY, 0.0}, 0.0},
421 {{kCargoCornerX, -kCargoCornerY, 0.0}, 0.0},
422 {{2.0 * kCenterFieldX - kCargoCornerX, -kCargoCornerY, 0.0}, 0.0},
423 {{2.0 * kCenterFieldX - kCargoCornerX, kCargoCornerY, 0.0}, 0.0}}};
424 for (int ii = 6; ii < 10; ++ii) {
425 obstacles_[ii] = Obstacle(cargo_corners[ii % cargo_corners.size()],
426 cargo_corners[(ii + 1) % cargo_corners.size()]);
427 }
428}
429
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800430} // namespace y2019::constants