blob: a5a71aa23ae14c72b96707267b7a037cc5f62773 [file] [log] [blame]
Austin Schuh13379ba2019-03-12 21:06:46 -07001#include "y2019/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
5#include <chrono>
6#include <cmath>
7
8#include "aos/logging/logging.h"
9#include "aos/util/phased_loop.h"
10
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12#include "frc971/control_loops/drivetrain/localizer.q.h"
Austin Schuh6bcc2302019-03-23 22:28:06 -070013#include "y2019/actors/auto_splines.h"
Austin Schuh13379ba2019-03-12 21:06:46 -070014#include "y2019/control_loops/drivetrain/drivetrain_base.h"
15
16namespace y2019 {
17namespace actors {
Austin Schuh13379ba2019-03-12 21:06:46 -070018using ::aos::monotonic_clock;
19namespace chrono = ::std::chrono;
20
Austin Schuh1bf8a212019-05-26 22:13:14 -070021AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
Austin Schuh13379ba2019-03-12 21:06:46 -070022 : frc971::autonomous::BaseAutonomousActor(
Austin Schuh1bf8a212019-05-26 22:13:14 -070023 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
Austin Schuheb99d072019-05-12 21:03:38 -070024 localizer_control_sender_(
25 event_loop->MakeSender<
26 ::frc971::control_loops::drivetrain::LocalizerControl>(
Austin Schuh170f4952019-06-29 18:58:30 -070027 ".frc971.control_loops.drivetrain.localizer_control")),
28 superstructure_goal_sender_(
29 event_loop->MakeSender<::y2019::control_loops::superstructure::
30 SuperstructureQueue::Goal>(
31 ".y2019.control_loops.superstructure.superstructure_queue.goal")),
32 superstructure_status_fetcher_(event_loop->MakeFetcher<
33 ::y2019::control_loops::superstructure::
34 SuperstructureQueue::Status>(
35 ".y2019.control_loops.superstructure.superstructure_queue.status")) {}
Austin Schuh13379ba2019-03-12 21:06:46 -070036
Austin Schuhb5b79a52019-05-08 20:32:07 -070037bool AutonomousActor::WaitForDriveXGreater(double x) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070038 AOS_LOG(INFO, "Waiting until x > %f\n", x);
Austin Schuhb5b79a52019-05-08 20:32:07 -070039 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -070040 event_loop()->monotonic_now(),
Austin Schuhb5b79a52019-05-08 20:32:07 -070041 ::std::chrono::milliseconds(5) / 2);
42
43 while (true) {
44 if (ShouldCancel()) {
45 return false;
46 }
47 phased_loop.SleepUntilNext();
Austin Schuhbd0a40f2019-06-30 14:56:31 -070048 drivetrain_status_fetcher_.Fetch();
49 if (drivetrain_status_fetcher_->x > x) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070050 AOS_LOG(INFO, "X at %f\n", drivetrain_status_fetcher_->x);
Austin Schuhb5b79a52019-05-08 20:32:07 -070051 return true;
52 }
53 }
54}
55
56bool AutonomousActor::WaitForDriveYCloseToZero(double y) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070057 AOS_LOG(INFO, "Waiting until |y| < %f\n", y);
Austin Schuhb5b79a52019-05-08 20:32:07 -070058 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -070059 event_loop()->monotonic_now(),
Austin Schuhb5b79a52019-05-08 20:32:07 -070060 ::std::chrono::milliseconds(5) / 2);
61
62 while (true) {
63 if (ShouldCancel()) {
64 return false;
65 }
66 phased_loop.SleepUntilNext();
Austin Schuhbd0a40f2019-06-30 14:56:31 -070067 drivetrain_status_fetcher_.Fetch();
68 if (::std::abs(drivetrain_status_fetcher_->y) < y) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070069 AOS_LOG(INFO, "Y at %f\n", drivetrain_status_fetcher_->y);
Austin Schuhb5b79a52019-05-08 20:32:07 -070070 return true;
71 }
72 }
73}
74
Austin Schuha9644062019-03-28 14:31:52 -070075void AutonomousActor::Reset(bool is_left) {
76 const double turn_scalar = is_left ? 1.0 : -1.0;
Austin Schuh13379ba2019-03-12 21:06:46 -070077 elevator_goal_ = 0.01;
78 wrist_goal_ = -M_PI / 2.0;
79 intake_goal_ = -1.2;
80
81 suction_on_ = false;
82 suction_gamepiece_ = 1;
83
84 elevator_max_velocity_ = 0.0;
85 elevator_max_acceleration_ = 0.0;
86 wrist_max_velocity_ = 0.0;
87 wrist_max_acceleration_ = 0.0;
88
89 InitializeEncoders();
90 SendSuperstructureGoal();
91
92 {
Austin Schuheb99d072019-05-12 21:03:38 -070093 auto localizer_resetter = localizer_control_sender_.MakeMessage();
Austin Schuh13379ba2019-03-12 21:06:46 -070094 // Start on the left l2.
95 localizer_resetter->x = 1.0;
Austin Schuhb5b79a52019-05-08 20:32:07 -070096 localizer_resetter->y = 1.35 * turn_scalar;
Austin Schuh13379ba2019-03-12 21:06:46 -070097 localizer_resetter->theta = M_PI;
Austin Schuhb5b79a52019-05-08 20:32:07 -070098 localizer_resetter->theta_uncertainty = 0.00001;
Austin Schuh13379ba2019-03-12 21:06:46 -070099 if (!localizer_resetter.Send()) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700100 AOS_LOG(ERROR, "Failed to reset localizer.\n");
Austin Schuh13379ba2019-03-12 21:06:46 -0700101 }
102 }
103
104 // Wait for the drivetrain to run so it has time to reset the heading.
105 // Otherwise our drivetrain reset will do a 180 right at the start.
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700106 WaitUntil([this]() { return drivetrain_status_fetcher_.Fetch(); });
Austin Schuhf257f3c2019-10-27 21:00:43 -0700107 AOS_LOG(INFO, "Heading is %f\n",
108 drivetrain_status_fetcher_->estimated_heading);
Austin Schuh13379ba2019-03-12 21:06:46 -0700109 InitializeEncoders();
110 ResetDrivetrain();
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700111 WaitUntil([this]() { return drivetrain_status_fetcher_.Fetch(); });
Austin Schuhf257f3c2019-10-27 21:00:43 -0700112 AOS_LOG(INFO, "Heading is %f\n",
113 drivetrain_status_fetcher_->estimated_heading);
Austin Schuh13379ba2019-03-12 21:06:46 -0700114
115 ResetDrivetrain();
116 InitializeEncoders();
117}
118
119const ProfileParameters kJumpDrive = {2.0, 3.0};
120const ProfileParameters kDrive = {4.0, 3.0};
121const ProfileParameters kTurn = {5.0, 15.0};
122
Austin Schuhb5b79a52019-05-08 20:32:07 -0700123const ElevatorWristPosition kPanelHPIntakeForwrdPos{0.01, M_PI / 2.0};
124const ElevatorWristPosition kPanelHPIntakeBackwardPos{0.015, -M_PI / 2.0};
125
126const ElevatorWristPosition kPanelForwardMiddlePos{0.75, M_PI / 2.0};
127const ElevatorWristPosition kPanelBackwardMiddlePos{0.78, -M_PI / 2.0};
128
129const ElevatorWristPosition kPanelBackwardUpperPos{1.50, -M_PI / 2.0};
130
131const ElevatorWristPosition kPanelCargoBackwardPos{0.0, -M_PI / 2.0};
132
Austin Schuh13379ba2019-03-12 21:06:46 -0700133bool AutonomousActor::RunAction(
134 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuh77ed5432019-07-07 20:41:36 -0700135 const monotonic_clock::time_point start_time = monotonic_now();
Austin Schuha9644062019-03-28 14:31:52 -0700136 const bool is_left = params.mode == 0;
137
138 {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700139 AOS_LOG(INFO, "Starting autonomous action with mode %" PRId32 " %s\n",
140 params.mode, is_left ? "left" : "right");
Austin Schuha9644062019-03-28 14:31:52 -0700141 }
Austin Schuhb5b79a52019-05-08 20:32:07 -0700142
Austin Schuha9644062019-03-28 14:31:52 -0700143 const double turn_scalar = is_left ? 1.0 : -1.0;
144
145 Reset(is_left);
Austin Schuhb5b79a52019-05-08 20:32:07 -0700146 enum class Mode { kTesting, kRocket, kCargoship };
147 Mode mode = Mode::kCargoship;
148 if (mode == Mode::kRocket) {
149 SplineHandle spline1 =
150 PlanSpline(AutonomousSplines::HabToFarRocketTest(is_left),
151 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700152
Austin Schuhb5b79a52019-05-08 20:32:07 -0700153 // Grab the disk, jump, wait until we have vacuum, then raise the elevator
154 set_elevator_goal(0.010);
155 set_wrist_goal(-M_PI / 2.0);
156 set_intake_goal(-1.2);
157 set_suction_goal(true, 1);
158 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700159
Austin Schuhb5b79a52019-05-08 20:32:07 -0700160 // if planned start the spline and plan the next
161 if (!spline1.WaitForPlan()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700162 AOS_LOG(INFO, "Planned\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700163 spline1.Start();
Austin Schuh13379ba2019-03-12 21:06:46 -0700164
Austin Schuhb5b79a52019-05-08 20:32:07 -0700165 // If suction, move the superstructure to score
166 if (!WaitForGamePiece()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700167 AOS_LOG(INFO, "Has game piece\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700168 if (!spline1.WaitForSplineDistanceRemaining(3.5)) return true;
169 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
170 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700171
Austin Schuhb5b79a52019-05-08 20:32:07 -0700172 if (!spline1.WaitForSplineDistanceRemaining(2.0)) return true;
173 set_elevator_wrist_goal(kPanelForwardMiddlePos);
174 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700175
Austin Schuhb5b79a52019-05-08 20:32:07 -0700176 // END SPLINE 1
Austin Schuh13379ba2019-03-12 21:06:46 -0700177
Austin Schuhb5b79a52019-05-08 20:32:07 -0700178 if (!spline1.WaitForSplineDistanceRemaining(0.2)) return true;
179 LineFollowAtVelocity(1.3, 4);
180 if (!WaitForMilliseconds(::std::chrono::milliseconds(1200))) return true;
Austin Schuh13379ba2019-03-12 21:06:46 -0700181
Austin Schuhb5b79a52019-05-08 20:32:07 -0700182 set_suction_goal(false, 1);
183 SendSuperstructureGoal();
184 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
185 LineFollowAtVelocity(-1.0, 4);
186 SplineHandle spline2 = PlanSpline(AutonomousSplines::FarRocketToHP(is_left),
187 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700188
Austin Schuhb5b79a52019-05-08 20:32:07 -0700189 if (!WaitForMilliseconds(::std::chrono::milliseconds(150))) return true;
190 if (!spline2.WaitForPlan()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700191 AOS_LOG(INFO, "Planned\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700192 // Drive back to hp and set the superstructure accordingly
193 spline2.Start();
194 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
195 set_elevator_wrist_goal(kPanelHPIntakeBackwardPos);
196 SendSuperstructureGoal();
197 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
198 set_suction_goal(true, 1);
199 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700200
Austin Schuhb5b79a52019-05-08 20:32:07 -0700201 if (!spline2.WaitForSplineDistanceRemaining(1.6)) return true;
202 LineFollowAtVelocity(-1.6);
203
204 // As soon as we pick up Panel 2 go score on the back rocket
205 if (!WaitForGamePiece()) return true;
206 LineFollowAtVelocity(1.5);
207 SplineHandle spline3 = PlanSpline(AutonomousSplines::HPToFarRocket(is_left),
208 SplineDirection::kForward);
209 if (!WaitForDriveXGreater(0.50)) return true;
210 if (!spline3.WaitForPlan()) return true;
211 spline3.Start();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700212 AOS_LOG(INFO, "Has game piece\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700213 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
214 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
215 SendSuperstructureGoal();
216 if (!WaitForDriveXGreater(7.1)) return true;
217 LineFollowAtVelocity(-1.5, 4);
218 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
219 set_elevator_wrist_goal(kPanelBackwardUpperPos);
220 SendSuperstructureGoal();
221 if (!WaitForMilliseconds(::std::chrono::milliseconds(1500))) return true;
222 set_suction_goal(false, 1);
223 SendSuperstructureGoal();
224 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
225 LineFollowAtVelocity(1.0, 4);
226 SendSuperstructureGoal();
227 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
228 } else if (mode == Mode::kCargoship) {
229 SplineHandle spline1 =
230 PlanSpline(AutonomousSplines::HABToSecondCargoShipBay(is_left),
231 SplineDirection::kBackward);
232 set_elevator_goal(0.01);
233 set_wrist_goal(-M_PI / 2.0);
234 set_intake_goal(-1.2);
235 set_suction_goal(true, 1);
236 SendSuperstructureGoal();
237
238 // if planned start the spline and plan the next
239 if (!spline1.WaitForPlan()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700240 AOS_LOG(INFO, "Planned\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700241 spline1.Start();
242
243 // If suction, move the superstructure to score
244 if (!WaitForGamePiece()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700245 AOS_LOG(INFO, "Has game piece\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700246 // unstick the hatch panel
247 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
248 set_elevator_goal(0.5);
249 set_wrist_goal(-M_PI / 2.0);
250 SendSuperstructureGoal();
251 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
252 set_elevator_wrist_goal(kPanelCargoBackwardPos);
253 SendSuperstructureGoal();
254
255 if (!spline1.WaitForSplineDistanceRemaining(0.8)) return true;
256 // Line follow in to the first disc.
257 LineFollowAtVelocity(-0.9, 2);
258 if (!WaitForDriveYCloseToZero(1.2)) return true;
259
260 set_suction_goal(false, 1);
261 SendSuperstructureGoal();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700262 AOS_LOG(INFO, "Dropping disc 1 %f\n",
263 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700264
265 if (!WaitForDriveYCloseToZero(1.13)) return true;
266 if (!WaitForMilliseconds(::std::chrono::milliseconds(300))) return true;
267
268 LineFollowAtVelocity(0.9, 2);
269 SplineHandle spline2 =
270 PlanSpline(AutonomousSplines::SecondCargoShipBayToHP(is_left),
271 SplineDirection::kForward);
272 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
273 if (!spline2.WaitForPlan()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700274 AOS_LOG(INFO, "Planned\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700275 // Drive back to hp and set the superstructure accordingly
276 spline2.Start();
277 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
278 set_elevator_wrist_goal(kPanelHPIntakeForwrdPos);
279 SendSuperstructureGoal();
280 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
281 set_suction_goal(true, 1);
282 SendSuperstructureGoal();
283
284 if (!spline2.WaitForSplineDistanceRemaining(1.75)) return true;
285 LineFollowAtVelocity(1.5);
286 // As soon as we pick up Panel 2 go score on the rocket
287 if (!WaitForGamePiece()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700288 AOS_LOG(INFO, "Got gamepiece %f\n",
289 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700290 LineFollowAtVelocity(-4.0);
291 SplineHandle spline3 =
292 PlanSpline(AutonomousSplines::HPToThirdCargoShipBay(is_left),
293 SplineDirection::kBackward);
294 if (!WaitForDriveXGreater(0.55)) return true;
295 if (!spline3.WaitForPlan()) return true;
296 spline3.Start();
297 // Wait until we are a bit out to lift.
298 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
299 set_elevator_wrist_goal(kPanelCargoBackwardPos);
300 SendSuperstructureGoal();
301
302 if (!spline3.WaitForSplineDistanceRemaining(0.7)) return true;
303 // Line follow in to the second disc.
304 LineFollowAtVelocity(-0.7, 3);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700305 AOS_LOG(INFO, "Drawing in disc 2 %f\n",
306 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700307 if (!WaitForDriveYCloseToZero(1.2)) return true;
308
309 set_suction_goal(false, 1);
310 SendSuperstructureGoal();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700311 AOS_LOG(INFO, "Dropping disc 2 %f\n",
312 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700313
314 if (!WaitForDriveYCloseToZero(1.13)) return true;
315 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700316 AOS_LOG(INFO, "Backing up %f\n",
317 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700318 LineFollowAtVelocity(0.9, 3);
319 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
320 } else {
321 // Grab the disk, wait until we have vacuum, then jump
322 set_elevator_goal(0.01);
323 set_wrist_goal(-M_PI / 2.0);
324 set_intake_goal(-1.2);
325 set_suction_goal(true, 1);
326 SendSuperstructureGoal();
327
328 if (!WaitForGamePiece()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700329 AOS_LOG(INFO, "Has game piece\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700330
331 StartDrive(-4.0, 0.0, kJumpDrive, kTurn);
332 if (!WaitForDriveNear(3.3, 10.0)) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700333 AOS_LOG(INFO, "Lifting\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700334 set_elevator_goal(0.30);
335 SendSuperstructureGoal();
336
337 if (!WaitForDriveNear(2.8, 10.0)) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700338 AOS_LOG(INFO, "Off the platform\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700339
340 StartDrive(0.0, 1.00 * turn_scalar, kDrive, kTurn);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700341 AOS_LOG(INFO, "Turn started\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700342 if (!WaitForSuperstructureDone()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700343 AOS_LOG(INFO, "Superstructure done\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700344
345 if (!WaitForDriveNear(0.7, 10.0)) return true;
346 StartDrive(0.0, -0.35 * turn_scalar, kDrive, kTurn);
347
Austin Schuhf257f3c2019-10-27 21:00:43 -0700348 AOS_LOG(INFO, "Elevator up\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700349 set_elevator_goal(0.78);
350 SendSuperstructureGoal();
351
352 if (!WaitForDriveDone()) return true;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700353 AOS_LOG(INFO, "Done driving\n");
Austin Schuhb5b79a52019-05-08 20:32:07 -0700354
355 if (!WaitForSuperstructureDone()) return true;
356 }
Austin Schuh13379ba2019-03-12 21:06:46 -0700357
Austin Schuhf257f3c2019-10-27 21:00:43 -0700358 AOS_LOG(INFO, "Done %f\n",
359 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh13379ba2019-03-12 21:06:46 -0700360
Austin Schuh13379ba2019-03-12 21:06:46 -0700361 return true;
362}
363
364} // namespace actors
365} // namespace y2019