blob: c35612fa017b909505fff41444f27a3fad44a7d3 [file] [log] [blame]
Comran Morshede68e3732016-03-12 14:12:11 +00001#include "y2016/actors/autonomous_actor.h"
2
Austin Schuh8aec1ed2016-05-01 13:29:20 -07003#include <chrono>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07004#include <cinttypes>
Comran Morshedb134e772016-03-16 21:05:05 +00005#include <cmath>
6
John Park33858a32018-09-28 23:05:48 -07007#include "aos/logging/logging.h"
James Kuszmaul651fc3f2019-05-15 21:14:25 -07008#include "aos/util/phased_loop.h"
Comran Morshed435f1112016-03-12 14:20:45 +00009#include "y2016/control_loops/drivetrain/drivetrain_base.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070010#include "y2016/control_loops/shooter/shooter_goal_generated.h"
11#include "y2016/control_loops/shooter/shooter_status_generated.h"
12#include "y2016/control_loops/superstructure/superstructure_goal_generated.h"
13#include "y2016/control_loops/superstructure/superstructure_status_generated.h"
14#include "y2016/queues/ball_detector_generated.h"
15#include "y2016/vision/vision_generated.h"
Comran Morshede68e3732016-03-12 14:12:11 +000016
17namespace y2016 {
18namespace actors {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080019using ::aos::monotonic_clock;
Alex Perrycb7da4b2019-08-28 19:35:56 -070020using ::frc971::ProfileParametersT;
21namespace superstructure = y2016::control_loops::superstructure;
22namespace shooter = y2016::control_loops::shooter;
Austin Schuhf2a50ba2016-12-24 16:16:26 -080023namespace chrono = ::std::chrono;
24namespace this_thread = ::std::this_thread;
Comran Morshed435f1112016-03-12 14:20:45 +000025
26namespace {
Alex Perrycb7da4b2019-08-28 19:35:56 -070027ProfileParametersT MakeProfileParameters(float max_velocity,
28 float max_acceleration) {
29 ProfileParametersT result;
30 result.max_velocity = max_velocity;
31 result.max_acceleration = max_acceleration;
32 return result;
33}
Comran Morshed435f1112016-03-12 14:20:45 +000034
Alex Perrycb7da4b2019-08-28 19:35:56 -070035const ProfileParametersT kSlowDrive = MakeProfileParameters(0.8, 2.5);
36const ProfileParametersT kLowBarDrive = MakeProfileParameters(1.3, 2.5);
37const ProfileParametersT kMoatDrive = MakeProfileParameters(1.2, 3.5);
38const ProfileParametersT kRealignDrive = MakeProfileParameters(2.0, 2.5);
39const ProfileParametersT kRockWallDrive = MakeProfileParameters(0.8, 2.5);
40const ProfileParametersT kFastDrive = MakeProfileParameters(3.0, 2.5);
Austin Schuh23b21802016-04-03 21:18:56 -070041
Alex Perrycb7da4b2019-08-28 19:35:56 -070042const ProfileParametersT kSlowTurn = MakeProfileParameters(0.8, 3.0);
43const ProfileParametersT kFastTurn = MakeProfileParameters(3.0, 10.0);
44const ProfileParametersT kStealTurn = MakeProfileParameters(4.0, 15.0);
45const ProfileParametersT kSwerveTurn = MakeProfileParameters(2.0, 7.0);
46const ProfileParametersT kFinishTurn = MakeProfileParameters(2.0, 5.0);
47
48const ProfileParametersT kTwoBallLowDrive = MakeProfileParameters(1.7, 3.5);
49const ProfileParametersT kTwoBallFastDrive = MakeProfileParameters(3.0, 1.5);
50const ProfileParametersT kTwoBallReturnDrive = MakeProfileParameters(3.0, 1.9);
51const ProfileParametersT kTwoBallReturnSlow = MakeProfileParameters(3.0, 2.5);
52const ProfileParametersT kTwoBallBallPickup = MakeProfileParameters(2.0, 1.75);
53const ProfileParametersT kTwoBallBallPickupAccel =
54 MakeProfileParameters(2.0, 2.5);
Austin Schuhf2a50ba2016-12-24 16:16:26 -080055
Comran Morshed435f1112016-03-12 14:20:45 +000056} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000057
Austin Schuh1bf8a212019-05-26 22:13:14 -070058AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
Philipp Schrader4bd29b12017-02-22 04:42:27 +000059 : frc971::autonomous::BaseAutonomousActor(
Austin Schuh1bf8a212019-05-26 22:13:14 -070060 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
61 vision_align_actor_factory_(
Austin Schuh28bde302019-05-26 22:24:33 -070062 actors::VisionAlignActor::MakeFactory(event_loop)),
63 vision_status_fetcher_(
Tyler Chatowbf0609c2021-07-31 16:13:27 -070064 event_loop->MakeFetcher<::y2016::vision::VisionStatus>("/vision")),
Austin Schuh4b652c92019-05-27 13:22:27 -070065 ball_detector_fetcher_(
66 event_loop->MakeFetcher<::y2016::sensors::BallDetector>(
Alex Perrycb7da4b2019-08-28 19:35:56 -070067 "/superstructure")),
Austin Schuhae023fb2019-06-29 17:11:45 -070068 shooter_goal_sender_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070069 event_loop->MakeSender<::y2016::control_loops::shooter::Goal>(
70 "/shooter")),
Austin Schuhae023fb2019-06-29 17:11:45 -070071 shooter_status_fetcher_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070072 event_loop->MakeFetcher<::y2016::control_loops::shooter::Status>(
73 "/shooter")),
Austin Schuh9481d0d2019-06-29 21:56:17 -070074 superstructure_status_fetcher_(
Austin Schuh9481d0d2019-06-29 21:56:17 -070075 event_loop
Alex Perrycb7da4b2019-08-28 19:35:56 -070076 ->MakeFetcher<::y2016::control_loops::superstructure::Status>(
77 "/superstructure")),
78 superstructure_goal_sender_(
79 event_loop->MakeSender<::y2016::control_loops::superstructure::Goal>(
80 "/superstructure")) {}
Comran Morshed435f1112016-03-12 14:20:45 +000081
Austin Schuhe4ec49c2016-04-24 19:07:15 -070082constexpr double kDoNotTurnCare = 2.0;
83
Comran Morshedb134e772016-03-16 21:05:05 +000084void AutonomousActor::MoveSuperstructure(
85 double intake, double shoulder, double wrist,
Alex Perrycb7da4b2019-08-28 19:35:56 -070086 const ProfileParametersT intake_params,
87 const ProfileParametersT shoulder_params,
88 const ProfileParametersT wrist_params, bool traverse_up,
Austin Schuh23b21802016-04-03 21:18:56 -070089 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +000090 superstructure_goal_ = {intake, shoulder, wrist};
91
Alex Perrycb7da4b2019-08-28 19:35:56 -070092 auto builder = superstructure_goal_sender_.MakeBuilder();
Comran Morshedb134e772016-03-16 21:05:05 +000093
Alex Perrycb7da4b2019-08-28 19:35:56 -070094 superstructure::Goal::Builder superstructure_goal_builder =
95 builder.MakeBuilder<superstructure::Goal>();
Comran Morshedb134e772016-03-16 21:05:05 +000096
Alex Perrycb7da4b2019-08-28 19:35:56 -070097 superstructure_goal_builder.add_angle_intake(intake);
98 superstructure_goal_builder.add_angle_shoulder(shoulder);
99 superstructure_goal_builder.add_angle_wrist(wrist);
Comran Morshedb134e772016-03-16 21:05:05 +0000100
Alex Perrycb7da4b2019-08-28 19:35:56 -0700101 superstructure_goal_builder.add_max_angular_velocity_intake(
102 intake_params.max_velocity);
103 superstructure_goal_builder.add_max_angular_velocity_shoulder(
104 shoulder_params.max_velocity);
105 superstructure_goal_builder.add_max_angular_velocity_wrist(
106 wrist_params.max_velocity);
Comran Morshedb134e772016-03-16 21:05:05 +0000107
Alex Perrycb7da4b2019-08-28 19:35:56 -0700108 superstructure_goal_builder.add_max_angular_acceleration_intake(
109 intake_params.max_acceleration);
110 superstructure_goal_builder.add_max_angular_acceleration_shoulder(
111 shoulder_params.max_acceleration);
112 superstructure_goal_builder.add_max_angular_acceleration_wrist(
113 wrist_params.max_acceleration);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700114
Alex Perrycb7da4b2019-08-28 19:35:56 -0700115 superstructure_goal_builder.add_voltage_top_rollers(roller_power);
116 superstructure_goal_builder.add_voltage_bottom_rollers(roller_power);
Comran Morshedb134e772016-03-16 21:05:05 +0000117
Alex Perrycb7da4b2019-08-28 19:35:56 -0700118 superstructure_goal_builder.add_traverse_unlatched(true);
119 superstructure_goal_builder.add_traverse_down(!traverse_up);
120 superstructure_goal_builder.add_voltage_climber(0.0);
121 superstructure_goal_builder.add_unfold_climber(false);
122
123 if (!builder.Send(superstructure_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700124 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
Comran Morshedb134e772016-03-16 21:05:05 +0000125 }
126}
127
Austin Schuh23b21802016-04-03 21:18:56 -0700128void AutonomousActor::OpenShooter() {
129 shooter_speed_ = 0.0;
130
Alex Perrycb7da4b2019-08-28 19:35:56 -0700131 auto builder = shooter_goal_sender_.MakeBuilder();
132 shooter::Goal::Builder shooter_goal_builder =
133 builder.MakeBuilder<shooter::Goal>();
134 shooter_goal_builder.add_angular_velocity(shooter_speed_);
135 shooter_goal_builder.add_clamp_open(true);
136 shooter_goal_builder.add_push_to_shooter(false);
137 shooter_goal_builder.add_force_lights_on(false);
138 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700139 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700140 }
141}
142
143void AutonomousActor::CloseShooter() {
144 shooter_speed_ = 0.0;
145
Alex Perrycb7da4b2019-08-28 19:35:56 -0700146 auto builder = shooter_goal_sender_.MakeBuilder();
147 shooter::Goal::Builder shooter_goal_builder =
148 builder.MakeBuilder<shooter::Goal>();
149 shooter_goal_builder.add_angular_velocity(shooter_speed_);
150 shooter_goal_builder.add_clamp_open(false);
151 shooter_goal_builder.add_push_to_shooter(false);
152 shooter_goal_builder.add_force_lights_on(false);
Austin Schuhae023fb2019-06-29 17:11:45 -0700153
Alex Perrycb7da4b2019-08-28 19:35:56 -0700154 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700155 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700156 }
157}
158
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700159void AutonomousActor::SetShooterSpeed(double speed) {
160 shooter_speed_ = speed;
161
162 // In auto, we want to have the lights on whenever possible since we have no
163 // hope of a human aligning the robot.
164 bool force_lights_on = shooter_speed_ > 1.0;
165
Alex Perrycb7da4b2019-08-28 19:35:56 -0700166 auto builder = shooter_goal_sender_.MakeBuilder();
167 shooter::Goal::Builder shooter_goal_builder =
168 builder.MakeBuilder<shooter::Goal>();
169 shooter_goal_builder.add_angular_velocity(shooter_speed_);
170 shooter_goal_builder.add_clamp_open(false);
171 shooter_goal_builder.add_push_to_shooter(false);
172 shooter_goal_builder.add_force_lights_on(force_lights_on);
Austin Schuhae023fb2019-06-29 17:11:45 -0700173
Alex Perrycb7da4b2019-08-28 19:35:56 -0700174 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700175 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700176 }
177}
178
179void AutonomousActor::Shoot() {
180 uint32_t initial_shots = 0;
181
Austin Schuhae023fb2019-06-29 17:11:45 -0700182 shooter_status_fetcher_.Fetch();
183 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700184 initial_shots = shooter_status_fetcher_->shots();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700185 }
186
187 // In auto, we want to have the lights on whenever possible since we have no
188 // hope of a human aligning the robot.
189 bool force_lights_on = shooter_speed_ > 1.0;
190
Alex Perrycb7da4b2019-08-28 19:35:56 -0700191 auto builder = shooter_goal_sender_.MakeBuilder();
192 shooter::Goal::Builder shooter_goal_builder =
193 builder.MakeBuilder<shooter::Goal>();
194 shooter_goal_builder.add_angular_velocity(shooter_speed_);
195 shooter_goal_builder.add_clamp_open(false);
196 shooter_goal_builder.add_push_to_shooter(true);
197 shooter_goal_builder.add_force_lights_on(force_lights_on);
Austin Schuhae023fb2019-06-29 17:11:45 -0700198
Alex Perrycb7da4b2019-08-28 19:35:56 -0700199 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700200 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700201 }
202
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700203 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700204 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700205 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700206 while (true) {
207 if (ShouldCancel()) return;
208
209 // Wait for the shot count to change so we know when the shot is complete.
Austin Schuhae023fb2019-06-29 17:11:45 -0700210 shooter_status_fetcher_.Fetch();
211 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700212 if (initial_shots < shooter_status_fetcher_->shots()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700213 return;
214 }
215 }
216 phased_loop.SleepUntilNext();
217 }
218}
219
220void AutonomousActor::WaitForShooterSpeed() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700221 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700222 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700223 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700224 while (true) {
225 if (ShouldCancel()) return;
226
Austin Schuhae023fb2019-06-29 17:11:45 -0700227 shooter_status_fetcher_.Fetch();
228 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700229 if (shooter_status_fetcher_->left()->ready() &&
230 shooter_status_fetcher_->right()->ready()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700231 return;
232 }
233 }
234 phased_loop.SleepUntilNext();
235 }
236}
237
238void AutonomousActor::AlignWithVisionGoal() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700239 vision_align_action::VisionAlignActionParamsT params;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700240 vision_action_ = vision_align_actor_factory_.Make(params);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700241 vision_action_->Start();
242}
243
Austin Schuh23b21802016-04-03 21:18:56 -0700244void AutonomousActor::WaitForAlignedWithVision(
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800245 chrono::nanoseconds align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700246 bool vision_valid = false;
247 double last_angle = 0.0;
248 int ready_to_fire = 0;
249
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700250 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700251 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700252 ::std::chrono::milliseconds(5) / 2);
Austin Schuh77ed5432019-07-07 20:41:36 -0700253 const monotonic_clock::time_point end_time = monotonic_now() + align_duration;
254 while (end_time > monotonic_now()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700255 if (ShouldCancel()) break;
256
Austin Schuh28bde302019-05-26 22:24:33 -0700257 vision_status_fetcher_.Fetch();
258 if (vision_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700259 vision_valid = (vision_status_fetcher_->left_image_valid() &&
260 vision_status_fetcher_->right_image_valid());
261 last_angle = vision_status_fetcher_->horizontal_angle();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700262 }
263
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700264 drivetrain_status_fetcher_.Fetch();
265 drivetrain_goal_fetcher_.Fetch();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700266
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700267 if (drivetrain_status_fetcher_.get() && drivetrain_goal_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700268 const double left_goal = drivetrain_goal_fetcher_->left_goal();
269 const double right_goal = drivetrain_goal_fetcher_->right_goal();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700270 const double left_current =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700271 drivetrain_status_fetcher_->estimated_left_position();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700272 const double right_current =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700273 drivetrain_status_fetcher_->estimated_right_position();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700274 const double left_velocity =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700275 drivetrain_status_fetcher_->estimated_left_velocity();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700276 const double right_velocity =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700277 drivetrain_status_fetcher_->estimated_right_velocity();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700278
279 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
280 ::std::abs((left_goal - right_goal) -
281 (left_current - right_current)) /
282 dt_config_.robot_radius / 2.0 <
283 0.02 &&
284 ::std::abs(left_velocity - right_velocity) < 0.01) {
285 ++ready_to_fire;
286 } else {
287 ready_to_fire = 0;
288 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700289 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700290 break;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700291 AOS_LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700292 }
293 }
294 phased_loop.SleepUntilNext();
295 }
296
297 vision_action_->Cancel();
298 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuhf257f3c2019-10-27 21:00:43 -0700299 AOS_LOG(INFO, "Done waiting for vision\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700300}
301
302bool AutonomousActor::IntakeDone() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700303 superstructure_status_fetcher_.Fetch();
Austin Schuh23b21802016-04-03 21:18:56 -0700304
305 constexpr double kProfileError = 1e-5;
306 constexpr double kEpsilon = 0.15;
307
Alex Perrycb7da4b2019-08-28 19:35:56 -0700308 if (superstructure_status_fetcher_->state() < 12 ||
309 superstructure_status_fetcher_->state() == 16) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700310 AOS_LOG(ERROR, "Superstructure no longer running, aborting action\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700311 return true;
312 }
313
Alex Perrycb7da4b2019-08-28 19:35:56 -0700314 if (::std::abs(superstructure_status_fetcher_->intake()->goal_angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700315 superstructure_goal_.intake) < kProfileError &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700316 ::std::abs(
317 superstructure_status_fetcher_->intake()->goal_angular_velocity()) <
318 kProfileError) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700319 AOS_LOG(DEBUG, "Profile done.\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700320 if (::std::abs(superstructure_status_fetcher_->intake()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700321 superstructure_goal_.intake) < kEpsilon &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700322 ::std::abs(
323 superstructure_status_fetcher_->intake()->angular_velocity()) <
324 kEpsilon) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700325 AOS_LOG(INFO, "Near goal, done.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700326 return true;
327 }
328 }
329 return false;
330}
331
332bool AutonomousActor::SuperstructureProfileDone() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700333 if (superstructure_status_fetcher_->state() < 12 ||
334 superstructure_status_fetcher_->state() == 16) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700335 AOS_LOG(ERROR, "Superstructure no longer running, aborting action\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700336 return true;
337 }
338
Austin Schuh9481d0d2019-06-29 21:56:17 -0700339 constexpr double kProfileError = 1e-5;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700340 return ::std::abs(superstructure_status_fetcher_->intake()->goal_angle() -
341 superstructure_goal_.intake) < kProfileError &&
342 ::std::abs(superstructure_status_fetcher_->shoulder()->goal_angle() -
343 superstructure_goal_.shoulder) < kProfileError &&
344 ::std::abs(superstructure_status_fetcher_->wrist()->goal_angle() -
345 superstructure_goal_.wrist) < kProfileError &&
346 ::std::abs(superstructure_status_fetcher_->intake()
347 ->goal_angular_velocity()) < kProfileError &&
348 ::std::abs(superstructure_status_fetcher_->shoulder()
349 ->goal_angular_velocity()) < kProfileError &&
Austin Schuh9481d0d2019-06-29 21:56:17 -0700350 ::std::abs(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700351 superstructure_status_fetcher_->wrist()->goal_angular_velocity()) <
352 kProfileError;
Austin Schuh9481d0d2019-06-29 21:56:17 -0700353}
354
355bool AutonomousActor::SuperstructureDone() {
356 superstructure_status_fetcher_.Fetch();
357
358 constexpr double kEpsilon = 0.03;
Austin Schuh23b21802016-04-03 21:18:56 -0700359 if (SuperstructureProfileDone()) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700360 AOS_LOG(DEBUG, "Profile done.\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700361 if (::std::abs(superstructure_status_fetcher_->intake()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700362 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700363 ::std::abs(superstructure_status_fetcher_->shoulder()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700364 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700365 ::std::abs(superstructure_status_fetcher_->wrist()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700366 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700367 ::std::abs(
368 superstructure_status_fetcher_->intake()->angular_velocity()) <
369 (kEpsilon + 0.1) &&
370 ::std::abs(
371 superstructure_status_fetcher_->shoulder()->angular_velocity()) <
372 (kEpsilon + 0.10) &&
373 ::std::abs(
374 superstructure_status_fetcher_->wrist()->angular_velocity()) <
375 (kEpsilon + 0.05)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700376 AOS_LOG(INFO, "Near goal, done.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700377 return true;
378 }
379 }
380 return false;
381}
382
383void AutonomousActor::WaitForIntake() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700384 WaitUntil(::std::bind(&AutonomousActor::IntakeDone, this));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700385}
386
Comran Morshedb134e772016-03-16 21:05:05 +0000387void AutonomousActor::WaitForSuperstructure() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700388 WaitUntil(::std::bind(&AutonomousActor::SuperstructureDone, this));
Austin Schuh23b21802016-04-03 21:18:56 -0700389}
Comran Morshedb134e772016-03-16 21:05:05 +0000390
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700391void AutonomousActor::WaitForSuperstructureProfile() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700392 WaitUntil([this]() {
393 superstructure_status_fetcher_.Fetch();
394 return SuperstructureProfileDone();
395 });
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700396}
397
Austin Schuh23b21802016-04-03 21:18:56 -0700398void AutonomousActor::WaitForSuperstructureLow() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700399 WaitUntil([this]() {
400 superstructure_status_fetcher_.Fetch();
Comran Morshedb134e772016-03-16 21:05:05 +0000401
Austin Schuh9481d0d2019-06-29 21:56:17 -0700402 return SuperstructureProfileDone() ||
Alex Perrycb7da4b2019-08-28 19:35:56 -0700403 superstructure_status_fetcher_->shoulder()->angle() < 0.1;
Austin Schuh9481d0d2019-06-29 21:56:17 -0700404 });
Comran Morshedb134e772016-03-16 21:05:05 +0000405}
Austin Schuh9481d0d2019-06-29 21:56:17 -0700406
Austin Schuh23b21802016-04-03 21:18:56 -0700407void AutonomousActor::BackLongShotLowBarTwoBall() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700408 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700409 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55,
410 MakeProfileParameters(7.0, 40.0),
411 MakeProfileParameters(4.0, 6.0),
412 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700413}
414
415void AutonomousActor::BackLongShotTwoBall() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700416 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700417 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55,
418 MakeProfileParameters(7.0, 40.0),
419 MakeProfileParameters(4.0, 6.0),
420 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700421}
422
423void AutonomousActor::BackLongShotTwoBallFinish() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700424 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700425 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625 + 0.03,
426 MakeProfileParameters(7.0, 40.0),
427 MakeProfileParameters(4.0, 6.0),
428 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700429}
430
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700431void AutonomousActor::BackLongShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700432 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700433 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62,
434 MakeProfileParameters(7.0, 40.0),
435 MakeProfileParameters(4.0, 6.0),
436 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700437}
438
439void AutonomousActor::BackMiddleShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700440 AOS_LOG(INFO, "Expanding for back middle shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700441 MoveSuperstructure(-0.05, M_PI / 2.0 - 0.2, -0.665,
442 MakeProfileParameters(7.0, 40.0),
443 MakeProfileParameters(4.0, 10.0),
444 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700445}
446
Austin Schuh3e4a5272016-04-20 20:11:00 -0700447void AutonomousActor::FrontLongShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700448 AOS_LOG(INFO, "Expanding for front long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700449 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02,
450 MakeProfileParameters(7.0, 40.0),
451 MakeProfileParameters(4.0, 6.0),
452 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700453}
454
455void AutonomousActor::FrontMiddleShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700456 AOS_LOG(INFO, "Expanding for front middle shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700457 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44,
458 MakeProfileParameters(7.0, 40.0),
459 MakeProfileParameters(4.0, 10.0),
460 MakeProfileParameters(10.0, 25.0), true, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700461}
462
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700463void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700464 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0,
465 MakeProfileParameters(7.0, 40.0),
466 MakeProfileParameters(4.0, 10.0),
467 MakeProfileParameters(10.0, 25.0), !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700468}
469
Austin Schuh3e4a5272016-04-20 20:11:00 -0700470void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700471 if (ShouldCancel()) return;
472 // Make sure that the base is aligned with the base.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700473 AOS_LOG(INFO, "Waiting for the superstructure\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700474 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700475
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800476 this_thread::sleep_for(chrono::milliseconds(500));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700477
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700478 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700479 AOS_LOG(INFO, "Triggering the vision actor\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700480 AlignWithVisionGoal();
481
482 // Wait for the drive base to be aligned with the target and make sure that
483 // the shooter is up to speed.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700484 AOS_LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800485 WaitForAlignedWithVision(chrono::milliseconds(2000));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700486 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700487 AOS_LOG(INFO, "Waiting for shooter to be up to speed\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700488 WaitForShooterSpeed();
489 if (ShouldCancel()) return;
490
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800491 this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhf257f3c2019-10-27 21:00:43 -0700492 AOS_LOG(INFO, "Shoot!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700493 Shoot();
494
495 // Turn off the shooter and fold up the superstructure.
496 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700497 AOS_LOG(INFO, "Stopping shooter\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700498 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700499 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700500 TuckArm(false, false);
501
502 // Wait for everything to be folded up.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700503 AOS_LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700504 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700505}
506
507void AutonomousActor::LowBarDrive() {
508 TuckArm(false, true);
509 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
510
511 if (!WaitForDriveNear(5.3, 0.0)) return;
512 TuckArm(true, true);
513
514 if (!WaitForDriveNear(5.0, 0.0)) return;
515
516 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
517
518 if (!WaitForDriveNear(3.0, 0.0)) return;
519
520 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
521
522 if (!WaitForDriveNear(1.0, 0.0)) return;
523
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700524 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700525}
526
Austin Schuh3e4a5272016-04-20 20:11:00 -0700527void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
528 double below, double above) {
529 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
530 if (!WaitForBelowAngle(below)) return;
531 if (!WaitForAboveAngle(above)) return;
532 // Ok, we are good now. Compensate by moving the goal by the error.
533 // Should be here at 2.7
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700534 drivetrain_status_fetcher_.Fetch();
535 if (drivetrain_status_fetcher_.get()) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700536 const double left_error =
537 (initial_drivetrain_.left -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700538 drivetrain_status_fetcher_->estimated_left_position());
Austin Schuh3e4a5272016-04-20 20:11:00 -0700539 const double right_error =
540 (initial_drivetrain_.right -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700541 drivetrain_status_fetcher_->estimated_right_position());
Austin Schuh3e4a5272016-04-20 20:11:00 -0700542 const double distance_to_go = (left_error + right_error) / 2.0;
543 const double distance_compensation =
544 goal_distance - tip_distance - distance_to_go;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700545 AOS_LOG(INFO, "Going %f further at the bump\n", distance_compensation);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700546 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
547 }
548}
549
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700550void AutonomousActor::MiddleDrive() {
551 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700552 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700553 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700554}
555
556void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700557 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700558 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700559 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700560
561 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700562 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700563}
564
565void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700566 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700567 constexpr double kDriveDistance = 5.10;
568 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
569
570 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
571 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700572
573 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700574 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700575}
Comran Morshedb134e772016-03-16 21:05:05 +0000576
Austin Schuh23b21802016-04-03 21:18:56 -0700577void AutonomousActor::CloseIfBall() {
Austin Schuh4b652c92019-05-27 13:22:27 -0700578 ball_detector_fetcher_.Fetch();
579 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700580 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh23b21802016-04-03 21:18:56 -0700581 if (ball_detected) {
582 CloseShooter();
583 }
584 }
585}
586
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700587void AutonomousActor::WaitForBallOrDriveDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700588 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700589 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700590 ::std::chrono::milliseconds(5) / 2);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700591 while (true) {
592 if (ShouldCancel()) {
593 return;
594 }
595 phased_loop.SleepUntilNext();
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700596 drivetrain_status_fetcher_.Fetch();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700597 if (IsDriveDone()) {
598 return;
599 }
600
Austin Schuh4b652c92019-05-27 13:22:27 -0700601 ball_detector_fetcher_.Fetch();
602 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700603 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700604 if (ball_detected) {
605 return;
606 }
607 }
608 }
609}
610
Austin Schuh3e4a5272016-04-20 20:11:00 -0700611void AutonomousActor::TwoBallAuto() {
Austin Schuh77ed5432019-07-07 20:41:36 -0700612 const monotonic_clock::time_point start_time = monotonic_now();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700613 OpenShooter();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700614 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
615 MakeProfileParameters(4.0, 10.0),
616 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700617 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700618 AOS_LOG(INFO, "Waiting for the intake to come down.\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700619
620 WaitForIntake();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700621 AOS_LOG(INFO, "Intake done at %f seconds, starting to drive\n",
622 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700623 if (ShouldCancel()) return;
624 const double kDriveDistance = 5.05;
625 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
626
627 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700628 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700629
Austin Schuh295c2d92016-05-01 12:28:04 -0700630 // Check if the ball is there.
631 bool first_ball_there = true;
Austin Schuh4b652c92019-05-27 13:22:27 -0700632 ball_detector_fetcher_.Fetch();
633 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700634 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh295c2d92016-05-01 12:28:04 -0700635 first_ball_there = ball_detected;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700636 AOS_LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
637 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh295c2d92016-05-01 12:28:04 -0700638 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700639 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 40.0),
640 MakeProfileParameters(4.0, 10.0),
641 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700642 AOS_LOG(INFO,
643 "Shutting off rollers at %f seconds, starting to straighten out\n",
644 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700645 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700646 MoveSuperstructure(-0.05, -0.010, 0.0, MakeProfileParameters(8.0, 40.0),
647 MakeProfileParameters(4.0, 10.0),
648 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700649 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700650 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700651
652 // We are now under the low bar. Start lifting.
653 BackLongShotLowBarTwoBall();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700654 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700655 SetShooterSpeed(640.0);
656 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
657
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700658 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
659 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700660 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
661 BackLongShotTwoBall();
662
663 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700664 AOS_LOG(INFO, "First shot done driving at %f seconds\n",
665 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700666
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700667 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700668
669 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700670 AlignWithVisionGoal();
671
672 WaitForShooterSpeed();
673 if (ShouldCancel()) return;
674
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800675 constexpr chrono::milliseconds kVisionExtra{0};
676 WaitForAlignedWithVision(chrono::milliseconds(500) + kVisionExtra);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700677 BackLongShotTwoBallFinish();
678 WaitForSuperstructureProfile();
679 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700680 AOS_LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700681 if (first_ball_there) {
682 Shoot();
683 } else {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700684 AOS_LOG(INFO, "Nah, not shooting\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700685 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700686
Austin Schuhf257f3c2019-10-27 21:00:43 -0700687 AOS_LOG(INFO, "First shot at %f seconds\n",
688 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700689 if (ShouldCancel()) return;
690
691 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700692 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700693 TuckArm(true, true);
694
695 // Undo vision move.
696 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
697 if (!WaitForDriveDone()) return;
698
699 constexpr double kBackDrive = 3.09 - 0.4;
700 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700701 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700702 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700703 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
704 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700705
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700706 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700707 AOS_LOG(INFO, "At Low Bar %f\n",
708 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700709
710 OpenShooter();
711 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700712 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
713 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700714 constexpr double kBallSmallWallTurn = -0.11;
715 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
716
Alex Perrycb7da4b2019-08-28 19:35:56 -0700717 MoveSuperstructure(0.03, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
718 MakeProfileParameters(4.0, 10.0),
719 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700720
721 if (!WaitForDriveProfileDone()) return;
722
Alex Perrycb7da4b2019-08-28 19:35:56 -0700723 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
724 MakeProfileParameters(4.0, 10.0),
725 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700726
Austin Schuhf257f3c2019-10-27 21:00:43 -0700727 AOS_LOG(INFO, "Done backing up %f\n",
728 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700729
730 constexpr double kDriveBackDistance = 5.15 - 0.4;
731 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
732 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700733 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700734
735 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700736 AOS_LOG(INFO, "Straightening up at %f\n",
737 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700738
739 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700740 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700741
Austin Schuh4b652c92019-05-27 13:22:27 -0700742 ball_detector_fetcher_.Fetch();
743 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700744 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700745 if (!ball_detected) {
746 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700747 AOS_LOG(INFO, "Aborting, no ball %f\n",
748 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700749 return;
750 }
751 }
752 CloseShooter();
753
754 BackLongShotLowBarTwoBall();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700755 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700756 SetShooterSpeed(640.0);
757 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
758
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700759 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700760 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
761 BackLongShotTwoBall();
762
763 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700764 AOS_LOG(INFO, "Second shot done driving at %f seconds\n",
765 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700766 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700767 AlignWithVisionGoal();
768 if (ShouldCancel()) return;
769
770 WaitForShooterSpeed();
771 if (ShouldCancel()) return;
772
773 // 2.2 with 0.4 of vision.
774 // 1.8 without any vision.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700775 AOS_LOG(INFO, "Going to vision align at %f\n",
776 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800777 WaitForAlignedWithVision(
778 (start_time + chrono::milliseconds(13500) + kVisionExtra * 2) -
Austin Schuh77ed5432019-07-07 20:41:36 -0700779 monotonic_now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700780 BackLongShotTwoBallFinish();
781 WaitForSuperstructureProfile();
782 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700783 AOS_LOG(INFO, "Shoot at %f\n",
784 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700785 Shoot();
786
Austin Schuhf257f3c2019-10-27 21:00:43 -0700787 AOS_LOG(INFO, "Second shot at %f seconds\n",
788 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700789 if (ShouldCancel()) return;
790
791 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700792 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700793 TuckArm(true, false);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700794 AOS_LOG(INFO, "Shot %f\n",
795 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700796
797 WaitForSuperstructureLow();
798
Austin Schuhf257f3c2019-10-27 21:00:43 -0700799 AOS_LOG(INFO, "Done %f\n",
800 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700801}
802
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700803void AutonomousActor::StealAndMoveOverBy(double distance) {
804 OpenShooter();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700805 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
806 MakeProfileParameters(4.0, 10.0),
807 MakeProfileParameters(10.0, 25.0), true, 12.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700808 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700809 AOS_LOG(INFO, "Waiting for the intake to come down.\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700810
811 WaitForIntake();
812 if (ShouldCancel()) return;
813 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
814 WaitForBallOrDriveDone();
815 if (ShouldCancel()) return;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700816 MoveSuperstructure(1.0, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
817 MakeProfileParameters(4.0, 10.0),
818 MakeProfileParameters(10.0, 25.0), true, 12.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700819
820 if (!WaitForDriveDone()) return;
821 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
822 if (!WaitForDriveDone()) return;
823}
824
Philipp Schrader4bd29b12017-02-22 04:42:27 +0000825bool AutonomousActor::RunAction(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700826 const ::frc971::autonomous::AutonomousActionParams *params) {
Austin Schuh77ed5432019-07-07 20:41:36 -0700827 monotonic_clock::time_point start_time = monotonic_now();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700828 AOS_LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n",
Alex Perrycb7da4b2019-08-28 19:35:56 -0700829 params->mode());
Comran Morshede68e3732016-03-12 14:12:11 +0000830
Comran Morshed435f1112016-03-12 14:20:45 +0000831 InitializeEncoders();
832 ResetDrivetrain();
833
Alex Perrycb7da4b2019-08-28 19:35:56 -0700834 switch (params->mode()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700835 case 0:
836 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700837 if (!WaitForDriveDone()) return true;
838 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700839 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700840 FrontLongShot();
841
842 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700843 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700844 SetShooterSpeed(640.0);
845
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700846 break;
847 case 1:
848 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700849 if (!WaitForDriveDone()) return true;
850 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700851 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700852 FrontMiddleShot();
853
854 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700855 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700856 SetShooterSpeed(600.0);
857
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700858 break;
859 case 2:
860 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700861 if (!WaitForDriveDone()) return true;
862 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700863 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700864 FrontMiddleShot();
865
866 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700867 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700868 SetShooterSpeed(600.0);
869
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700870 break;
871 case 3:
872 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700873 if (!WaitForDriveDone()) return true;
874 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700875 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700876 FrontMiddleShot();
877
878 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700879 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700880 SetShooterSpeed(600.0);
881
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700882 break;
883 case 4:
884 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700885 if (!WaitForDriveDone()) return true;
886 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700887 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700888 FrontMiddleShot();
889
890 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700891 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700892 SetShooterSpeed(600.0);
893
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700894 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700895 case 5:
Campbell Crowley9ed61a52016-11-05 17:13:07 -0700896 case 15:
Austin Schuh3e4a5272016-04-20 20:11:00 -0700897 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -0700898 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700899 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700900 case 6:
901 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
902 if (ShouldCancel()) return true;
903
904 TwoFromMiddleDrive();
905 if (!WaitForDriveDone()) return true;
906 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700907 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700908 FrontMiddleShot();
909
910 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700911 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700912 SetShooterSpeed(600.0);
913
914 break;
915 case 7:
916 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
917 if (ShouldCancel()) return true;
918
919 OneFromMiddleDrive(true);
920 if (!WaitForDriveDone()) return true;
921 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700922 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700923 FrontMiddleShot();
924
925 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700926 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700927 SetShooterSpeed(600.0);
928
929 break;
930 case 8: {
931 StealAndMoveOverBy(2.95);
932 if (ShouldCancel()) return true;
933
934 MiddleDrive();
935 if (!WaitForDriveDone()) return true;
936 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700937 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700938 FrontMiddleShot();
939
940 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700941 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700942 SetShooterSpeed(600.0);
943
944 } break;
945 case 9: {
946 StealAndMoveOverBy(1.70);
947 if (ShouldCancel()) return true;
948
949 OneFromMiddleDrive(false);
950 if (!WaitForDriveDone()) return true;
951 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700952 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700953 FrontMiddleShot();
954
955 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700956 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700957 SetShooterSpeed(600.0);
958
959 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700960 default:
Alex Perrycb7da4b2019-08-28 19:35:56 -0700961 AOS_LOG(ERROR, "Invalid auto mode %d\n", params->mode());
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700962 return true;
963 }
Comran Morshed435f1112016-03-12 14:20:45 +0000964
Austin Schuh3e4a5272016-04-20 20:11:00 -0700965 DoFullShot();
966
967 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +0000968 if (!WaitForDriveDone()) return true;
969
Austin Schuhf257f3c2019-10-27 21:00:43 -0700970 AOS_LOG(INFO, "Done %f\n",
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700971 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Comran Morshed435f1112016-03-12 14:20:45 +0000972
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700973 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuh77ed5432019-07-07 20:41:36 -0700974 monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700975 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700976
Comran Morshed435f1112016-03-12 14:20:45 +0000977 while (!ShouldCancel()) {
978 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +0000979 }
Austin Schuhf257f3c2019-10-27 21:00:43 -0700980 AOS_LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +0000981
982 return true;
983}
984
Comran Morshede68e3732016-03-12 14:12:11 +0000985} // namespace actors
986} // namespace y2016