blob: a665c28345de3b53bc05a06a015189fd6ed01172 [file] [log] [blame]
Comran Morshede68e3732016-03-12 14:12:11 +00001#include "y2016/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
Austin Schuh8aec1ed2016-05-01 13:29:20 -07005#include <chrono>
Comran Morshedb134e772016-03-16 21:05:05 +00006#include <cmath>
7
John Park33858a32018-09-28 23:05:48 -07008#include "aos/logging/logging.h"
James Kuszmaul651fc3f2019-05-15 21:14:25 -07009#include "aos/util/phased_loop.h"
Comran Morshed435f1112016-03-12 14:20:45 +000010
Comran Morshed435f1112016-03-12 14:20:45 +000011#include "y2016/control_loops/drivetrain/drivetrain_base.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070012#include "y2016/control_loops/shooter/shooter_goal_generated.h"
13#include "y2016/control_loops/shooter/shooter_status_generated.h"
14#include "y2016/control_loops/superstructure/superstructure_goal_generated.h"
15#include "y2016/control_loops/superstructure/superstructure_status_generated.h"
16#include "y2016/queues/ball_detector_generated.h"
17#include "y2016/vision/vision_generated.h"
Comran Morshede68e3732016-03-12 14:12:11 +000018
19namespace y2016 {
20namespace actors {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080021using ::aos::monotonic_clock;
Alex Perrycb7da4b2019-08-28 19:35:56 -070022using ::frc971::ProfileParametersT;
23namespace superstructure = y2016::control_loops::superstructure;
24namespace shooter = y2016::control_loops::shooter;
Austin Schuhf2a50ba2016-12-24 16:16:26 -080025namespace chrono = ::std::chrono;
26namespace this_thread = ::std::this_thread;
Comran Morshed435f1112016-03-12 14:20:45 +000027
28namespace {
Alex Perrycb7da4b2019-08-28 19:35:56 -070029ProfileParametersT MakeProfileParameters(float max_velocity,
30 float max_acceleration) {
31 ProfileParametersT result;
32 result.max_velocity = max_velocity;
33 result.max_acceleration = max_acceleration;
34 return result;
35}
Comran Morshed435f1112016-03-12 14:20:45 +000036
Alex Perrycb7da4b2019-08-28 19:35:56 -070037const ProfileParametersT kSlowDrive = MakeProfileParameters(0.8, 2.5);
38const ProfileParametersT kLowBarDrive = MakeProfileParameters(1.3, 2.5);
39const ProfileParametersT kMoatDrive = MakeProfileParameters(1.2, 3.5);
40const ProfileParametersT kRealignDrive = MakeProfileParameters(2.0, 2.5);
41const ProfileParametersT kRockWallDrive = MakeProfileParameters(0.8, 2.5);
42const ProfileParametersT kFastDrive = MakeProfileParameters(3.0, 2.5);
Austin Schuh23b21802016-04-03 21:18:56 -070043
Alex Perrycb7da4b2019-08-28 19:35:56 -070044const ProfileParametersT kSlowTurn = MakeProfileParameters(0.8, 3.0);
45const ProfileParametersT kFastTurn = MakeProfileParameters(3.0, 10.0);
46const ProfileParametersT kStealTurn = MakeProfileParameters(4.0, 15.0);
47const ProfileParametersT kSwerveTurn = MakeProfileParameters(2.0, 7.0);
48const ProfileParametersT kFinishTurn = MakeProfileParameters(2.0, 5.0);
49
50const ProfileParametersT kTwoBallLowDrive = MakeProfileParameters(1.7, 3.5);
51const ProfileParametersT kTwoBallFastDrive = MakeProfileParameters(3.0, 1.5);
52const ProfileParametersT kTwoBallReturnDrive = MakeProfileParameters(3.0, 1.9);
53const ProfileParametersT kTwoBallReturnSlow = MakeProfileParameters(3.0, 2.5);
54const ProfileParametersT kTwoBallBallPickup = MakeProfileParameters(2.0, 1.75);
55const ProfileParametersT kTwoBallBallPickupAccel =
56 MakeProfileParameters(2.0, 2.5);
Austin Schuhf2a50ba2016-12-24 16:16:26 -080057
Comran Morshed435f1112016-03-12 14:20:45 +000058} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000059
Austin Schuh1bf8a212019-05-26 22:13:14 -070060AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
Philipp Schrader4bd29b12017-02-22 04:42:27 +000061 : frc971::autonomous::BaseAutonomousActor(
Austin Schuh1bf8a212019-05-26 22:13:14 -070062 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
63 vision_align_actor_factory_(
Austin Schuh28bde302019-05-26 22:24:33 -070064 actors::VisionAlignActor::MakeFactory(event_loop)),
65 vision_status_fetcher_(
66 event_loop->MakeFetcher<::y2016::vision::VisionStatus>(
Alex Perrycb7da4b2019-08-28 19:35:56 -070067 "/superstructure")),
Austin Schuh4b652c92019-05-27 13:22:27 -070068 ball_detector_fetcher_(
69 event_loop->MakeFetcher<::y2016::sensors::BallDetector>(
Alex Perrycb7da4b2019-08-28 19:35:56 -070070 "/superstructure")),
Austin Schuhae023fb2019-06-29 17:11:45 -070071 shooter_goal_sender_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070072 event_loop->MakeSender<::y2016::control_loops::shooter::Goal>(
73 "/shooter")),
Austin Schuhae023fb2019-06-29 17:11:45 -070074 shooter_status_fetcher_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070075 event_loop->MakeFetcher<::y2016::control_loops::shooter::Status>(
76 "/shooter")),
Austin Schuh9481d0d2019-06-29 21:56:17 -070077 superstructure_status_fetcher_(
Austin Schuh9481d0d2019-06-29 21:56:17 -070078 event_loop
Alex Perrycb7da4b2019-08-28 19:35:56 -070079 ->MakeFetcher<::y2016::control_loops::superstructure::Status>(
80 "/superstructure")),
81 superstructure_goal_sender_(
82 event_loop->MakeSender<::y2016::control_loops::superstructure::Goal>(
83 "/superstructure")) {}
Comran Morshed435f1112016-03-12 14:20:45 +000084
Austin Schuhe4ec49c2016-04-24 19:07:15 -070085constexpr double kDoNotTurnCare = 2.0;
86
Comran Morshedb134e772016-03-16 21:05:05 +000087void AutonomousActor::MoveSuperstructure(
88 double intake, double shoulder, double wrist,
Alex Perrycb7da4b2019-08-28 19:35:56 -070089 const ProfileParametersT intake_params,
90 const ProfileParametersT shoulder_params,
91 const ProfileParametersT wrist_params, bool traverse_up,
Austin Schuh23b21802016-04-03 21:18:56 -070092 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +000093 superstructure_goal_ = {intake, shoulder, wrist};
94
Alex Perrycb7da4b2019-08-28 19:35:56 -070095 auto builder = superstructure_goal_sender_.MakeBuilder();
Comran Morshedb134e772016-03-16 21:05:05 +000096
Alex Perrycb7da4b2019-08-28 19:35:56 -070097 superstructure::Goal::Builder superstructure_goal_builder =
98 builder.MakeBuilder<superstructure::Goal>();
Comran Morshedb134e772016-03-16 21:05:05 +000099
Alex Perrycb7da4b2019-08-28 19:35:56 -0700100 superstructure_goal_builder.add_angle_intake(intake);
101 superstructure_goal_builder.add_angle_shoulder(shoulder);
102 superstructure_goal_builder.add_angle_wrist(wrist);
Comran Morshedb134e772016-03-16 21:05:05 +0000103
Alex Perrycb7da4b2019-08-28 19:35:56 -0700104 superstructure_goal_builder.add_max_angular_velocity_intake(
105 intake_params.max_velocity);
106 superstructure_goal_builder.add_max_angular_velocity_shoulder(
107 shoulder_params.max_velocity);
108 superstructure_goal_builder.add_max_angular_velocity_wrist(
109 wrist_params.max_velocity);
Comran Morshedb134e772016-03-16 21:05:05 +0000110
Alex Perrycb7da4b2019-08-28 19:35:56 -0700111 superstructure_goal_builder.add_max_angular_acceleration_intake(
112 intake_params.max_acceleration);
113 superstructure_goal_builder.add_max_angular_acceleration_shoulder(
114 shoulder_params.max_acceleration);
115 superstructure_goal_builder.add_max_angular_acceleration_wrist(
116 wrist_params.max_acceleration);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700117
Alex Perrycb7da4b2019-08-28 19:35:56 -0700118 superstructure_goal_builder.add_voltage_top_rollers(roller_power);
119 superstructure_goal_builder.add_voltage_bottom_rollers(roller_power);
Comran Morshedb134e772016-03-16 21:05:05 +0000120
Alex Perrycb7da4b2019-08-28 19:35:56 -0700121 superstructure_goal_builder.add_traverse_unlatched(true);
122 superstructure_goal_builder.add_traverse_down(!traverse_up);
123 superstructure_goal_builder.add_voltage_climber(0.0);
124 superstructure_goal_builder.add_unfold_climber(false);
125
126 if (!builder.Send(superstructure_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700127 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
Comran Morshedb134e772016-03-16 21:05:05 +0000128 }
129}
130
Austin Schuh23b21802016-04-03 21:18:56 -0700131void AutonomousActor::OpenShooter() {
132 shooter_speed_ = 0.0;
133
Alex Perrycb7da4b2019-08-28 19:35:56 -0700134 auto builder = shooter_goal_sender_.MakeBuilder();
135 shooter::Goal::Builder shooter_goal_builder =
136 builder.MakeBuilder<shooter::Goal>();
137 shooter_goal_builder.add_angular_velocity(shooter_speed_);
138 shooter_goal_builder.add_clamp_open(true);
139 shooter_goal_builder.add_push_to_shooter(false);
140 shooter_goal_builder.add_force_lights_on(false);
141 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700142 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700143 }
144}
145
146void AutonomousActor::CloseShooter() {
147 shooter_speed_ = 0.0;
148
Alex Perrycb7da4b2019-08-28 19:35:56 -0700149 auto builder = shooter_goal_sender_.MakeBuilder();
150 shooter::Goal::Builder shooter_goal_builder =
151 builder.MakeBuilder<shooter::Goal>();
152 shooter_goal_builder.add_angular_velocity(shooter_speed_);
153 shooter_goal_builder.add_clamp_open(false);
154 shooter_goal_builder.add_push_to_shooter(false);
155 shooter_goal_builder.add_force_lights_on(false);
Austin Schuhae023fb2019-06-29 17:11:45 -0700156
Alex Perrycb7da4b2019-08-28 19:35:56 -0700157 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700158 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700159 }
160}
161
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700162void AutonomousActor::SetShooterSpeed(double speed) {
163 shooter_speed_ = speed;
164
165 // In auto, we want to have the lights on whenever possible since we have no
166 // hope of a human aligning the robot.
167 bool force_lights_on = shooter_speed_ > 1.0;
168
Alex Perrycb7da4b2019-08-28 19:35:56 -0700169 auto builder = shooter_goal_sender_.MakeBuilder();
170 shooter::Goal::Builder shooter_goal_builder =
171 builder.MakeBuilder<shooter::Goal>();
172 shooter_goal_builder.add_angular_velocity(shooter_speed_);
173 shooter_goal_builder.add_clamp_open(false);
174 shooter_goal_builder.add_push_to_shooter(false);
175 shooter_goal_builder.add_force_lights_on(force_lights_on);
Austin Schuhae023fb2019-06-29 17:11:45 -0700176
Alex Perrycb7da4b2019-08-28 19:35:56 -0700177 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700178 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700179 }
180}
181
182void AutonomousActor::Shoot() {
183 uint32_t initial_shots = 0;
184
Austin Schuhae023fb2019-06-29 17:11:45 -0700185 shooter_status_fetcher_.Fetch();
186 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700187 initial_shots = shooter_status_fetcher_->shots();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700188 }
189
190 // In auto, we want to have the lights on whenever possible since we have no
191 // hope of a human aligning the robot.
192 bool force_lights_on = shooter_speed_ > 1.0;
193
Alex Perrycb7da4b2019-08-28 19:35:56 -0700194 auto builder = shooter_goal_sender_.MakeBuilder();
195 shooter::Goal::Builder shooter_goal_builder =
196 builder.MakeBuilder<shooter::Goal>();
197 shooter_goal_builder.add_angular_velocity(shooter_speed_);
198 shooter_goal_builder.add_clamp_open(false);
199 shooter_goal_builder.add_push_to_shooter(true);
200 shooter_goal_builder.add_force_lights_on(force_lights_on);
Austin Schuhae023fb2019-06-29 17:11:45 -0700201
Alex Perrycb7da4b2019-08-28 19:35:56 -0700202 if (!builder.Send(shooter_goal_builder.Finish())) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700203 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700204 }
205
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700206 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700207 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700208 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700209 while (true) {
210 if (ShouldCancel()) return;
211
212 // Wait for the shot count to change so we know when the shot is complete.
Austin Schuhae023fb2019-06-29 17:11:45 -0700213 shooter_status_fetcher_.Fetch();
214 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700215 if (initial_shots < shooter_status_fetcher_->shots()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700216 return;
217 }
218 }
219 phased_loop.SleepUntilNext();
220 }
221}
222
223void AutonomousActor::WaitForShooterSpeed() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700224 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700225 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700226 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700227 while (true) {
228 if (ShouldCancel()) return;
229
Austin Schuhae023fb2019-06-29 17:11:45 -0700230 shooter_status_fetcher_.Fetch();
231 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700232 if (shooter_status_fetcher_->left()->ready() &&
233 shooter_status_fetcher_->right()->ready()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700234 return;
235 }
236 }
237 phased_loop.SleepUntilNext();
238 }
239}
240
241void AutonomousActor::AlignWithVisionGoal() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700242 vision_align_action::VisionAlignActionParamsT params;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700243 vision_action_ = vision_align_actor_factory_.Make(params);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700244 vision_action_->Start();
245}
246
Austin Schuh23b21802016-04-03 21:18:56 -0700247void AutonomousActor::WaitForAlignedWithVision(
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800248 chrono::nanoseconds align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700249 bool vision_valid = false;
250 double last_angle = 0.0;
251 int ready_to_fire = 0;
252
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700253 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700254 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700255 ::std::chrono::milliseconds(5) / 2);
Austin Schuh77ed5432019-07-07 20:41:36 -0700256 const monotonic_clock::time_point end_time = monotonic_now() + align_duration;
257 while (end_time > monotonic_now()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700258 if (ShouldCancel()) break;
259
Austin Schuh28bde302019-05-26 22:24:33 -0700260 vision_status_fetcher_.Fetch();
261 if (vision_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700262 vision_valid = (vision_status_fetcher_->left_image_valid() &&
263 vision_status_fetcher_->right_image_valid());
264 last_angle = vision_status_fetcher_->horizontal_angle();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700265 }
266
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700267 drivetrain_status_fetcher_.Fetch();
268 drivetrain_goal_fetcher_.Fetch();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700269
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700270 if (drivetrain_status_fetcher_.get() && drivetrain_goal_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700271 const double left_goal = drivetrain_goal_fetcher_->left_goal();
272 const double right_goal = drivetrain_goal_fetcher_->right_goal();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700273 const double left_current =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700274 drivetrain_status_fetcher_->estimated_left_position();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700275 const double right_current =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700276 drivetrain_status_fetcher_->estimated_right_position();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700277 const double left_velocity =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700278 drivetrain_status_fetcher_->estimated_left_velocity();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700279 const double right_velocity =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700280 drivetrain_status_fetcher_->estimated_right_velocity();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700281
282 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
283 ::std::abs((left_goal - right_goal) -
284 (left_current - right_current)) /
285 dt_config_.robot_radius / 2.0 <
286 0.02 &&
287 ::std::abs(left_velocity - right_velocity) < 0.01) {
288 ++ready_to_fire;
289 } else {
290 ready_to_fire = 0;
291 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700292 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700293 break;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700294 AOS_LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700295 }
296 }
297 phased_loop.SleepUntilNext();
298 }
299
300 vision_action_->Cancel();
301 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuhf257f3c2019-10-27 21:00:43 -0700302 AOS_LOG(INFO, "Done waiting for vision\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700303}
304
305bool AutonomousActor::IntakeDone() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700306 superstructure_status_fetcher_.Fetch();
Austin Schuh23b21802016-04-03 21:18:56 -0700307
308 constexpr double kProfileError = 1e-5;
309 constexpr double kEpsilon = 0.15;
310
Alex Perrycb7da4b2019-08-28 19:35:56 -0700311 if (superstructure_status_fetcher_->state() < 12 ||
312 superstructure_status_fetcher_->state() == 16) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700313 AOS_LOG(ERROR, "Superstructure no longer running, aborting action\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700314 return true;
315 }
316
Alex Perrycb7da4b2019-08-28 19:35:56 -0700317 if (::std::abs(superstructure_status_fetcher_->intake()->goal_angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700318 superstructure_goal_.intake) < kProfileError &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700319 ::std::abs(
320 superstructure_status_fetcher_->intake()->goal_angular_velocity()) <
321 kProfileError) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700322 AOS_LOG(DEBUG, "Profile done.\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700323 if (::std::abs(superstructure_status_fetcher_->intake()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700324 superstructure_goal_.intake) < kEpsilon &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700325 ::std::abs(
326 superstructure_status_fetcher_->intake()->angular_velocity()) <
327 kEpsilon) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700328 AOS_LOG(INFO, "Near goal, done.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700329 return true;
330 }
331 }
332 return false;
333}
334
335bool AutonomousActor::SuperstructureProfileDone() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700336 if (superstructure_status_fetcher_->state() < 12 ||
337 superstructure_status_fetcher_->state() == 16) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700338 AOS_LOG(ERROR, "Superstructure no longer running, aborting action\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700339 return true;
340 }
341
Austin Schuh9481d0d2019-06-29 21:56:17 -0700342 constexpr double kProfileError = 1e-5;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700343 return ::std::abs(superstructure_status_fetcher_->intake()->goal_angle() -
344 superstructure_goal_.intake) < kProfileError &&
345 ::std::abs(superstructure_status_fetcher_->shoulder()->goal_angle() -
346 superstructure_goal_.shoulder) < kProfileError &&
347 ::std::abs(superstructure_status_fetcher_->wrist()->goal_angle() -
348 superstructure_goal_.wrist) < kProfileError &&
349 ::std::abs(superstructure_status_fetcher_->intake()
350 ->goal_angular_velocity()) < kProfileError &&
351 ::std::abs(superstructure_status_fetcher_->shoulder()
352 ->goal_angular_velocity()) < kProfileError &&
Austin Schuh9481d0d2019-06-29 21:56:17 -0700353 ::std::abs(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700354 superstructure_status_fetcher_->wrist()->goal_angular_velocity()) <
355 kProfileError;
Austin Schuh9481d0d2019-06-29 21:56:17 -0700356}
357
358bool AutonomousActor::SuperstructureDone() {
359 superstructure_status_fetcher_.Fetch();
360
361 constexpr double kEpsilon = 0.03;
Austin Schuh23b21802016-04-03 21:18:56 -0700362 if (SuperstructureProfileDone()) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700363 AOS_LOG(DEBUG, "Profile done.\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700364 if (::std::abs(superstructure_status_fetcher_->intake()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700365 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700366 ::std::abs(superstructure_status_fetcher_->shoulder()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700367 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700368 ::std::abs(superstructure_status_fetcher_->wrist()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700369 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700370 ::std::abs(
371 superstructure_status_fetcher_->intake()->angular_velocity()) <
372 (kEpsilon + 0.1) &&
373 ::std::abs(
374 superstructure_status_fetcher_->shoulder()->angular_velocity()) <
375 (kEpsilon + 0.10) &&
376 ::std::abs(
377 superstructure_status_fetcher_->wrist()->angular_velocity()) <
378 (kEpsilon + 0.05)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700379 AOS_LOG(INFO, "Near goal, done.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700380 return true;
381 }
382 }
383 return false;
384}
385
386void AutonomousActor::WaitForIntake() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700387 WaitUntil(::std::bind(&AutonomousActor::IntakeDone, this));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700388}
389
Comran Morshedb134e772016-03-16 21:05:05 +0000390void AutonomousActor::WaitForSuperstructure() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700391 WaitUntil(::std::bind(&AutonomousActor::SuperstructureDone, this));
Austin Schuh23b21802016-04-03 21:18:56 -0700392}
Comran Morshedb134e772016-03-16 21:05:05 +0000393
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700394void AutonomousActor::WaitForSuperstructureProfile() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700395 WaitUntil([this]() {
396 superstructure_status_fetcher_.Fetch();
397 return SuperstructureProfileDone();
398 });
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700399}
400
Austin Schuh23b21802016-04-03 21:18:56 -0700401void AutonomousActor::WaitForSuperstructureLow() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700402 WaitUntil([this]() {
403 superstructure_status_fetcher_.Fetch();
Comran Morshedb134e772016-03-16 21:05:05 +0000404
Austin Schuh9481d0d2019-06-29 21:56:17 -0700405 return SuperstructureProfileDone() ||
Alex Perrycb7da4b2019-08-28 19:35:56 -0700406 superstructure_status_fetcher_->shoulder()->angle() < 0.1;
Austin Schuh9481d0d2019-06-29 21:56:17 -0700407 });
Comran Morshedb134e772016-03-16 21:05:05 +0000408}
Austin Schuh9481d0d2019-06-29 21:56:17 -0700409
Austin Schuh23b21802016-04-03 21:18:56 -0700410void AutonomousActor::BackLongShotLowBarTwoBall() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700411 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700412 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55,
413 MakeProfileParameters(7.0, 40.0),
414 MakeProfileParameters(4.0, 6.0),
415 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700416}
417
418void AutonomousActor::BackLongShotTwoBall() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700419 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700420 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55,
421 MakeProfileParameters(7.0, 40.0),
422 MakeProfileParameters(4.0, 6.0),
423 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700424}
425
426void AutonomousActor::BackLongShotTwoBallFinish() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700427 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700428 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625 + 0.03,
429 MakeProfileParameters(7.0, 40.0),
430 MakeProfileParameters(4.0, 6.0),
431 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700432}
433
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700434void AutonomousActor::BackLongShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700435 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700436 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62,
437 MakeProfileParameters(7.0, 40.0),
438 MakeProfileParameters(4.0, 6.0),
439 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700440}
441
442void AutonomousActor::BackMiddleShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700443 AOS_LOG(INFO, "Expanding for back middle shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700444 MoveSuperstructure(-0.05, M_PI / 2.0 - 0.2, -0.665,
445 MakeProfileParameters(7.0, 40.0),
446 MakeProfileParameters(4.0, 10.0),
447 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700448}
449
Austin Schuh3e4a5272016-04-20 20:11:00 -0700450void AutonomousActor::FrontLongShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700451 AOS_LOG(INFO, "Expanding for front long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700452 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02,
453 MakeProfileParameters(7.0, 40.0),
454 MakeProfileParameters(4.0, 6.0),
455 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700456}
457
458void AutonomousActor::FrontMiddleShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700459 AOS_LOG(INFO, "Expanding for front middle shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700460 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44,
461 MakeProfileParameters(7.0, 40.0),
462 MakeProfileParameters(4.0, 10.0),
463 MakeProfileParameters(10.0, 25.0), true, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700464}
465
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700466void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700467 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0,
468 MakeProfileParameters(7.0, 40.0),
469 MakeProfileParameters(4.0, 10.0),
470 MakeProfileParameters(10.0, 25.0), !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700471}
472
Austin Schuh3e4a5272016-04-20 20:11:00 -0700473void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700474 if (ShouldCancel()) return;
475 // Make sure that the base is aligned with the base.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700476 AOS_LOG(INFO, "Waiting for the superstructure\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700477 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700478
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800479 this_thread::sleep_for(chrono::milliseconds(500));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700480
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700481 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700482 AOS_LOG(INFO, "Triggering the vision actor\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700483 AlignWithVisionGoal();
484
485 // Wait for the drive base to be aligned with the target and make sure that
486 // the shooter is up to speed.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700487 AOS_LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800488 WaitForAlignedWithVision(chrono::milliseconds(2000));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700489 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700490 AOS_LOG(INFO, "Waiting for shooter to be up to speed\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700491 WaitForShooterSpeed();
492 if (ShouldCancel()) return;
493
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800494 this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhf257f3c2019-10-27 21:00:43 -0700495 AOS_LOG(INFO, "Shoot!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700496 Shoot();
497
498 // Turn off the shooter and fold up the superstructure.
499 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700500 AOS_LOG(INFO, "Stopping shooter\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700501 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700502 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700503 TuckArm(false, false);
504
505 // Wait for everything to be folded up.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700506 AOS_LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700507 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700508}
509
510void AutonomousActor::LowBarDrive() {
511 TuckArm(false, true);
512 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
513
514 if (!WaitForDriveNear(5.3, 0.0)) return;
515 TuckArm(true, true);
516
517 if (!WaitForDriveNear(5.0, 0.0)) return;
518
519 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
520
521 if (!WaitForDriveNear(3.0, 0.0)) return;
522
523 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
524
525 if (!WaitForDriveNear(1.0, 0.0)) return;
526
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700527 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700528}
529
Austin Schuh3e4a5272016-04-20 20:11:00 -0700530void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
531 double below, double above) {
532 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
533 if (!WaitForBelowAngle(below)) return;
534 if (!WaitForAboveAngle(above)) return;
535 // Ok, we are good now. Compensate by moving the goal by the error.
536 // Should be here at 2.7
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700537 drivetrain_status_fetcher_.Fetch();
538 if (drivetrain_status_fetcher_.get()) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700539 const double left_error =
540 (initial_drivetrain_.left -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700541 drivetrain_status_fetcher_->estimated_left_position());
Austin Schuh3e4a5272016-04-20 20:11:00 -0700542 const double right_error =
543 (initial_drivetrain_.right -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700544 drivetrain_status_fetcher_->estimated_right_position());
Austin Schuh3e4a5272016-04-20 20:11:00 -0700545 const double distance_to_go = (left_error + right_error) / 2.0;
546 const double distance_compensation =
547 goal_distance - tip_distance - distance_to_go;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700548 AOS_LOG(INFO, "Going %f further at the bump\n", distance_compensation);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700549 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
550 }
551}
552
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700553void AutonomousActor::MiddleDrive() {
554 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700555 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700556 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700557}
558
559void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700560 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700561 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700562 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700563
564 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700565 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700566}
567
568void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700569 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700570 constexpr double kDriveDistance = 5.10;
571 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
572
573 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
574 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700575
576 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700577 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700578}
Comran Morshedb134e772016-03-16 21:05:05 +0000579
Austin Schuh23b21802016-04-03 21:18:56 -0700580void AutonomousActor::CloseIfBall() {
Austin Schuh4b652c92019-05-27 13:22:27 -0700581 ball_detector_fetcher_.Fetch();
582 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700583 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh23b21802016-04-03 21:18:56 -0700584 if (ball_detected) {
585 CloseShooter();
586 }
587 }
588}
589
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700590void AutonomousActor::WaitForBallOrDriveDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700591 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -0700592 event_loop()->monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700593 ::std::chrono::milliseconds(5) / 2);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700594 while (true) {
595 if (ShouldCancel()) {
596 return;
597 }
598 phased_loop.SleepUntilNext();
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700599 drivetrain_status_fetcher_.Fetch();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700600 if (IsDriveDone()) {
601 return;
602 }
603
Austin Schuh4b652c92019-05-27 13:22:27 -0700604 ball_detector_fetcher_.Fetch();
605 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700606 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700607 if (ball_detected) {
608 return;
609 }
610 }
611 }
612}
613
Austin Schuh3e4a5272016-04-20 20:11:00 -0700614void AutonomousActor::TwoBallAuto() {
Austin Schuh77ed5432019-07-07 20:41:36 -0700615 const monotonic_clock::time_point start_time = monotonic_now();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700616 OpenShooter();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700617 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
618 MakeProfileParameters(4.0, 10.0),
619 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700620 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700621 AOS_LOG(INFO, "Waiting for the intake to come down.\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700622
623 WaitForIntake();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700624 AOS_LOG(INFO, "Intake done at %f seconds, starting to drive\n",
625 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700626 if (ShouldCancel()) return;
627 const double kDriveDistance = 5.05;
628 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
629
630 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700631 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700632
Austin Schuh295c2d92016-05-01 12:28:04 -0700633 // Check if the ball is there.
634 bool first_ball_there = true;
Austin Schuh4b652c92019-05-27 13:22:27 -0700635 ball_detector_fetcher_.Fetch();
636 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700637 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh295c2d92016-05-01 12:28:04 -0700638 first_ball_there = ball_detected;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700639 AOS_LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
640 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh295c2d92016-05-01 12:28:04 -0700641 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700642 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 40.0),
643 MakeProfileParameters(4.0, 10.0),
644 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700645 AOS_LOG(INFO,
646 "Shutting off rollers at %f seconds, starting to straighten out\n",
647 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700648 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700649 MoveSuperstructure(-0.05, -0.010, 0.0, MakeProfileParameters(8.0, 40.0),
650 MakeProfileParameters(4.0, 10.0),
651 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700652 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700653 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700654
655 // We are now under the low bar. Start lifting.
656 BackLongShotLowBarTwoBall();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700657 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700658 SetShooterSpeed(640.0);
659 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
660
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700661 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
662 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700663 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
664 BackLongShotTwoBall();
665
666 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700667 AOS_LOG(INFO, "First shot done driving at %f seconds\n",
668 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700669
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700670 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700671
672 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700673 AlignWithVisionGoal();
674
675 WaitForShooterSpeed();
676 if (ShouldCancel()) return;
677
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800678 constexpr chrono::milliseconds kVisionExtra{0};
679 WaitForAlignedWithVision(chrono::milliseconds(500) + kVisionExtra);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700680 BackLongShotTwoBallFinish();
681 WaitForSuperstructureProfile();
682 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700683 AOS_LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700684 if (first_ball_there) {
685 Shoot();
686 } else {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700687 AOS_LOG(INFO, "Nah, not shooting\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700688 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700689
Austin Schuhf257f3c2019-10-27 21:00:43 -0700690 AOS_LOG(INFO, "First shot at %f seconds\n",
691 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700692 if (ShouldCancel()) return;
693
694 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700695 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700696 TuckArm(true, true);
697
698 // Undo vision move.
699 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
700 if (!WaitForDriveDone()) return;
701
702 constexpr double kBackDrive = 3.09 - 0.4;
703 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700704 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700705 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700706 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
707 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700708
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700709 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700710 AOS_LOG(INFO, "At Low Bar %f\n",
711 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700712
713 OpenShooter();
714 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700715 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
716 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700717 constexpr double kBallSmallWallTurn = -0.11;
718 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
719
Alex Perrycb7da4b2019-08-28 19:35:56 -0700720 MoveSuperstructure(0.03, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
721 MakeProfileParameters(4.0, 10.0),
722 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700723
724 if (!WaitForDriveProfileDone()) return;
725
Alex Perrycb7da4b2019-08-28 19:35:56 -0700726 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
727 MakeProfileParameters(4.0, 10.0),
728 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700729
Austin Schuhf257f3c2019-10-27 21:00:43 -0700730 AOS_LOG(INFO, "Done backing up %f\n",
731 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700732
733 constexpr double kDriveBackDistance = 5.15 - 0.4;
734 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
735 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700736 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700737
738 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700739 AOS_LOG(INFO, "Straightening up at %f\n",
740 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700741
742 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700743 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700744
Austin Schuh4b652c92019-05-27 13:22:27 -0700745 ball_detector_fetcher_.Fetch();
746 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700747 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700748 if (!ball_detected) {
749 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700750 AOS_LOG(INFO, "Aborting, no ball %f\n",
751 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700752 return;
753 }
754 }
755 CloseShooter();
756
757 BackLongShotLowBarTwoBall();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700758 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700759 SetShooterSpeed(640.0);
760 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
761
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700762 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700763 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
764 BackLongShotTwoBall();
765
766 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700767 AOS_LOG(INFO, "Second shot done driving at %f seconds\n",
768 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700769 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700770 AlignWithVisionGoal();
771 if (ShouldCancel()) return;
772
773 WaitForShooterSpeed();
774 if (ShouldCancel()) return;
775
776 // 2.2 with 0.4 of vision.
777 // 1.8 without any vision.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700778 AOS_LOG(INFO, "Going to vision align at %f\n",
779 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800780 WaitForAlignedWithVision(
781 (start_time + chrono::milliseconds(13500) + kVisionExtra * 2) -
Austin Schuh77ed5432019-07-07 20:41:36 -0700782 monotonic_now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700783 BackLongShotTwoBallFinish();
784 WaitForSuperstructureProfile();
785 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700786 AOS_LOG(INFO, "Shoot at %f\n",
787 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700788 Shoot();
789
Austin Schuhf257f3c2019-10-27 21:00:43 -0700790 AOS_LOG(INFO, "Second shot at %f seconds\n",
791 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700792 if (ShouldCancel()) return;
793
794 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700795 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700796 TuckArm(true, false);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700797 AOS_LOG(INFO, "Shot %f\n",
798 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700799
800 WaitForSuperstructureLow();
801
Austin Schuhf257f3c2019-10-27 21:00:43 -0700802 AOS_LOG(INFO, "Done %f\n",
803 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700804}
805
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700806void AutonomousActor::StealAndMoveOverBy(double distance) {
807 OpenShooter();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700808 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
809 MakeProfileParameters(4.0, 10.0),
810 MakeProfileParameters(10.0, 25.0), true, 12.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700811 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700812 AOS_LOG(INFO, "Waiting for the intake to come down.\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700813
814 WaitForIntake();
815 if (ShouldCancel()) return;
816 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
817 WaitForBallOrDriveDone();
818 if (ShouldCancel()) return;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700819 MoveSuperstructure(1.0, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
820 MakeProfileParameters(4.0, 10.0),
821 MakeProfileParameters(10.0, 25.0), true, 12.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700822
823 if (!WaitForDriveDone()) return;
824 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
825 if (!WaitForDriveDone()) return;
826}
827
Philipp Schrader4bd29b12017-02-22 04:42:27 +0000828bool AutonomousActor::RunAction(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700829 const ::frc971::autonomous::AutonomousActionParams *params) {
Austin Schuh77ed5432019-07-07 20:41:36 -0700830 monotonic_clock::time_point start_time = monotonic_now();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700831 AOS_LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n",
Alex Perrycb7da4b2019-08-28 19:35:56 -0700832 params->mode());
Comran Morshede68e3732016-03-12 14:12:11 +0000833
Comran Morshed435f1112016-03-12 14:20:45 +0000834 InitializeEncoders();
835 ResetDrivetrain();
836
Alex Perrycb7da4b2019-08-28 19:35:56 -0700837 switch (params->mode()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700838 case 0:
839 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700840 if (!WaitForDriveDone()) return true;
841 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700842 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700843 FrontLongShot();
844
845 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700846 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700847 SetShooterSpeed(640.0);
848
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700849 break;
850 case 1:
851 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700852 if (!WaitForDriveDone()) return true;
853 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700854 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700855 FrontMiddleShot();
856
857 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700858 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700859 SetShooterSpeed(600.0);
860
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700861 break;
862 case 2:
863 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700864 if (!WaitForDriveDone()) return true;
865 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700866 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700867 FrontMiddleShot();
868
869 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700870 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700871 SetShooterSpeed(600.0);
872
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700873 break;
874 case 3:
875 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700876 if (!WaitForDriveDone()) return true;
877 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700878 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700879 FrontMiddleShot();
880
881 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700882 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700883 SetShooterSpeed(600.0);
884
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700885 break;
886 case 4:
887 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700888 if (!WaitForDriveDone()) return true;
889 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700890 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700891 FrontMiddleShot();
892
893 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700894 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700895 SetShooterSpeed(600.0);
896
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700897 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700898 case 5:
Campbell Crowley9ed61a52016-11-05 17:13:07 -0700899 case 15:
Austin Schuh3e4a5272016-04-20 20:11:00 -0700900 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -0700901 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700902 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700903 case 6:
904 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
905 if (ShouldCancel()) return true;
906
907 TwoFromMiddleDrive();
908 if (!WaitForDriveDone()) return true;
909 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700910 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700911 FrontMiddleShot();
912
913 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700914 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700915 SetShooterSpeed(600.0);
916
917 break;
918 case 7:
919 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
920 if (ShouldCancel()) return true;
921
922 OneFromMiddleDrive(true);
923 if (!WaitForDriveDone()) return true;
924 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700925 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700926 FrontMiddleShot();
927
928 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700929 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700930 SetShooterSpeed(600.0);
931
932 break;
933 case 8: {
934 StealAndMoveOverBy(2.95);
935 if (ShouldCancel()) return true;
936
937 MiddleDrive();
938 if (!WaitForDriveDone()) return true;
939 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700940 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700941 FrontMiddleShot();
942
943 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700944 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700945 SetShooterSpeed(600.0);
946
947 } break;
948 case 9: {
949 StealAndMoveOverBy(1.70);
950 if (ShouldCancel()) return true;
951
952 OneFromMiddleDrive(false);
953 if (!WaitForDriveDone()) return true;
954 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700955 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700956 FrontMiddleShot();
957
958 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700959 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700960 SetShooterSpeed(600.0);
961
962 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700963 default:
Alex Perrycb7da4b2019-08-28 19:35:56 -0700964 AOS_LOG(ERROR, "Invalid auto mode %d\n", params->mode());
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700965 return true;
966 }
Comran Morshed435f1112016-03-12 14:20:45 +0000967
Austin Schuh3e4a5272016-04-20 20:11:00 -0700968 DoFullShot();
969
970 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +0000971 if (!WaitForDriveDone()) return true;
972
Austin Schuhf257f3c2019-10-27 21:00:43 -0700973 AOS_LOG(INFO, "Done %f\n",
Austin Schuh77ed5432019-07-07 20:41:36 -0700974 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Comran Morshed435f1112016-03-12 14:20:45 +0000975
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700976 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuh77ed5432019-07-07 20:41:36 -0700977 monotonic_now(),
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700978 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700979
Comran Morshed435f1112016-03-12 14:20:45 +0000980 while (!ShouldCancel()) {
981 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +0000982 }
Austin Schuhf257f3c2019-10-27 21:00:43 -0700983 AOS_LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +0000984
985 return true;
986}
987
Comran Morshede68e3732016-03-12 14:12:11 +0000988} // namespace actors
989} // namespace y2016