blob: 4204b5c923e6310241c25ae4c375b42cf48a5379 [file] [log] [blame]
Tyler Chatow37ecdcd2019-01-26 20:18:42 -08001#include "y2019/constants.h"
2
3#include <inttypes.h>
4
5#include <map>
6
7#if __has_feature(address_sanitizer)
8#include "sanitizer/lsan_interface.h"
9#endif
10
11#include "aos/logging/logging.h"
12#include "aos/mutex/mutex.h"
13#include "aos/network/team_number.h"
14#include "aos/once.h"
Theo Bafrali00e42272019-02-12 01:07:46 -080015#include "y2019/control_loops/superstructure/elevator/integral_elevator_plant.h"
16#include "y2019/control_loops/superstructure/intake/integral_intake_plant.h"
17#include "y2019/control_loops/superstructure/stilts/integral_stilts_plant.h"
18#include "y2019/control_loops/superstructure/wrist/integral_wrist_plant.h"
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080019
20namespace y2019 {
21namespace constants {
22
Theo Bafrali00e42272019-02-12 01:07:46 -080023using ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator;
24
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080025const int Values::kZeroingSampleSize;
26
27namespace {
28
29const uint16_t kCompTeamNumber = 971;
30const uint16_t kPracticeTeamNumber = 9971;
Alex Perry5fb5ff22019-02-09 21:53:17 -080031const uint16_t kCodingRobotTeamNumber = 7971;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080032
James Kuszmaul22c5ab32019-02-09 14:45:58 -080033constexpr double FeetToMeters(double ft) {
34 return 0.3048 * ft;
35}
36constexpr double InchToMeters(double in) {
37 return 0.0254 * in;
38}
39constexpr double DegToRad(double deg) {
40 return deg * M_PI / 180.0;
41}
42
Tyler Chatow37ecdcd2019-01-26 20:18:42 -080043const Values *DoGetValuesForTeam(uint16_t team) {
44 Values *const r = new Values();
Alex Perry5fb5ff22019-02-09 21:53:17 -080045 Values::PotAndAbsConstants *const elevator = &r->elevator;
Theo Bafrali00e42272019-02-12 01:07:46 -080046 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
47 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator>
48 *const elevator_params = &(elevator->subsystem_params);
Alex Perry5fb5ff22019-02-09 21:53:17 -080049 Values::PotAndAbsConstants *const stilts = &r->stilts;
Theo Bafrali00e42272019-02-12 01:07:46 -080050 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
51 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator>
52 *const stilts_params = &(stilts->subsystem_params);
Alex Perry5fb5ff22019-02-09 21:53:17 -080053 Values::PotAndAbsConstants *const wrist = &r->wrist;
Theo Bafrali00e42272019-02-12 01:07:46 -080054 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
55 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator>
56 *const wrist_params = &(wrist->subsystem_params);
57 ::frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemParams<
58 ::frc971::zeroing::AbsoluteEncoderZeroingEstimator> *const intake =
59 &r->intake;
Alex Perry5fb5ff22019-02-09 21:53:17 -080060
Theo Bafrali00e42272019-02-12 01:07:46 -080061 // Elevator constants.
Austin Schuh7f87b472019-02-15 23:20:57 -080062 elevator_params->zeroing_voltage = 3.0;
Theo Bafrali00e42272019-02-12 01:07:46 -080063 elevator_params->operating_voltage = 12.0;
64 elevator_params->zeroing_profile_params = {0.1, 1.0};
Austin Schuh7f87b472019-02-15 23:20:57 -080065 elevator_params->default_profile_params = {4.0, 16.0};
Theo Bafrali00e42272019-02-12 01:07:46 -080066 elevator_params->range = Values::kElevatorRange();
67 elevator_params->make_integral_loop =
68 &control_loops::superstructure::elevator::MakeIntegralElevatorLoop;
69 elevator_params->zeroing_constants.average_filter_size =
70 Values::kZeroingSampleSize;
71 elevator_params->zeroing_constants.one_revolution_distance =
Alex Perry5fb5ff22019-02-09 21:53:17 -080072 M_PI * 2.0 * constants::Values::kElevatorEncoderRatio();
Theo Bafrali00e42272019-02-12 01:07:46 -080073 elevator_params->zeroing_constants.zeroing_threshold = 0.005;
74 elevator_params->zeroing_constants.moving_buffer_size = 20;
75 elevator_params->zeroing_constants.allowable_encoder_error = 0.9;
Alex Perry5fb5ff22019-02-09 21:53:17 -080076
Theo Bafrali00e42272019-02-12 01:07:46 -080077 // Wrist constants.
78 wrist_params->zeroing_voltage = 4.0;
79 wrist_params->operating_voltage = 12.0;
80 wrist_params->zeroing_profile_params = {0.5, 2.0};
Austin Schuh7f87b472019-02-15 23:20:57 -080081 wrist_params->default_profile_params = {10.0, 40.0};
Theo Bafrali00e42272019-02-12 01:07:46 -080082 wrist_params->range = Values::kWristRange();
83 wrist_params->make_integral_loop =
84 &control_loops::superstructure::wrist::MakeIntegralWristLoop;
85 wrist_params->zeroing_constants.average_filter_size =
86 Values::kZeroingSampleSize;
87 wrist_params->zeroing_constants.one_revolution_distance =
Alex Perry5fb5ff22019-02-09 21:53:17 -080088 M_PI * 2.0 * constants::Values::kWristEncoderRatio();
Theo Bafrali00e42272019-02-12 01:07:46 -080089 wrist_params->zeroing_constants.zeroing_threshold = 0.0005;
90 wrist_params->zeroing_constants.moving_buffer_size = 20;
91 wrist_params->zeroing_constants.allowable_encoder_error = 0.9;
92
93 // Intake constants.
Austin Schuh7f87b472019-02-15 23:20:57 -080094 intake->zeroing_voltage = 3.0;
Theo Bafrali00e42272019-02-12 01:07:46 -080095 intake->operating_voltage = 12.0;
96 intake->zeroing_profile_params = {0.5, 3.0};
Austin Schuh7f87b472019-02-15 23:20:57 -080097 intake->default_profile_params = {6.0, 30.0};
Theo Bafrali00e42272019-02-12 01:07:46 -080098 intake->range = Values::kIntakeRange();
99 intake->make_integral_loop =
100 control_loops::superstructure::intake::MakeIntegralIntakeLoop;
101 intake->zeroing_constants.average_filter_size = Values::kZeroingSampleSize;
102 intake->zeroing_constants.one_revolution_distance =
103 M_PI * 2.0 * constants::Values::kIntakeEncoderRatio();
104 intake->zeroing_constants.zeroing_threshold = 0.0005;
105 intake->zeroing_constants.moving_buffer_size = 20;
106 intake->zeroing_constants.allowable_encoder_error = 0.9;
107
108 // Stilts constants.
Austin Schuh7f87b472019-02-15 23:20:57 -0800109 stilts_params->zeroing_voltage = 3.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800110 stilts_params->operating_voltage = 12.0;
Austin Schuh7f87b472019-02-15 23:20:57 -0800111 stilts_params->zeroing_profile_params = {0.1, 0.5};
Austin Schuh6e5a3e12019-02-17 15:03:56 -0800112 stilts_params->default_profile_params = {0.1, 0.5};
Theo Bafrali00e42272019-02-12 01:07:46 -0800113 stilts_params->range = Values::kStiltsRange();
114 stilts_params->make_integral_loop =
115 &control_loops::superstructure::stilts::MakeIntegralStiltsLoop;
116 stilts_params->zeroing_constants.average_filter_size =
117 Values::kZeroingSampleSize;
118 stilts_params->zeroing_constants.one_revolution_distance =
119 M_PI * 2.0 * constants::Values::kStiltsEncoderRatio();
120 stilts_params->zeroing_constants.zeroing_threshold = 0.0005;
121 stilts_params->zeroing_constants.moving_buffer_size = 20;
122 stilts_params->zeroing_constants.allowable_encoder_error = 0.9;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800123
124 switch (team) {
125 // A set of constants for tests.
126 case 1:
Theo Bafrali00e42272019-02-12 01:07:46 -0800127 elevator_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800128 elevator->potentiometer_offset = 0.0;
129
Theo Bafrali00e42272019-02-12 01:07:46 -0800130 intake->zeroing_constants.measured_absolute_position = 0.0;
131 intake->zeroing_constants.middle_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800132
Theo Bafrali00e42272019-02-12 01:07:46 -0800133 wrist_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800134 wrist->potentiometer_offset = 0.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800135
136 stilts_params->zeroing_constants.measured_absolute_position = 0.0;
137 stilts->potentiometer_offset = 0.0;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800138 break;
139
140 case kCompTeamNumber:
Theo Bafrali00e42272019-02-12 01:07:46 -0800141 elevator_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800142 elevator->potentiometer_offset = 0.0;
143
Theo Bafrali00e42272019-02-12 01:07:46 -0800144 intake->zeroing_constants.measured_absolute_position = 0.0;
145 intake->zeroing_constants.middle_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800146
Theo Bafrali00e42272019-02-12 01:07:46 -0800147 wrist_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800148 wrist->potentiometer_offset = 0.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800149
150 stilts_params->zeroing_constants.measured_absolute_position = 0.0;
151 stilts->potentiometer_offset = 0.0;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800152 break;
153
154 case kPracticeTeamNumber:
Austin Schuhb12f9162019-02-17 22:33:38 -0800155 elevator_params->zeroing_constants.measured_absolute_position = 0.172663;
156 elevator->potentiometer_offset = -0.022320 + 0.020567;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800157
Austin Schuh862d4de2019-02-17 14:15:18 -0800158 intake->zeroing_constants.measured_absolute_position = 1.756847;
Austin Schuhed7f8632019-02-15 23:12:20 -0800159 intake->zeroing_constants.middle_position =
160 Values::kIntakeRange().middle();
Theo Bafrali00e42272019-02-12 01:07:46 -0800161
162 stilts_params->zeroing_constants.measured_absolute_position = 0.0;
163 stilts->potentiometer_offset = 0.0;
Austin Schuhed7f8632019-02-15 23:12:20 -0800164
165 wrist_params->zeroing_constants.measured_absolute_position = 0.357394;
166 wrist->potentiometer_offset = -1.479097 - 2.740303;
167
Austin Schuhb12f9162019-02-17 22:33:38 -0800168 stilts_params->zeroing_constants.measured_absolute_position = 0.036469;
169 stilts->potentiometer_offset = -0.093820 + 0.0124;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800170 break;
171
172 case kCodingRobotTeamNumber:
Theo Bafrali00e42272019-02-12 01:07:46 -0800173 elevator_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800174 elevator->potentiometer_offset = 0.0;
175
Theo Bafrali00e42272019-02-12 01:07:46 -0800176 intake->zeroing_constants.measured_absolute_position = 0.0;
177 intake->zeroing_constants.middle_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800178
Theo Bafrali00e42272019-02-12 01:07:46 -0800179 wrist_params->zeroing_constants.measured_absolute_position = 0.0;
Alex Perry5fb5ff22019-02-09 21:53:17 -0800180 wrist->potentiometer_offset = 0.0;
Theo Bafrali00e42272019-02-12 01:07:46 -0800181
182 stilts_params->zeroing_constants.measured_absolute_position = 0.0;
183 stilts->potentiometer_offset = 0.0;
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800184 break;
185
186 default:
187 LOG(FATAL, "unknown team #%" PRIu16 "\n", team);
188 }
189
190 return r;
191}
192
193const Values *DoGetValues() {
194 uint16_t team = ::aos::network::GetTeamNumber();
195 LOG(INFO, "creating a Constants for team %" PRIu16 "\n", team);
196 return DoGetValuesForTeam(team);
197}
198
199} // namespace
200
201const Values &GetValues() {
202 static ::aos::Once<const Values> once(DoGetValues);
203 return *once.Get();
204}
205
206const Values &GetValuesForTeam(uint16_t team_number) {
207 static ::aos::Mutex mutex;
208 ::aos::MutexLocker locker(&mutex);
209
210 // IMPORTANT: This declaration has to stay after the mutex is locked to avoid
211 // race conditions.
212 static ::std::map<uint16_t, const Values *> values;
213
214 if (values.count(team_number) == 0) {
215 values[team_number] = DoGetValuesForTeam(team_number);
216#if __has_feature(address_sanitizer)
217 __lsan_ignore_object(values[team_number]);
218#endif
219 }
220 return *values[team_number];
221}
222
James Kuszmaul22c5ab32019-02-09 14:45:58 -0800223constexpr size_t Field::kNumTargets;
224constexpr size_t Field::kNumObstacles;
225
226Field::Field() {
227 // TODO(james): These values need to re-verified. I got them by skimming the
228 // manual and they all seem to be pretty much correct.
229 //
230 // Note: Per //frc971/control_loops/pose.h, coordinate system is:
231 // -In meters
232 // -Origin at center of our driver's station wall
233 // -Positive X-axis pointing straight out from driver's station
234 // -Positive Y-axis pointing straight left from the driver's perspective
235 // -Positive Z-axis is straight up.
236 // -The angle of the target is such that the angle is the angle you would
237 // need to be facing to see it straight-on. I.e., if the target angle is
238 // pi / 2.0, then you would be able to see it face on by facing straight
239 // left from the driver's point of view (if you were standing in the right
240 // spot).
241 constexpr double kCenterFieldX = FeetToMeters(27.0) + InchToMeters(1.125);
242
243 constexpr double kFarSideCargoBayX =
244 kCenterFieldX - InchToMeters(20.875);
245 constexpr double kMidSideCargoBayX = kFarSideCargoBayX - InchToMeters(21.75);
246 constexpr double kNearSideCargoBayX = kMidSideCargoBayX - InchToMeters(21.75);
247 constexpr double kSideCargoBayY = InchToMeters(24 + 3 + 0.875);
248 constexpr double kSideCargoBayTheta = -M_PI_2;
249
250 constexpr double kFaceCargoBayX =
251 kCenterFieldX - InchToMeters(7 * 12 + 11.75 + 9);
252 constexpr double kFaceCargoBayY = InchToMeters(10.875);
253 constexpr double kFaceCargoBayTheta = 0.0;
254
255 constexpr double kRocketX = kCenterFieldX - FeetToMeters(8);
256 constexpr double kRocketY = InchToMeters((26 * 12 + 10.5) / 2.0);
257
258 constexpr double kRocketPortX = kRocketX;
259 constexpr double kRocketPortY = kRocketY - 0.70;
260 constexpr double kRocketPortTheta = M_PI_2;
261
262 // Half of portal + guess at width * cos(61.5 deg)
263 const double kRocketHatchXOffset = InchToMeters(14.634);
264 const double kRocketHatchY = kRocketPortY + InchToMeters(9.326);
265 const double kRocketNearX = kRocketX - kRocketHatchXOffset;
266 const double kRocketFarX = kRocketX + kRocketHatchXOffset;
267 constexpr double kRocketNearTheta = DegToRad(28.5);
268 constexpr double kRocketFarTheta = M_PI - kRocketNearTheta;
269
270 constexpr double kHpSlotY = InchToMeters((26 * 12 + 10.5) / 2.0 - 25.9);
271 constexpr double kHpSlotTheta = M_PI;
272
273 constexpr double kNormalZ = 0.80;
274 constexpr double kPortZ = 0.99;
275
276 const Pose far_side_cargo_bay({kFarSideCargoBayX, kSideCargoBayY, kNormalZ},
277 kSideCargoBayTheta);
278 const Pose mid_side_cargo_bay({kMidSideCargoBayX, kSideCargoBayY, kNormalZ},
279 kSideCargoBayTheta);
280 const Pose near_side_cargo_bay({kNearSideCargoBayX, kSideCargoBayY, kNormalZ},
281 kSideCargoBayTheta);
282
283 const Pose face_cargo_bay({kFaceCargoBayX, kFaceCargoBayY, kNormalZ},
284 kFaceCargoBayTheta);
285
286 const Pose rocket_port({kRocketPortX, kRocketPortY, kPortZ},
287 kRocketPortTheta);
288
289 const Pose rocket_near({kRocketNearX, kRocketHatchY, kNormalZ},
290 kRocketNearTheta);
291 const Pose rocket_far({kRocketFarX, kRocketHatchY, kNormalZ},
292 kRocketFarTheta);
293
294 const Pose hp_slot({0.0, kHpSlotY, kNormalZ}, kHpSlotTheta);
295
296 const ::std::array<Pose, 8> quarter_field_targets{
297 {far_side_cargo_bay, mid_side_cargo_bay, near_side_cargo_bay,
298 face_cargo_bay, rocket_port, rocket_near, rocket_far, hp_slot}};
299
300 // Mirror across center field mid-line (short field axis):
301 ::std::array<Pose, 16> half_field_targets;
302 ::std::copy(quarter_field_targets.begin(), quarter_field_targets.end(),
303 half_field_targets.begin());
304 for (int ii = 0; ii < 8; ++ii) {
305 const int jj = ii + 8;
306 half_field_targets[jj] = quarter_field_targets[ii];
307 half_field_targets[jj].mutable_pos()->x() =
308 2.0 * kCenterFieldX - half_field_targets[jj].rel_pos().x();
309 half_field_targets[jj].set_theta(
310 aos::math::NormalizeAngle(M_PI - half_field_targets[jj].rel_theta()));
311 }
312
313 ::std::array<Pose, 32> target_poses_;
314
315 // Mirror across x-axis (long field axis):
316 ::std::copy(half_field_targets.begin(), half_field_targets.end(),
317 target_poses_.begin());
318 for (int ii = 0; ii < 16; ++ii) {
319 const int jj = ii + 16;
320 target_poses_[jj] = half_field_targets[ii];
321 target_poses_[jj].mutable_pos()->y() *= -1;
322 target_poses_[jj].set_theta(-target_poses_[jj].rel_theta());
323 }
324 for (int ii = 0; ii < 32; ++ii) {
325 targets_[ii] = {target_poses_[ii]};
326 }
327
328 // Define rocket obstacles as just being a single line that should block any
329 // cameras trying to see through the rocket up and down the field.
330 // This line is parallel to the driver's station wall and extends behind
331 // the portal.
332 Obstacle rocket_obstacle({{kRocketPortX, kRocketY, 0.0}, 0.0},
333 {{kRocketPortX, kRocketPortY + 0.01, 0.0}, 0.0});
334 // First, we mirror rocket obstacles across x-axis:
335 Obstacle rocket_obstacle2({{kRocketPortX, -kRocketY, 0.0}, 0.0},
336 {{kRocketPortX, -kRocketPortY - 0.01, 0.0}, 0.0});
337
338 // Define an obstacle for the Hab that extends striaght out a few feet from
339 // the driver's station wall.
340 // TODO(james): Does this actually block our view?
341 const double kHabL3X = FeetToMeters(4.0);
342 Obstacle hab_obstacle({}, {{kHabL3X, 0.0, 0.0}, 0.0});
343 ::std::array<Obstacle, 3> half_obstacles{
344 {rocket_obstacle, rocket_obstacle2, hab_obstacle}};
345 ::std::copy(half_obstacles.begin(), half_obstacles.end(), obstacles_.begin());
346
347 // Next, we mirror across the mid-line (short axis) to duplicate the
348 // rockets and hab to opposite side of the field.
349 for (int ii = 0; ii < 3; ++ii) {
350 const int jj = ii + 3;
351 obstacles_[jj] = half_obstacles[ii];
352 obstacles_[jj].mutable_pose1()->mutable_pos()->x() =
353 2.0 * kCenterFieldX - obstacles_[jj].mutable_pose1()->rel_pos().x();
354 obstacles_[jj].mutable_pose2()->mutable_pos()->x() =
355 2.0 * kCenterFieldX - obstacles_[jj].mutable_pose2()->rel_pos().x();
356 }
357
358 // Finally, define a rectangular cargo ship.
359 const double kCargoCornerX = kFaceCargoBayX + 0.1;
360 const double kCargoCornerY = kSideCargoBayY - 0.1;
361 ::std::array<Pose, 4> cargo_corners{
362 {{{kCargoCornerX, kCargoCornerY, 0.0}, 0.0},
363 {{kCargoCornerX, -kCargoCornerY, 0.0}, 0.0},
364 {{2.0 * kCenterFieldX - kCargoCornerX, -kCargoCornerY, 0.0}, 0.0},
365 {{2.0 * kCenterFieldX - kCargoCornerX, kCargoCornerY, 0.0}, 0.0}}};
366 for (int ii = 6; ii < 10; ++ii) {
367 obstacles_[ii] = Obstacle(cargo_corners[ii % cargo_corners.size()],
368 cargo_corners[(ii + 1) % cargo_corners.size()]);
369 }
370}
371
Tyler Chatow37ecdcd2019-01-26 20:18:42 -0800372} // namespace constants
373} // namespace y2019