blob: 0a298d70a9919c7fa1a07e5b873b2858e0b2763d [file] [log] [blame]
milind-u086d7262022-01-19 20:44:18 -08001#include "y2022/actors/autonomous_actor.h"
2
3#include <chrono>
4#include <cinttypes>
5#include <cmath>
6
7#include "aos/logging/logging.h"
Ravago Jones81e50632022-03-11 16:23:51 -08008#include "aos/network/team_number.h"
9#include "aos/util/math.h"
milind-u086d7262022-01-19 20:44:18 -080010#include "frc971/control_loops/drivetrain/localizer_generated.h"
Ravago Jones81e50632022-03-11 16:23:51 -080011#include "y2022/actors/auto_splines.h"
12#include "y2022/constants.h"
milind-u086d7262022-01-19 20:44:18 -080013#include "y2022/control_loops/drivetrain/drivetrain_base.h"
14
Ravago Jones81e50632022-03-11 16:23:51 -080015DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
Austin Schuh42d7e5f2022-03-16 23:35:09 -070016DEFINE_bool(rapid_react, true,
Milind Upadhyaya7793962022-03-11 19:39:36 -080017 "If true, run the main rapid react autonomous mode");
Henry Speiser5eed1de2022-04-07 21:52:10 -070018DEFINE_bool(rapid_react_two, false,
19 "If true, run the two ball rapid react autonomous mode");
Ravago Jones81e50632022-03-11 16:23:51 -080020
milind-u086d7262022-01-19 20:44:18 -080021namespace y2022 {
22namespace actors {
Ravago Jones81e50632022-03-11 16:23:51 -080023namespace {
Henry Speisere23d4de2022-04-05 16:47:47 -070024constexpr double kExtendIntakeGoal = -0.10;
Ravago Jones81e50632022-03-11 16:23:51 -080025constexpr double kRetractIntakeGoal = 1.47;
Austin Schuh42d7e5f2022-03-16 23:35:09 -070026constexpr double kIntakeRollerVoltage = 12.0;
Ravago Jones81e50632022-03-11 16:23:51 -080027constexpr double kRollerVoltage = 12.0;
28constexpr double kCatapultReturnPosition = -0.908;
29} // namespace
milind-u086d7262022-01-19 20:44:18 -080030
31using ::aos::monotonic_clock;
Ravago Jones81e50632022-03-11 16:23:51 -080032using frc971::CreateProfileParameters;
milind-u086d7262022-01-19 20:44:18 -080033using ::frc971::ProfileParametersT;
Ravago Jones81e50632022-03-11 16:23:51 -080034using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
35using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
milind-u086d7262022-01-19 20:44:18 -080036using frc971::control_loops::drivetrain::LocalizerControl;
Ravago Jones81e50632022-03-11 16:23:51 -080037
milind-u086d7262022-01-19 20:44:18 -080038namespace chrono = ::std::chrono;
39
40AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
41 : frc971::autonomous::BaseAutonomousActor(
Ravago Jones81e50632022-03-11 16:23:51 -080042 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
43 localizer_control_sender_(
44 event_loop->MakeSender<
45 ::frc971::control_loops::drivetrain::LocalizerControl>(
46 "/drivetrain")),
47 superstructure_goal_sender_(
48 event_loop->MakeSender<control_loops::superstructure::Goal>(
49 "/superstructure")),
50 superstructure_status_fetcher_(
51 event_loop->MakeFetcher<control_loops::superstructure::Status>(
52 "/superstructure")),
53 joystick_state_fetcher_(
54 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
55 robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
56 auto_splines_() {
57 set_max_drivetrain_voltage(12.0);
58 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
59 event_loop->OnRun([this, event_loop]() {
60 replan_timer_->Setup(event_loop->monotonic_now());
61 button_poll_->Setup(event_loop->monotonic_now(), chrono::milliseconds(50));
62 });
63
64 button_poll_ = event_loop->AddTimer([this]() {
65 const aos::monotonic_clock::time_point now =
66 this->event_loop()->context().monotonic_event_time;
67 if (robot_state_fetcher_.Fetch()) {
68 if (robot_state_fetcher_->user_button()) {
69 user_indicated_safe_to_reset_ = true;
70 MaybeSendStartingPosition();
71 }
72 }
73 if (joystick_state_fetcher_.Fetch()) {
74 if (joystick_state_fetcher_->has_alliance() &&
75 (joystick_state_fetcher_->alliance() != alliance_)) {
76 alliance_ = joystick_state_fetcher_->alliance();
77 is_planned_ = false;
78 // Only kick the planning out by 2 seconds. If we end up enabled in that
79 // second, then we will kick it out further based on the code below.
80 replan_timer_->Setup(now + std::chrono::seconds(2));
81 }
82 if (joystick_state_fetcher_->enabled()) {
83 if (!is_planned_) {
84 // Only replan once we've been disabled for 5 seconds.
85 replan_timer_->Setup(now + std::chrono::seconds(5));
86 }
87 }
88 }
89 });
90}
91
92void AutonomousActor::Replan() {
93 LOG(INFO) << "Alliance " << static_cast<int>(alliance_);
94 if (alliance_ == aos::Alliance::kInvalid) {
95 return;
96 }
97 sent_starting_position_ = false;
98 if (FLAGS_spline_auto) {
99 test_spline_ =
100 PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
101 std::placeholders::_1, alliance_),
102 SplineDirection::kForward);
103
104 starting_position_ = test_spline_->starting_position();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800105 } else if (FLAGS_rapid_react) {
106 rapid_react_splines_ = {
107 PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
108 std::placeholders::_1, alliance_),
Henry Speiser09e8da92022-03-14 20:58:45 -0700109 SplineDirection::kBackward),
Milind Upadhyaya7793962022-03-11 19:39:36 -0800110 PlanSpline(std::bind(&AutonomousSplines::Spline2, &auto_splines_,
111 std::placeholders::_1, alliance_),
Henry Speisere23d4de2022-04-05 16:47:47 -0700112 SplineDirection::kBackward),
Milind Upadhyaya7793962022-03-11 19:39:36 -0800113 PlanSpline(std::bind(&AutonomousSplines::Spline3, &auto_splines_,
114 std::placeholders::_1, alliance_),
Henry Speisere23d4de2022-04-05 16:47:47 -0700115 SplineDirection::kForward)};
Milind Upadhyaya7793962022-03-11 19:39:36 -0800116 starting_position_ = rapid_react_splines_.value()[0].starting_position();
117 CHECK(starting_position_);
Henry Speiser5eed1de2022-04-07 21:52:10 -0700118 } else if (FLAGS_rapid_react_two) {
119 rapid_react_two_spline_ = {
120 PlanSpline(std::bind(&AutonomousSplines::SplineTwoBall, &auto_splines_,
121 std::placeholders::_1, alliance_),
122 SplineDirection::kBackward)};
123 starting_position_ = rapid_react_two_spline_.value()[0].starting_position();
124 CHECK(starting_position_);
Ravago Jones81e50632022-03-11 16:23:51 -0800125 }
126
127 is_planned_ = true;
128
129 MaybeSendStartingPosition();
130}
131
132void AutonomousActor::MaybeSendStartingPosition() {
133 if (is_planned_ && user_indicated_safe_to_reset_ &&
134 !sent_starting_position_) {
135 CHECK(starting_position_);
136 SendStartingPosition(starting_position_.value());
137 }
138}
milind-u086d7262022-01-19 20:44:18 -0800139
140void AutonomousActor::Reset() {
141 InitializeEncoders();
142 ResetDrivetrain();
Ravago Jones81e50632022-03-11 16:23:51 -0800143 RetractFrontIntake();
144 RetractBackIntake();
145
146 joystick_state_fetcher_.Fetch();
147 CHECK(joystick_state_fetcher_.get() != nullptr)
148 << "Expect at least one JoystickState message before running auto...";
149 alliance_ = joystick_state_fetcher_->alliance();
milind-u086d7262022-01-19 20:44:18 -0800150}
151
152bool AutonomousActor::RunAction(
153 const ::frc971::autonomous::AutonomousActionParams *params) {
154 Reset();
Ravago Jones81e50632022-03-11 16:23:51 -0800155 if (!user_indicated_safe_to_reset_) {
156 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
157 CHECK(starting_position_);
158 SendStartingPosition(starting_position_.value());
159 }
160 // Clear this so that we don't accidentally resend things as soon as we replan
161 // later.
162 user_indicated_safe_to_reset_ = false;
163 is_planned_ = false;
164 starting_position_.reset();
milind-u086d7262022-01-19 20:44:18 -0800165
166 AOS_LOG(INFO, "Params are %d\n", params->mode());
Ravago Jones81e50632022-03-11 16:23:51 -0800167 if (alliance_ == aos::Alliance::kInvalid) {
168 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
169 return false;
170 }
171 if (FLAGS_spline_auto) {
172 SplineAuto();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800173 } else if (FLAGS_rapid_react) {
174 RapidReact();
Henry Speiser5eed1de2022-04-07 21:52:10 -0700175 } else if (FLAGS_rapid_react_two) {
176 RapidReactTwo();
Ravago Jones81e50632022-03-11 16:23:51 -0800177 }
178
milind-u086d7262022-01-19 20:44:18 -0800179 return true;
180}
181
Ravago Jones81e50632022-03-11 16:23:51 -0800182void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
183 // Set up the starting position for the blue alliance.
184
185 // TODO(james): Resetting the localizer breaks the left/right statespace
186 // controller. That is a bug, but we can fix that later by not resetting.
187 auto builder = localizer_control_sender_.MakeBuilder();
188
189 LocalizerControl::Builder localizer_control_builder =
190 builder.MakeBuilder<LocalizerControl>();
191 localizer_control_builder.add_x(start(0));
192 localizer_control_builder.add_y(start(1));
193 localizer_control_builder.add_theta(start(2));
194 localizer_control_builder.add_theta_uncertainty(0.00001);
195 LOG(INFO) << "User button pressed, x: " << start(0) << " y: " << start(1)
196 << " theta: " << start(2);
197 if (builder.Send(localizer_control_builder.Finish()) !=
198 aos::RawSender::Error::kOk) {
199 AOS_LOG(ERROR, "Failed to reset localizer.\n");
200 }
201}
202
203void AutonomousActor::SplineAuto() {
204 CHECK(test_spline_);
205
206 if (!test_spline_->WaitForPlan()) return;
207 test_spline_->Start();
208
209 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
210}
211
Milind Upadhyaya7793962022-03-11 19:39:36 -0800212void AutonomousActor::RapidReact() {
213 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
214
215 CHECK(rapid_react_splines_);
216
217 auto &splines = *rapid_react_splines_;
218
219 // Tell the superstructure a ball was preloaded
Milind Upadhyaya7793962022-03-11 19:39:36 -0800220 if (!WaitForPreloaded()) return;
Henry Speiser09e8da92022-03-14 20:58:45 -0700221
Henry Speisere23d4de2022-04-05 16:47:47 -0700222 // Fire preloaded ball while driving
Henry Speiser09e8da92022-03-14 20:58:45 -0700223 set_fire_at_will(true);
224 SendSuperstructureGoal();
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700225 if (!WaitForBallsShot()) return;
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700226 LOG(INFO) << "Shot first ball "
227 << chrono::duration<double>(aos::monotonic_clock::now() -
228 start_time)
229 .count()
230 << 's';
Henry Speiser09e8da92022-03-14 20:58:45 -0700231 set_fire_at_will(false);
232 SendSuperstructureGoal();
233
Henry Speisere23d4de2022-04-05 16:47:47 -0700234 // Drive and intake the ball nearest to the starting zone.
235 // Fire while moving.
Henry Speiser09e8da92022-03-14 20:58:45 -0700236 ExtendBackIntake();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800237 if (!splines[0].WaitForPlan()) return;
238 splines[0].Start();
Henry Speisere23d4de2022-04-05 16:47:47 -0700239 // Distance before we don't shoot while moving.
240 if (!splines[0].WaitForSplineDistanceRemaining(0.25)) return;
Milind Upadhyaya7793962022-03-11 19:39:36 -0800241
Milind Upadhyaya7793962022-03-11 19:39:36 -0800242 set_fire_at_will(true);
243 SendSuperstructureGoal();
Henry Speisere23d4de2022-04-05 16:47:47 -0700244
245 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
246
247 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
248
249 // Fire the last ball we picked up when stopped.
250 SendSuperstructureGoal();
251 LOG(INFO) << "Close";
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700252 if (!WaitForBallsShot()) return;
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700253 LOG(INFO) << "Shot first 3 balls "
254 << chrono::duration<double>(aos::monotonic_clock::now() -
255 start_time)
256 .count()
257 << 's';
Milind Upadhyaya7793962022-03-11 19:39:36 -0800258
259 // Drive to the human player station while intaking two balls.
260 // Once is already placed down,
261 // and one will be rolled to the robot by the human player
Henry Speiser09e8da92022-03-14 20:58:45 -0700262 if (!splines[1].WaitForPlan()) return;
263 splines[1].Start();
Henry Speisere23d4de2022-04-05 16:47:47 -0700264
265 std::this_thread::sleep_for(std::chrono::milliseconds(1500));
266
267 set_fire_at_will(false);
268 SendSuperstructureGoal();
269
Henry Speiser09e8da92022-03-14 20:58:45 -0700270 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
Henry Speisere23d4de2022-04-05 16:47:47 -0700271 std::this_thread::sleep_for(std::chrono::milliseconds(500));
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700272 LOG(INFO) << "At balls 4/5 "
273 << chrono::duration<double>(aos::monotonic_clock::now() -
274 start_time)
275 .count()
276 << 's';
Milind Upadhyaya7793962022-03-11 19:39:36 -0800277
278 // Drive to the shooting position
Henry Speiser09e8da92022-03-14 20:58:45 -0700279 if (!splines[2].WaitForPlan()) return;
280 splines[2].Start();
281 if (!splines[2].WaitForSplineDistanceRemaining(2.00)) return;
282 RetractFrontIntake();
283
284 if (!splines[2].WaitForSplineDistanceRemaining(0.02)) return;
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700285 LOG(INFO) << "Shooting last balls "
286 << chrono::duration<double>(aos::monotonic_clock::now() -
287 start_time)
288 .count()
289 << 's';
Milind Upadhyaya7793962022-03-11 19:39:36 -0800290
291 // Fire the two balls once we stopped
292 set_fire_at_will(true);
293 SendSuperstructureGoal();
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700294 if (!WaitForBallsShot()) return;
Milind Upadhyaya7793962022-03-11 19:39:36 -0800295 set_fire_at_will(false);
Henry Speiser09e8da92022-03-14 20:58:45 -0700296 SendSuperstructureGoal();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800297
298 LOG(INFO) << "Took "
299 << chrono::duration<double>(aos::monotonic_clock::now() -
300 start_time)
301 .count()
302 << 's';
303}
304
Henry Speiser5eed1de2022-04-07 21:52:10 -0700305// Rapid React Two Ball Autonomous.
306void AutonomousActor::RapidReactTwo() {
307 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
308
309 CHECK(rapid_react_two_spline_);
310
311 auto &splines = *rapid_react_two_spline_;
312
313 // Tell the superstructure a ball was preloaded
314 if (!WaitForPreloaded()) return;
315 set_fire_at_will(true);
316 SendSuperstructureGoal();
317 if (!WaitForBallsShot()) return;
318 LOG(INFO) << "Shot first ball "
319 << chrono::duration<double>(aos::monotonic_clock::now() -
320 start_time)
321 .count()
322 << 's';
323 set_fire_at_will(false);
324 SendSuperstructureGoal();
325
326 ExtendBackIntake();
327 if (!splines[0].WaitForPlan()) return;
328 splines[0].Start();
329 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
330
331 // Fire the ball once we stopped
332 RetractBackIntake();
333 set_fire_at_will(true);
334 SendSuperstructureGoal();
335 if (!WaitForBallsShot()) return;
336 LOG(INFO) << "Shot last ball "
337 << chrono::duration<double>(aos::monotonic_clock::now() -
338 start_time)
339 .count()
340 << 's';
341 set_fire_at_will(false);
342 SendSuperstructureGoal();
343}
344
Milind Upadhyaya7793962022-03-11 19:39:36 -0800345[[nodiscard]] bool AutonomousActor::WaitForPreloaded() {
Milind Upadhyay803bbf02022-03-11 17:56:26 -0800346 set_preloaded(true);
347 SendSuperstructureGoal();
348
349 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
350 event_loop()->monotonic_now(),
351 ActorBase::kLoopOffset);
352
353 bool loaded = false;
354 while (!loaded) {
355 if (ShouldCancel()) {
356 return false;
357 }
358
359 phased_loop.SleepUntilNext();
360 superstructure_status_fetcher_.Fetch();
361 CHECK(superstructure_status_fetcher_.get() != nullptr);
362
363 loaded = (superstructure_status_fetcher_->state() ==
364 control_loops::superstructure::SuperstructureState::LOADED);
365 }
366
367 set_preloaded(false);
368 SendSuperstructureGoal();
369
370 return true;
371}
372
Ravago Jones81e50632022-03-11 16:23:51 -0800373void AutonomousActor::SendSuperstructureGoal() {
374 auto builder = superstructure_goal_sender_.MakeBuilder();
375
376 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
377 intake_front_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
378 *builder.fbb(), intake_front_goal_,
379 CreateProfileParameters(*builder.fbb(), 20.0, 60.0));
380
381 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
382 intake_back_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
383 *builder.fbb(), intake_back_goal_,
384 CreateProfileParameters(*builder.fbb(), 20.0, 60.0));
385
386 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
387 catapult_return_position_offset =
388 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
389 *builder.fbb(), kCatapultReturnPosition,
390 CreateProfileParameters(*builder.fbb(), 9.0, 50.0));
391
392 superstructure::CatapultGoal::Builder catapult_goal_builder(*builder.fbb());
393 catapult_goal_builder.add_shot_position(0.03);
394 catapult_goal_builder.add_shot_velocity(18.0);
395 catapult_goal_builder.add_return_position(catapult_return_position_offset);
396 flatbuffers::Offset<superstructure::CatapultGoal> catapult_goal_offset =
397 catapult_goal_builder.Finish();
398
399 superstructure::Goal::Builder superstructure_builder =
400 builder.MakeBuilder<superstructure::Goal>();
401
402 superstructure_builder.add_intake_front(intake_front_offset);
403 superstructure_builder.add_intake_back(intake_back_offset);
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700404 superstructure_builder.add_roller_speed_compensation(0.0);
Ravago Jones81e50632022-03-11 16:23:51 -0800405 superstructure_builder.add_roller_speed_front(roller_front_voltage_);
406 superstructure_builder.add_roller_speed_back(roller_back_voltage_);
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700407 if (requested_intake_.has_value()) {
408 superstructure_builder.add_turret_intake(*requested_intake_);
409 }
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700410 superstructure_builder.add_transfer_roller_speed(transfer_roller_voltage_);
Ravago Jones81e50632022-03-11 16:23:51 -0800411 superstructure_builder.add_catapult(catapult_goal_offset);
412 superstructure_builder.add_fire(fire_);
Milind Upadhyay803bbf02022-03-11 17:56:26 -0800413 superstructure_builder.add_preloaded(preloaded_);
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700414 superstructure_builder.add_auto_aim(true);
Ravago Jones81e50632022-03-11 16:23:51 -0800415
416 if (builder.Send(superstructure_builder.Finish()) !=
417 aos::RawSender::Error::kOk) {
418 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
419 }
420}
421
422void AutonomousActor::ExtendFrontIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700423 set_requested_intake(RequestedIntake::kFront);
Ravago Jones81e50632022-03-11 16:23:51 -0800424 set_intake_front_goal(kExtendIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700425 set_roller_front_voltage(kIntakeRollerVoltage);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700426 set_transfer_roller_voltage(kRollerVoltage);
Ravago Jones81e50632022-03-11 16:23:51 -0800427 SendSuperstructureGoal();
428}
429
430void AutonomousActor::RetractFrontIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700431 set_requested_intake(std::nullopt);
Ravago Jones81e50632022-03-11 16:23:51 -0800432 set_intake_front_goal(kRetractIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700433 set_roller_front_voltage(0.0);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700434 set_transfer_roller_voltage(0.0);
Ravago Jones81e50632022-03-11 16:23:51 -0800435 SendSuperstructureGoal();
436}
437
438void AutonomousActor::ExtendBackIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700439 set_requested_intake(RequestedIntake::kBack);
Ravago Jones81e50632022-03-11 16:23:51 -0800440 set_intake_back_goal(kExtendIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700441 set_roller_back_voltage(kIntakeRollerVoltage);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700442 set_transfer_roller_voltage(-kRollerVoltage);
Ravago Jones81e50632022-03-11 16:23:51 -0800443 SendSuperstructureGoal();
444}
445
446void AutonomousActor::RetractBackIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700447 set_requested_intake(std::nullopt);
Ravago Jones81e50632022-03-11 16:23:51 -0800448 set_intake_back_goal(kRetractIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700449 set_roller_back_voltage(0.0);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700450 set_transfer_roller_voltage(0.0);
Ravago Jones81e50632022-03-11 16:23:51 -0800451 SendSuperstructureGoal();
452}
453
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700454[[nodiscard]] bool AutonomousActor::WaitForBallsShot() {
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700455 superstructure_status_fetcher_.Fetch();
456 CHECK(superstructure_status_fetcher_.get());
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700457
Ravago Jonesf699d1c2022-03-11 18:39:56 -0800458 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
459 event_loop()->monotonic_now(),
460 ActorBase::kLoopOffset);
461 superstructure_status_fetcher_.Fetch();
462 CHECK(superstructure_status_fetcher_.get() != nullptr);
Henry Speisere23d4de2022-04-05 16:47:47 -0700463
Ravago Jonesf699d1c2022-03-11 18:39:56 -0800464 while (true) {
465 if (ShouldCancel()) {
466 return false;
467 }
468 phased_loop.SleepUntilNext();
469 superstructure_status_fetcher_.Fetch();
470 CHECK(superstructure_status_fetcher_.get() != nullptr);
Henry Speisere23d4de2022-04-05 16:47:47 -0700471
472 if (!superstructure_status_fetcher_->front_intake_has_ball() &&
473 !superstructure_status_fetcher_->back_intake_has_ball() &&
474 superstructure_status_fetcher_->state() ==
475 control_loops::superstructure::SuperstructureState::IDLE) {
Ravago Jonesf699d1c2022-03-11 18:39:56 -0800476 return true;
477 }
478 }
479}
480
milind-u086d7262022-01-19 20:44:18 -0800481} // namespace actors
482} // namespace y2022