blob: ffba99bd1023da7e95fd036bb81d500f2f10eb5b [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
milind1f1dca32021-07-03 13:50:07 -0700123 if (builder.Send(superstructure_goal_builder.Finish()) !=
124 aos::RawSender::Error::kOk) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700125 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
Comran Morshedb134e772016-03-16 21:05:05 +0000126 }
127}
128
Austin Schuh23b21802016-04-03 21:18:56 -0700129void AutonomousActor::OpenShooter() {
130 shooter_speed_ = 0.0;
131
Alex Perrycb7da4b2019-08-28 19:35:56 -0700132 auto builder = shooter_goal_sender_.MakeBuilder();
133 shooter::Goal::Builder shooter_goal_builder =
134 builder.MakeBuilder<shooter::Goal>();
135 shooter_goal_builder.add_angular_velocity(shooter_speed_);
136 shooter_goal_builder.add_clamp_open(true);
137 shooter_goal_builder.add_push_to_shooter(false);
138 shooter_goal_builder.add_force_lights_on(false);
milind1f1dca32021-07-03 13:50:07 -0700139 if (builder.Send(shooter_goal_builder.Finish()) !=
140 aos::RawSender::Error::kOk) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700141 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700142 }
143}
144
145void AutonomousActor::CloseShooter() {
146 shooter_speed_ = 0.0;
147
Alex Perrycb7da4b2019-08-28 19:35:56 -0700148 auto builder = shooter_goal_sender_.MakeBuilder();
149 shooter::Goal::Builder shooter_goal_builder =
150 builder.MakeBuilder<shooter::Goal>();
151 shooter_goal_builder.add_angular_velocity(shooter_speed_);
152 shooter_goal_builder.add_clamp_open(false);
153 shooter_goal_builder.add_push_to_shooter(false);
154 shooter_goal_builder.add_force_lights_on(false);
milind1f1dca32021-07-03 13:50:07 -0700155 if (builder.Send(shooter_goal_builder.Finish()) !=
156 aos::RawSender::Error::kOk) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700157 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700158 }
159}
160
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700161void AutonomousActor::SetShooterSpeed(double speed) {
162 shooter_speed_ = speed;
163
164 // In auto, we want to have the lights on whenever possible since we have no
165 // hope of a human aligning the robot.
166 bool force_lights_on = shooter_speed_ > 1.0;
167
Alex Perrycb7da4b2019-08-28 19:35:56 -0700168 auto builder = shooter_goal_sender_.MakeBuilder();
169 shooter::Goal::Builder shooter_goal_builder =
170 builder.MakeBuilder<shooter::Goal>();
171 shooter_goal_builder.add_angular_velocity(shooter_speed_);
172 shooter_goal_builder.add_clamp_open(false);
173 shooter_goal_builder.add_push_to_shooter(false);
174 shooter_goal_builder.add_force_lights_on(force_lights_on);
Austin Schuhae023fb2019-06-29 17:11:45 -0700175
milind1f1dca32021-07-03 13:50:07 -0700176 if (builder.Send(shooter_goal_builder.Finish()) !=
177 aos::RawSender::Error::kOk) {
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
milind1f1dca32021-07-03 13:50:07 -0700202 if (builder.Send(shooter_goal_builder.Finish()) !=
203 aos::RawSender::Error::kOk) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700204 AOS_LOG(ERROR, "Sending shooter goal failed.\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700205 }
206
Yash Chainania6fe97b2021-12-15 21:01:11 -0800207 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
Austin Schuhd32b3622019-06-23 18:49:06 -0700208 event_loop()->monotonic_now(),
Yash Chainania6fe97b2021-12-15 21:01:11 -0800209 ActorBase::kLoopOffset);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700210 while (true) {
211 if (ShouldCancel()) return;
212
213 // Wait for the shot count to change so we know when the shot is complete.
Austin Schuhae023fb2019-06-29 17:11:45 -0700214 shooter_status_fetcher_.Fetch();
215 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700216 if (initial_shots < shooter_status_fetcher_->shots()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700217 return;
218 }
219 }
220 phased_loop.SleepUntilNext();
221 }
222}
223
224void AutonomousActor::WaitForShooterSpeed() {
Yash Chainania6fe97b2021-12-15 21:01:11 -0800225 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
Austin Schuhd32b3622019-06-23 18:49:06 -0700226 event_loop()->monotonic_now(),
Yash Chainania6fe97b2021-12-15 21:01:11 -0800227 ActorBase::kLoopOffset);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700228 while (true) {
229 if (ShouldCancel()) return;
230
Austin Schuhae023fb2019-06-29 17:11:45 -0700231 shooter_status_fetcher_.Fetch();
232 if (shooter_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700233 if (shooter_status_fetcher_->left()->ready() &&
234 shooter_status_fetcher_->right()->ready()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700235 return;
236 }
237 }
238 phased_loop.SleepUntilNext();
239 }
240}
241
242void AutonomousActor::AlignWithVisionGoal() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700243 vision_align_action::VisionAlignActionParamsT params;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700244 vision_action_ = vision_align_actor_factory_.Make(params);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700245 vision_action_->Start();
246}
247
Austin Schuh23b21802016-04-03 21:18:56 -0700248void AutonomousActor::WaitForAlignedWithVision(
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800249 chrono::nanoseconds align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700250 bool vision_valid = false;
251 double last_angle = 0.0;
252 int ready_to_fire = 0;
253
Yash Chainania6fe97b2021-12-15 21:01:11 -0800254 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
Austin Schuhd32b3622019-06-23 18:49:06 -0700255 event_loop()->monotonic_now(),
Yash Chainania6fe97b2021-12-15 21:01:11 -0800256 ActorBase::kLoopOffset);
Austin Schuh77ed5432019-07-07 20:41:36 -0700257 const monotonic_clock::time_point end_time = monotonic_now() + align_duration;
258 while (end_time > monotonic_now()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700259 if (ShouldCancel()) break;
260
Austin Schuh28bde302019-05-26 22:24:33 -0700261 vision_status_fetcher_.Fetch();
262 if (vision_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700263 vision_valid = (vision_status_fetcher_->left_image_valid() &&
264 vision_status_fetcher_->right_image_valid());
265 last_angle = vision_status_fetcher_->horizontal_angle();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700266 }
267
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700268 drivetrain_status_fetcher_.Fetch();
269 drivetrain_goal_fetcher_.Fetch();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700270
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700271 if (drivetrain_status_fetcher_.get() && drivetrain_goal_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700272 const double left_goal = drivetrain_goal_fetcher_->left_goal();
273 const double right_goal = drivetrain_goal_fetcher_->right_goal();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700274 const double left_current =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700275 drivetrain_status_fetcher_->estimated_left_position();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700276 const double right_current =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700277 drivetrain_status_fetcher_->estimated_right_position();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700278 const double left_velocity =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700279 drivetrain_status_fetcher_->estimated_left_velocity();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700280 const double right_velocity =
Alex Perrycb7da4b2019-08-28 19:35:56 -0700281 drivetrain_status_fetcher_->estimated_right_velocity();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700282
283 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
284 ::std::abs((left_goal - right_goal) -
285 (left_current - right_current)) /
286 dt_config_.robot_radius / 2.0 <
287 0.02 &&
288 ::std::abs(left_velocity - right_velocity) < 0.01) {
289 ++ready_to_fire;
290 } else {
291 ready_to_fire = 0;
292 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700293 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700294 break;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700295 AOS_LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700296 }
297 }
298 phased_loop.SleepUntilNext();
299 }
300
301 vision_action_->Cancel();
302 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuhf257f3c2019-10-27 21:00:43 -0700303 AOS_LOG(INFO, "Done waiting for vision\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700304}
305
306bool AutonomousActor::IntakeDone() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700307 superstructure_status_fetcher_.Fetch();
Austin Schuh23b21802016-04-03 21:18:56 -0700308
309 constexpr double kProfileError = 1e-5;
310 constexpr double kEpsilon = 0.15;
311
Alex Perrycb7da4b2019-08-28 19:35:56 -0700312 if (superstructure_status_fetcher_->state() < 12 ||
313 superstructure_status_fetcher_->state() == 16) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700314 AOS_LOG(ERROR, "Superstructure no longer running, aborting action\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700315 return true;
316 }
317
Alex Perrycb7da4b2019-08-28 19:35:56 -0700318 if (::std::abs(superstructure_status_fetcher_->intake()->goal_angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700319 superstructure_goal_.intake) < kProfileError &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700320 ::std::abs(
321 superstructure_status_fetcher_->intake()->goal_angular_velocity()) <
322 kProfileError) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700323 AOS_LOG(DEBUG, "Profile done.\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700324 if (::std::abs(superstructure_status_fetcher_->intake()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700325 superstructure_goal_.intake) < kEpsilon &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700326 ::std::abs(
327 superstructure_status_fetcher_->intake()->angular_velocity()) <
328 kEpsilon) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700329 AOS_LOG(INFO, "Near goal, done.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700330 return true;
331 }
332 }
333 return false;
334}
335
336bool AutonomousActor::SuperstructureProfileDone() {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700337 if (superstructure_status_fetcher_->state() < 12 ||
338 superstructure_status_fetcher_->state() == 16) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700339 AOS_LOG(ERROR, "Superstructure no longer running, aborting action\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700340 return true;
341 }
342
Austin Schuh9481d0d2019-06-29 21:56:17 -0700343 constexpr double kProfileError = 1e-5;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700344 return ::std::abs(superstructure_status_fetcher_->intake()->goal_angle() -
345 superstructure_goal_.intake) < kProfileError &&
346 ::std::abs(superstructure_status_fetcher_->shoulder()->goal_angle() -
347 superstructure_goal_.shoulder) < kProfileError &&
348 ::std::abs(superstructure_status_fetcher_->wrist()->goal_angle() -
349 superstructure_goal_.wrist) < kProfileError &&
350 ::std::abs(superstructure_status_fetcher_->intake()
351 ->goal_angular_velocity()) < kProfileError &&
352 ::std::abs(superstructure_status_fetcher_->shoulder()
353 ->goal_angular_velocity()) < kProfileError &&
Austin Schuh9481d0d2019-06-29 21:56:17 -0700354 ::std::abs(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700355 superstructure_status_fetcher_->wrist()->goal_angular_velocity()) <
356 kProfileError;
Austin Schuh9481d0d2019-06-29 21:56:17 -0700357}
358
359bool AutonomousActor::SuperstructureDone() {
360 superstructure_status_fetcher_.Fetch();
361
362 constexpr double kEpsilon = 0.03;
Austin Schuh23b21802016-04-03 21:18:56 -0700363 if (SuperstructureProfileDone()) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700364 AOS_LOG(DEBUG, "Profile done.\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700365 if (::std::abs(superstructure_status_fetcher_->intake()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700366 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700367 ::std::abs(superstructure_status_fetcher_->shoulder()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700368 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700369 ::std::abs(superstructure_status_fetcher_->wrist()->angle() -
Austin Schuh23b21802016-04-03 21:18:56 -0700370 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
Alex Perrycb7da4b2019-08-28 19:35:56 -0700371 ::std::abs(
372 superstructure_status_fetcher_->intake()->angular_velocity()) <
373 (kEpsilon + 0.1) &&
374 ::std::abs(
375 superstructure_status_fetcher_->shoulder()->angular_velocity()) <
376 (kEpsilon + 0.10) &&
377 ::std::abs(
378 superstructure_status_fetcher_->wrist()->angular_velocity()) <
379 (kEpsilon + 0.05)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700380 AOS_LOG(INFO, "Near goal, done.\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700381 return true;
382 }
383 }
384 return false;
385}
386
387void AutonomousActor::WaitForIntake() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700388 WaitUntil(::std::bind(&AutonomousActor::IntakeDone, this));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700389}
390
Comran Morshedb134e772016-03-16 21:05:05 +0000391void AutonomousActor::WaitForSuperstructure() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700392 WaitUntil(::std::bind(&AutonomousActor::SuperstructureDone, this));
Austin Schuh23b21802016-04-03 21:18:56 -0700393}
Comran Morshedb134e772016-03-16 21:05:05 +0000394
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700395void AutonomousActor::WaitForSuperstructureProfile() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700396 WaitUntil([this]() {
397 superstructure_status_fetcher_.Fetch();
398 return SuperstructureProfileDone();
399 });
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700400}
401
Austin Schuh23b21802016-04-03 21:18:56 -0700402void AutonomousActor::WaitForSuperstructureLow() {
Austin Schuh9481d0d2019-06-29 21:56:17 -0700403 WaitUntil([this]() {
404 superstructure_status_fetcher_.Fetch();
Comran Morshedb134e772016-03-16 21:05:05 +0000405
Austin Schuh9481d0d2019-06-29 21:56:17 -0700406 return SuperstructureProfileDone() ||
Alex Perrycb7da4b2019-08-28 19:35:56 -0700407 superstructure_status_fetcher_->shoulder()->angle() < 0.1;
Austin Schuh9481d0d2019-06-29 21:56:17 -0700408 });
Comran Morshedb134e772016-03-16 21:05:05 +0000409}
Austin Schuh9481d0d2019-06-29 21:56:17 -0700410
Austin Schuh23b21802016-04-03 21:18:56 -0700411void AutonomousActor::BackLongShotLowBarTwoBall() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700412 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700413 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55,
414 MakeProfileParameters(7.0, 40.0),
415 MakeProfileParameters(4.0, 6.0),
416 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700417}
418
419void AutonomousActor::BackLongShotTwoBall() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700420 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700421 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55,
422 MakeProfileParameters(7.0, 40.0),
423 MakeProfileParameters(4.0, 6.0),
424 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700425}
426
427void AutonomousActor::BackLongShotTwoBallFinish() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700428 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700429 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625 + 0.03,
430 MakeProfileParameters(7.0, 40.0),
431 MakeProfileParameters(4.0, 6.0),
432 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700433}
434
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700435void AutonomousActor::BackLongShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700436 AOS_LOG(INFO, "Expanding for back long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700437 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62,
438 MakeProfileParameters(7.0, 40.0),
439 MakeProfileParameters(4.0, 6.0),
440 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700441}
442
443void AutonomousActor::BackMiddleShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700444 AOS_LOG(INFO, "Expanding for back middle shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700445 MoveSuperstructure(-0.05, M_PI / 2.0 - 0.2, -0.665,
446 MakeProfileParameters(7.0, 40.0),
447 MakeProfileParameters(4.0, 10.0),
448 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700449}
450
Austin Schuh3e4a5272016-04-20 20:11:00 -0700451void AutonomousActor::FrontLongShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700452 AOS_LOG(INFO, "Expanding for front long shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700453 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02,
454 MakeProfileParameters(7.0, 40.0),
455 MakeProfileParameters(4.0, 6.0),
456 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700457}
458
459void AutonomousActor::FrontMiddleShot() {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700460 AOS_LOG(INFO, "Expanding for front middle shot\n");
Alex Perrycb7da4b2019-08-28 19:35:56 -0700461 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44,
462 MakeProfileParameters(7.0, 40.0),
463 MakeProfileParameters(4.0, 10.0),
464 MakeProfileParameters(10.0, 25.0), true, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700465}
466
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700467void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700468 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0,
469 MakeProfileParameters(7.0, 40.0),
470 MakeProfileParameters(4.0, 10.0),
471 MakeProfileParameters(10.0, 25.0), !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700472}
473
Austin Schuh3e4a5272016-04-20 20:11:00 -0700474void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700475 if (ShouldCancel()) return;
476 // Make sure that the base is aligned with the base.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700477 AOS_LOG(INFO, "Waiting for the superstructure\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700478 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700479
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800480 this_thread::sleep_for(chrono::milliseconds(500));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700481
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700482 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700483 AOS_LOG(INFO, "Triggering the vision actor\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700484 AlignWithVisionGoal();
485
486 // Wait for the drive base to be aligned with the target and make sure that
487 // the shooter is up to speed.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700488 AOS_LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800489 WaitForAlignedWithVision(chrono::milliseconds(2000));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700490 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700491 AOS_LOG(INFO, "Waiting for shooter to be up to speed\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700492 WaitForShooterSpeed();
493 if (ShouldCancel()) return;
494
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800495 this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhf257f3c2019-10-27 21:00:43 -0700496 AOS_LOG(INFO, "Shoot!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700497 Shoot();
498
499 // Turn off the shooter and fold up the superstructure.
500 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700501 AOS_LOG(INFO, "Stopping shooter\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700502 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700503 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700504 TuckArm(false, false);
505
506 // Wait for everything to be folded up.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700507 AOS_LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700508 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700509}
510
511void AutonomousActor::LowBarDrive() {
512 TuckArm(false, true);
513 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
514
515 if (!WaitForDriveNear(5.3, 0.0)) return;
516 TuckArm(true, true);
517
518 if (!WaitForDriveNear(5.0, 0.0)) return;
519
520 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
521
522 if (!WaitForDriveNear(3.0, 0.0)) return;
523
524 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
525
526 if (!WaitForDriveNear(1.0, 0.0)) return;
527
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700528 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700529}
530
Austin Schuh3e4a5272016-04-20 20:11:00 -0700531void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
532 double below, double above) {
533 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
534 if (!WaitForBelowAngle(below)) return;
535 if (!WaitForAboveAngle(above)) return;
536 // Ok, we are good now. Compensate by moving the goal by the error.
537 // Should be here at 2.7
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700538 drivetrain_status_fetcher_.Fetch();
539 if (drivetrain_status_fetcher_.get()) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700540 const double left_error =
541 (initial_drivetrain_.left -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700542 drivetrain_status_fetcher_->estimated_left_position());
Austin Schuh3e4a5272016-04-20 20:11:00 -0700543 const double right_error =
544 (initial_drivetrain_.right -
Alex Perrycb7da4b2019-08-28 19:35:56 -0700545 drivetrain_status_fetcher_->estimated_right_position());
Austin Schuh3e4a5272016-04-20 20:11:00 -0700546 const double distance_to_go = (left_error + right_error) / 2.0;
547 const double distance_compensation =
548 goal_distance - tip_distance - distance_to_go;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700549 AOS_LOG(INFO, "Going %f further at the bump\n", distance_compensation);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700550 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
551 }
552}
553
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700554void AutonomousActor::MiddleDrive() {
555 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700556 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700557 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700558}
559
560void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700561 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700562 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700563 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700564
565 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700566 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700567}
568
569void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700570 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700571 constexpr double kDriveDistance = 5.10;
572 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
573
574 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
575 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700576
577 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700578 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700579}
Comran Morshedb134e772016-03-16 21:05:05 +0000580
Austin Schuh23b21802016-04-03 21:18:56 -0700581void AutonomousActor::CloseIfBall() {
Austin Schuh4b652c92019-05-27 13:22:27 -0700582 ball_detector_fetcher_.Fetch();
583 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700584 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh23b21802016-04-03 21:18:56 -0700585 if (ball_detected) {
586 CloseShooter();
587 }
588 }
589}
590
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700591void AutonomousActor::WaitForBallOrDriveDone() {
Yash Chainania6fe97b2021-12-15 21:01:11 -0800592 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
Austin Schuhd32b3622019-06-23 18:49:06 -0700593 event_loop()->monotonic_now(),
Yash Chainania6fe97b2021-12-15 21:01:11 -0800594 ActorBase::kLoopOffset);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700595 while (true) {
596 if (ShouldCancel()) {
597 return;
598 }
599 phased_loop.SleepUntilNext();
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700600 drivetrain_status_fetcher_.Fetch();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700601 if (IsDriveDone()) {
602 return;
603 }
604
Austin Schuh4b652c92019-05-27 13:22:27 -0700605 ball_detector_fetcher_.Fetch();
606 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700607 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700608 if (ball_detected) {
609 return;
610 }
611 }
612 }
613}
614
Austin Schuh3e4a5272016-04-20 20:11:00 -0700615void AutonomousActor::TwoBallAuto() {
Austin Schuh77ed5432019-07-07 20:41:36 -0700616 const monotonic_clock::time_point start_time = monotonic_now();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700617 OpenShooter();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700618 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
619 MakeProfileParameters(4.0, 10.0),
620 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700621 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700622 AOS_LOG(INFO, "Waiting for the intake to come down.\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700623
624 WaitForIntake();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700625 AOS_LOG(INFO, "Intake done at %f seconds, starting to drive\n",
626 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700627 if (ShouldCancel()) return;
628 const double kDriveDistance = 5.05;
629 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
630
631 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700632 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700633
Austin Schuh295c2d92016-05-01 12:28:04 -0700634 // Check if the ball is there.
635 bool first_ball_there = true;
Austin Schuh4b652c92019-05-27 13:22:27 -0700636 ball_detector_fetcher_.Fetch();
637 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700638 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh295c2d92016-05-01 12:28:04 -0700639 first_ball_there = ball_detected;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700640 AOS_LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
641 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh295c2d92016-05-01 12:28:04 -0700642 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700643 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 40.0),
644 MakeProfileParameters(4.0, 10.0),
645 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700646 AOS_LOG(INFO,
647 "Shutting off rollers at %f seconds, starting to straighten out\n",
648 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700649 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700650 MoveSuperstructure(-0.05, -0.010, 0.0, MakeProfileParameters(8.0, 40.0),
651 MakeProfileParameters(4.0, 10.0),
652 MakeProfileParameters(10.0, 25.0), false, 0.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700653 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700654 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700655
656 // We are now under the low bar. Start lifting.
657 BackLongShotLowBarTwoBall();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700658 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700659 SetShooterSpeed(640.0);
660 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
661
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700662 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
663 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700664 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
665 BackLongShotTwoBall();
666
667 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700668 AOS_LOG(INFO, "First shot done driving at %f seconds\n",
669 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700670
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700671 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700672
673 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700674 AlignWithVisionGoal();
675
676 WaitForShooterSpeed();
677 if (ShouldCancel()) return;
678
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800679 constexpr chrono::milliseconds kVisionExtra{0};
680 WaitForAlignedWithVision(chrono::milliseconds(500) + kVisionExtra);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700681 BackLongShotTwoBallFinish();
682 WaitForSuperstructureProfile();
683 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700684 AOS_LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700685 if (first_ball_there) {
686 Shoot();
687 } else {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700688 AOS_LOG(INFO, "Nah, not shooting\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700689 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700690
Austin Schuhf257f3c2019-10-27 21:00:43 -0700691 AOS_LOG(INFO, "First shot at %f seconds\n",
692 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700693 if (ShouldCancel()) return;
694
695 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700696 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700697 TuckArm(true, true);
698
699 // Undo vision move.
700 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
701 if (!WaitForDriveDone()) return;
702
703 constexpr double kBackDrive = 3.09 - 0.4;
704 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700705 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700706 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700707 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
708 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700709
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700710 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700711 AOS_LOG(INFO, "At Low Bar %f\n",
712 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700713
714 OpenShooter();
715 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700716 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
717 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700718 constexpr double kBallSmallWallTurn = -0.11;
719 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
720
Alex Perrycb7da4b2019-08-28 19:35:56 -0700721 MoveSuperstructure(0.03, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
722 MakeProfileParameters(4.0, 10.0),
723 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700724
725 if (!WaitForDriveProfileDone()) return;
726
Alex Perrycb7da4b2019-08-28 19:35:56 -0700727 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
728 MakeProfileParameters(4.0, 10.0),
729 MakeProfileParameters(10.0, 25.0), false, 12.0);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700730
Austin Schuhf257f3c2019-10-27 21:00:43 -0700731 AOS_LOG(INFO, "Done backing up %f\n",
732 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700733
734 constexpr double kDriveBackDistance = 5.15 - 0.4;
735 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
736 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700737 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700738
739 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700740 AOS_LOG(INFO, "Straightening up at %f\n",
741 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700742
743 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700744 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700745
Austin Schuh4b652c92019-05-27 13:22:27 -0700746 ball_detector_fetcher_.Fetch();
747 if (ball_detector_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700748 const bool ball_detected = ball_detector_fetcher_->voltage() > 2.5;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700749 if (!ball_detected) {
750 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700751 AOS_LOG(INFO, "Aborting, no ball %f\n",
752 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700753 return;
754 }
755 }
756 CloseShooter();
757
758 BackLongShotLowBarTwoBall();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700759 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700760 SetShooterSpeed(640.0);
761 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
762
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700763 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700764 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
765 BackLongShotTwoBall();
766
767 if (!WaitForDriveDone()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700768 AOS_LOG(INFO, "Second shot done driving at %f seconds\n",
769 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700770 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700771 AlignWithVisionGoal();
772 if (ShouldCancel()) return;
773
774 WaitForShooterSpeed();
775 if (ShouldCancel()) return;
776
777 // 2.2 with 0.4 of vision.
778 // 1.8 without any vision.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700779 AOS_LOG(INFO, "Going to vision align at %f\n",
780 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800781 WaitForAlignedWithVision(
782 (start_time + chrono::milliseconds(13500) + kVisionExtra * 2) -
Austin Schuh77ed5432019-07-07 20:41:36 -0700783 monotonic_now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700784 BackLongShotTwoBallFinish();
785 WaitForSuperstructureProfile();
786 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700787 AOS_LOG(INFO, "Shoot at %f\n",
788 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700789 Shoot();
790
Austin Schuhf257f3c2019-10-27 21:00:43 -0700791 AOS_LOG(INFO, "Second shot at %f seconds\n",
792 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700793 if (ShouldCancel()) return;
794
795 SetShooterSpeed(0.0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700796 AOS_LOG(INFO, "Folding superstructure back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700797 TuckArm(true, false);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700798 AOS_LOG(INFO, "Shot %f\n",
799 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700800
801 WaitForSuperstructureLow();
802
Austin Schuhf257f3c2019-10-27 21:00:43 -0700803 AOS_LOG(INFO, "Done %f\n",
804 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700805}
806
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700807void AutonomousActor::StealAndMoveOverBy(double distance) {
808 OpenShooter();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700809 MoveSuperstructure(0.10, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
810 MakeProfileParameters(4.0, 10.0),
811 MakeProfileParameters(10.0, 25.0), true, 12.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700812 if (ShouldCancel()) return;
Austin Schuhf257f3c2019-10-27 21:00:43 -0700813 AOS_LOG(INFO, "Waiting for the intake to come down.\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700814
815 WaitForIntake();
816 if (ShouldCancel()) return;
817 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
818 WaitForBallOrDriveDone();
819 if (ShouldCancel()) return;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700820 MoveSuperstructure(1.0, -0.010, 0.0, MakeProfileParameters(8.0, 60.0),
821 MakeProfileParameters(4.0, 10.0),
822 MakeProfileParameters(10.0, 25.0), true, 12.0);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700823
824 if (!WaitForDriveDone()) return;
825 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
826 if (!WaitForDriveDone()) return;
827}
828
Philipp Schrader4bd29b12017-02-22 04:42:27 +0000829bool AutonomousActor::RunAction(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700830 const ::frc971::autonomous::AutonomousActionParams *params) {
Austin Schuh77ed5432019-07-07 20:41:36 -0700831 monotonic_clock::time_point start_time = monotonic_now();
Austin Schuhf257f3c2019-10-27 21:00:43 -0700832 AOS_LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n",
Alex Perrycb7da4b2019-08-28 19:35:56 -0700833 params->mode());
Comran Morshede68e3732016-03-12 14:12:11 +0000834
Comran Morshed435f1112016-03-12 14:20:45 +0000835 InitializeEncoders();
836 ResetDrivetrain();
837
Alex Perrycb7da4b2019-08-28 19:35:56 -0700838 switch (params->mode()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700839 case 0:
840 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700841 if (!WaitForDriveDone()) return true;
842 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700843 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700844 FrontLongShot();
845
846 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700847 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700848 SetShooterSpeed(640.0);
849
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700850 break;
851 case 1:
852 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700853 if (!WaitForDriveDone()) return true;
854 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700855 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700856 FrontMiddleShot();
857
858 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700859 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700860 SetShooterSpeed(600.0);
861
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700862 break;
863 case 2:
864 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700865 if (!WaitForDriveDone()) return true;
866 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700867 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700868 FrontMiddleShot();
869
870 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700871 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700872 SetShooterSpeed(600.0);
873
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700874 break;
875 case 3:
876 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700877 if (!WaitForDriveDone()) return true;
878 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700879 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700880 FrontMiddleShot();
881
882 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700883 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700884 SetShooterSpeed(600.0);
885
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700886 break;
887 case 4:
888 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700889 if (!WaitForDriveDone()) return true;
890 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700891 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700892 FrontMiddleShot();
893
894 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700895 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700896 SetShooterSpeed(600.0);
897
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700898 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700899 case 5:
Campbell Crowley9ed61a52016-11-05 17:13:07 -0700900 case 15:
Austin Schuh3e4a5272016-04-20 20:11:00 -0700901 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -0700902 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700903 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700904 case 6:
905 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
906 if (ShouldCancel()) return true;
907
908 TwoFromMiddleDrive();
909 if (!WaitForDriveDone()) return true;
910 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700911 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700912 FrontMiddleShot();
913
914 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700915 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700916 SetShooterSpeed(600.0);
917
918 break;
919 case 7:
920 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
921 if (ShouldCancel()) return true;
922
923 OneFromMiddleDrive(true);
924 if (!WaitForDriveDone()) return true;
925 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700926 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700927 FrontMiddleShot();
928
929 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700930 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700931 SetShooterSpeed(600.0);
932
933 break;
934 case 8: {
935 StealAndMoveOverBy(2.95);
936 if (ShouldCancel()) return true;
937
938 MiddleDrive();
939 if (!WaitForDriveDone()) return true;
940 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700941 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700942 FrontMiddleShot();
943
944 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700945 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700946 SetShooterSpeed(600.0);
947
948 } break;
949 case 9: {
950 StealAndMoveOverBy(1.70);
951 if (ShouldCancel()) return true;
952
953 OneFromMiddleDrive(false);
954 if (!WaitForDriveDone()) return true;
955 // Get the superstructure to unfold and get ready for shooting.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700956 AOS_LOG(INFO, "Unfolding superstructure\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700957 FrontMiddleShot();
958
959 // Spin up the shooter wheels.
Austin Schuhf257f3c2019-10-27 21:00:43 -0700960 AOS_LOG(INFO, "Spinning up the shooter wheels\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700961 SetShooterSpeed(600.0);
962
963 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700964 default:
Alex Perrycb7da4b2019-08-28 19:35:56 -0700965 AOS_LOG(ERROR, "Invalid auto mode %d\n", params->mode());
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700966 return true;
967 }
Comran Morshed435f1112016-03-12 14:20:45 +0000968
Austin Schuh3e4a5272016-04-20 20:11:00 -0700969 DoFullShot();
970
971 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +0000972 if (!WaitForDriveDone()) return true;
973
Austin Schuhf257f3c2019-10-27 21:00:43 -0700974 AOS_LOG(INFO, "Done %f\n",
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700975 ::aos::time::DurationInSeconds(monotonic_now() - start_time));
Comran Morshed435f1112016-03-12 14:20:45 +0000976
Yash Chainania6fe97b2021-12-15 21:01:11 -0800977 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
978 monotonic_now(), ActorBase::kLoopOffset);
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