blob: 8408789a6a071e5d26f506184e45cbd527c436a3 [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) {
38 LOG(INFO, "Waiting until x > %f\n", x);
39 ::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) {
50 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) {
57 LOG(INFO, "Waiting until |y| < %f\n", y);
58 ::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) {
69 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()) {
100 LOG(ERROR, "Failed to reset localizer.\n");
101 }
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(); });
107 LOG(INFO, "Heading is %f\n", drivetrain_status_fetcher_->estimated_heading);
Austin Schuh13379ba2019-03-12 21:06:46 -0700108 InitializeEncoders();
109 ResetDrivetrain();
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700110 WaitUntil([this]() { return drivetrain_status_fetcher_.Fetch(); });
111 LOG(INFO, "Heading is %f\n", drivetrain_status_fetcher_->estimated_heading);
Austin Schuh13379ba2019-03-12 21:06:46 -0700112
113 ResetDrivetrain();
114 InitializeEncoders();
115}
116
117const ProfileParameters kJumpDrive = {2.0, 3.0};
118const ProfileParameters kDrive = {4.0, 3.0};
119const ProfileParameters kTurn = {5.0, 15.0};
120
Austin Schuhb5b79a52019-05-08 20:32:07 -0700121const ElevatorWristPosition kPanelHPIntakeForwrdPos{0.01, M_PI / 2.0};
122const ElevatorWristPosition kPanelHPIntakeBackwardPos{0.015, -M_PI / 2.0};
123
124const ElevatorWristPosition kPanelForwardMiddlePos{0.75, M_PI / 2.0};
125const ElevatorWristPosition kPanelBackwardMiddlePos{0.78, -M_PI / 2.0};
126
127const ElevatorWristPosition kPanelBackwardUpperPos{1.50, -M_PI / 2.0};
128
129const ElevatorWristPosition kPanelCargoBackwardPos{0.0, -M_PI / 2.0};
130
Austin Schuh13379ba2019-03-12 21:06:46 -0700131bool AutonomousActor::RunAction(
132 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuh77ed5432019-07-07 20:41:36 -0700133 const monotonic_clock::time_point start_time = monotonic_now();
Austin Schuha9644062019-03-28 14:31:52 -0700134 const bool is_left = params.mode == 0;
135
136 {
137 LOG(INFO, "Starting autonomous action with mode %" PRId32 " %s\n",
138 params.mode, is_left ? "left" : "right");
139 }
Austin Schuhb5b79a52019-05-08 20:32:07 -0700140
Austin Schuha9644062019-03-28 14:31:52 -0700141 const double turn_scalar = is_left ? 1.0 : -1.0;
142
143 Reset(is_left);
Austin Schuhb5b79a52019-05-08 20:32:07 -0700144 enum class Mode { kTesting, kRocket, kCargoship };
145 Mode mode = Mode::kCargoship;
146 if (mode == Mode::kRocket) {
147 SplineHandle spline1 =
148 PlanSpline(AutonomousSplines::HabToFarRocketTest(is_left),
149 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700150
Austin Schuhb5b79a52019-05-08 20:32:07 -0700151 // Grab the disk, jump, wait until we have vacuum, then raise the elevator
152 set_elevator_goal(0.010);
153 set_wrist_goal(-M_PI / 2.0);
154 set_intake_goal(-1.2);
155 set_suction_goal(true, 1);
156 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700157
Austin Schuhb5b79a52019-05-08 20:32:07 -0700158 // if planned start the spline and plan the next
159 if (!spline1.WaitForPlan()) return true;
160 LOG(INFO, "Planned\n");
161 spline1.Start();
Austin Schuh13379ba2019-03-12 21:06:46 -0700162
Austin Schuhb5b79a52019-05-08 20:32:07 -0700163 // If suction, move the superstructure to score
164 if (!WaitForGamePiece()) return true;
165 LOG(INFO, "Has game piece\n");
166 if (!spline1.WaitForSplineDistanceRemaining(3.5)) return true;
167 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
168 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700169
Austin Schuhb5b79a52019-05-08 20:32:07 -0700170 if (!spline1.WaitForSplineDistanceRemaining(2.0)) return true;
171 set_elevator_wrist_goal(kPanelForwardMiddlePos);
172 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700173
Austin Schuhb5b79a52019-05-08 20:32:07 -0700174 // END SPLINE 1
Austin Schuh13379ba2019-03-12 21:06:46 -0700175
Austin Schuhb5b79a52019-05-08 20:32:07 -0700176 if (!spline1.WaitForSplineDistanceRemaining(0.2)) return true;
177 LineFollowAtVelocity(1.3, 4);
178 if (!WaitForMilliseconds(::std::chrono::milliseconds(1200))) return true;
Austin Schuh13379ba2019-03-12 21:06:46 -0700179
Austin Schuhb5b79a52019-05-08 20:32:07 -0700180 set_suction_goal(false, 1);
181 SendSuperstructureGoal();
182 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
183 LineFollowAtVelocity(-1.0, 4);
184 SplineHandle spline2 = PlanSpline(AutonomousSplines::FarRocketToHP(is_left),
185 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700186
Austin Schuhb5b79a52019-05-08 20:32:07 -0700187 if (!WaitForMilliseconds(::std::chrono::milliseconds(150))) return true;
188 if (!spline2.WaitForPlan()) return true;
189 LOG(INFO, "Planned\n");
190 // Drive back to hp and set the superstructure accordingly
191 spline2.Start();
192 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
193 set_elevator_wrist_goal(kPanelHPIntakeBackwardPos);
194 SendSuperstructureGoal();
195 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
196 set_suction_goal(true, 1);
197 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700198
Austin Schuhb5b79a52019-05-08 20:32:07 -0700199 if (!spline2.WaitForSplineDistanceRemaining(1.6)) return true;
200 LineFollowAtVelocity(-1.6);
201
202 // As soon as we pick up Panel 2 go score on the back rocket
203 if (!WaitForGamePiece()) return true;
204 LineFollowAtVelocity(1.5);
205 SplineHandle spline3 = PlanSpline(AutonomousSplines::HPToFarRocket(is_left),
206 SplineDirection::kForward);
207 if (!WaitForDriveXGreater(0.50)) return true;
208 if (!spline3.WaitForPlan()) return true;
209 spline3.Start();
210 LOG(INFO, "Has game piece\n");
211 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
212 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
213 SendSuperstructureGoal();
214 if (!WaitForDriveXGreater(7.1)) return true;
215 LineFollowAtVelocity(-1.5, 4);
216 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
217 set_elevator_wrist_goal(kPanelBackwardUpperPos);
218 SendSuperstructureGoal();
219 if (!WaitForMilliseconds(::std::chrono::milliseconds(1500))) return true;
220 set_suction_goal(false, 1);
221 SendSuperstructureGoal();
222 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
223 LineFollowAtVelocity(1.0, 4);
224 SendSuperstructureGoal();
225 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
226 } else if (mode == Mode::kCargoship) {
227 SplineHandle spline1 =
228 PlanSpline(AutonomousSplines::HABToSecondCargoShipBay(is_left),
229 SplineDirection::kBackward);
230 set_elevator_goal(0.01);
231 set_wrist_goal(-M_PI / 2.0);
232 set_intake_goal(-1.2);
233 set_suction_goal(true, 1);
234 SendSuperstructureGoal();
235
236 // if planned start the spline and plan the next
237 if (!spline1.WaitForPlan()) return true;
238 LOG(INFO, "Planned\n");
239 spline1.Start();
240
241 // If suction, move the superstructure to score
242 if (!WaitForGamePiece()) return true;
243 LOG(INFO, "Has game piece\n");
244 // unstick the hatch panel
245 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
246 set_elevator_goal(0.5);
247 set_wrist_goal(-M_PI / 2.0);
248 SendSuperstructureGoal();
249 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
250 set_elevator_wrist_goal(kPanelCargoBackwardPos);
251 SendSuperstructureGoal();
252
253 if (!spline1.WaitForSplineDistanceRemaining(0.8)) return true;
254 // Line follow in to the first disc.
255 LineFollowAtVelocity(-0.9, 2);
256 if (!WaitForDriveYCloseToZero(1.2)) return true;
257
258 set_suction_goal(false, 1);
259 SendSuperstructureGoal();
260 LOG(INFO, "Dropping disc 1 %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700261 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700262
263 if (!WaitForDriveYCloseToZero(1.13)) return true;
264 if (!WaitForMilliseconds(::std::chrono::milliseconds(300))) return true;
265
266 LineFollowAtVelocity(0.9, 2);
267 SplineHandle spline2 =
268 PlanSpline(AutonomousSplines::SecondCargoShipBayToHP(is_left),
269 SplineDirection::kForward);
270 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
271 if (!spline2.WaitForPlan()) return true;
272 LOG(INFO, "Planned\n");
273 // Drive back to hp and set the superstructure accordingly
274 spline2.Start();
275 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
276 set_elevator_wrist_goal(kPanelHPIntakeForwrdPos);
277 SendSuperstructureGoal();
278 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
279 set_suction_goal(true, 1);
280 SendSuperstructureGoal();
281
282 if (!spline2.WaitForSplineDistanceRemaining(1.75)) return true;
283 LineFollowAtVelocity(1.5);
284 // As soon as we pick up Panel 2 go score on the rocket
285 if (!WaitForGamePiece()) return true;
286 LOG(INFO, "Got gamepiece %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700287 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700288 LineFollowAtVelocity(-4.0);
289 SplineHandle spline3 =
290 PlanSpline(AutonomousSplines::HPToThirdCargoShipBay(is_left),
291 SplineDirection::kBackward);
292 if (!WaitForDriveXGreater(0.55)) return true;
293 if (!spline3.WaitForPlan()) return true;
294 spline3.Start();
295 // Wait until we are a bit out to lift.
296 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
297 set_elevator_wrist_goal(kPanelCargoBackwardPos);
298 SendSuperstructureGoal();
299
300 if (!spline3.WaitForSplineDistanceRemaining(0.7)) return true;
301 // Line follow in to the second disc.
302 LineFollowAtVelocity(-0.7, 3);
303 LOG(INFO, "Drawing in disc 2 %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700304 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700305 if (!WaitForDriveYCloseToZero(1.2)) return true;
306
307 set_suction_goal(false, 1);
308 SendSuperstructureGoal();
309 LOG(INFO, "Dropping disc 2 %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700310 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700311
312 if (!WaitForDriveYCloseToZero(1.13)) return true;
313 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
314 LOG(INFO, "Backing up %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700315 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700316 LineFollowAtVelocity(0.9, 3);
317 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
318 } else {
319 // Grab the disk, wait until we have vacuum, then jump
320 set_elevator_goal(0.01);
321 set_wrist_goal(-M_PI / 2.0);
322 set_intake_goal(-1.2);
323 set_suction_goal(true, 1);
324 SendSuperstructureGoal();
325
326 if (!WaitForGamePiece()) return true;
327 LOG(INFO, "Has game piece\n");
328
329 StartDrive(-4.0, 0.0, kJumpDrive, kTurn);
330 if (!WaitForDriveNear(3.3, 10.0)) return true;
331 LOG(INFO, "Lifting\n");
332 set_elevator_goal(0.30);
333 SendSuperstructureGoal();
334
335 if (!WaitForDriveNear(2.8, 10.0)) return true;
336 LOG(INFO, "Off the platform\n");
337
338 StartDrive(0.0, 1.00 * turn_scalar, kDrive, kTurn);
339 LOG(INFO, "Turn started\n");
340 if (!WaitForSuperstructureDone()) return true;
341 LOG(INFO, "Superstructure done\n");
342
343 if (!WaitForDriveNear(0.7, 10.0)) return true;
344 StartDrive(0.0, -0.35 * turn_scalar, kDrive, kTurn);
345
346 LOG(INFO, "Elevator up\n");
347 set_elevator_goal(0.78);
348 SendSuperstructureGoal();
349
350 if (!WaitForDriveDone()) return true;
351 LOG(INFO, "Done driving\n");
352
353 if (!WaitForSuperstructureDone()) return true;
354 }
Austin Schuh13379ba2019-03-12 21:06:46 -0700355
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700356 LOG(INFO, "Done %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700357 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh13379ba2019-03-12 21:06:46 -0700358
Austin Schuh13379ba2019-03-12 21:06:46 -0700359 return true;
360}
361
362} // namespace actors
363} // namespace y2019