blob: 41f7e04b99692f1a3c5a4c2a7ff8dc976bdcecd8 [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 Schuh9651c5a2022-04-17 19:12:42 -070016DEFINE_bool(rapid_react, true,
Milind Upadhyaya7793962022-03-11 19:39:36 -080017 "If true, run the main rapid react autonomous mode");
Austin Schuh9651c5a2022-04-17 19:12:42 -070018DEFINE_bool(rapid_react_two, false,
Henry Speiser5eed1de2022-04-07 21:52:10 -070019 "If true, run the two ball rapid react autonomous mode");
Ravago Jones81e50632022-03-11 16:23:51 -080020
Stephan Pleinesf63bde82024-01-13 15:59:33 -080021namespace y2022::actors {
Ravago Jones81e50632022-03-11 16:23:51 -080022namespace {
Henry Speisere23d4de2022-04-05 16:47:47 -070023constexpr double kExtendIntakeGoal = -0.10;
Ravago Jones81e50632022-03-11 16:23:51 -080024constexpr double kRetractIntakeGoal = 1.47;
Austin Schuh42d7e5f2022-03-16 23:35:09 -070025constexpr double kIntakeRollerVoltage = 12.0;
Ravago Jones81e50632022-03-11 16:23:51 -080026constexpr double kRollerVoltage = 12.0;
27constexpr double kCatapultReturnPosition = -0.908;
28} // namespace
milind-u086d7262022-01-19 20:44:18 -080029
30using ::aos::monotonic_clock;
Ravago Jones81e50632022-03-11 16:23:51 -080031using frc971::CreateProfileParameters;
milind-u086d7262022-01-19 20:44:18 -080032using ::frc971::ProfileParametersT;
Ravago Jones81e50632022-03-11 16:23:51 -080033using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
34using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
milind-u086d7262022-01-19 20:44:18 -080035using frc971::control_loops::drivetrain::LocalizerControl;
Ravago Jones81e50632022-03-11 16:23:51 -080036
milind-u086d7262022-01-19 20:44:18 -080037namespace chrono = ::std::chrono;
38
39AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
40 : frc971::autonomous::BaseAutonomousActor(
Ravago Jones81e50632022-03-11 16:23:51 -080041 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
42 localizer_control_sender_(
43 event_loop->MakeSender<
44 ::frc971::control_loops::drivetrain::LocalizerControl>(
45 "/drivetrain")),
46 superstructure_goal_sender_(
47 event_loop->MakeSender<control_loops::superstructure::Goal>(
48 "/superstructure")),
49 superstructure_status_fetcher_(
50 event_loop->MakeFetcher<control_loops::superstructure::Status>(
51 "/superstructure")),
52 joystick_state_fetcher_(
53 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
54 robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
55 auto_splines_() {
56 set_max_drivetrain_voltage(12.0);
57 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
58 event_loop->OnRun([this, event_loop]() {
Philipp Schradera6712522023-07-05 20:25:11 -070059 replan_timer_->Schedule(event_loop->monotonic_now());
60 button_poll_->Schedule(event_loop->monotonic_now(),
61 chrono::milliseconds(50));
Ravago Jones81e50632022-03-11 16:23:51 -080062 });
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.
Philipp Schradera6712522023-07-05 20:25:11 -070080 replan_timer_->Schedule(now + std::chrono::seconds(2));
Ravago Jones81e50632022-03-11 16:23:51 -080081 }
82 if (joystick_state_fetcher_->enabled()) {
83 if (!is_planned_) {
84 // Only replan once we've been disabled for 5 seconds.
Philipp Schradera6712522023-07-05 20:25:11 -070085 replan_timer_->Schedule(now + std::chrono::seconds(5));
Ravago Jones81e50632022-03-11 16:23:51 -080086 }
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_ = {
Austin Schuhf3413b72022-04-16 19:09:33 -0700120 PlanSpline(std::bind(&AutonomousSplines::SplineTwoBall1, &auto_splines_,
Henry Speiser5eed1de2022-04-07 21:52:10 -0700121 std::placeholders::_1, alliance_),
Austin Schuhf3413b72022-04-16 19:09:33 -0700122 SplineDirection::kBackward),
123 PlanSpline(std::bind(&AutonomousSplines::SplineTwoBall2, &auto_splines_,
124 std::placeholders::_1, alliance_),
125 SplineDirection::kForward)};
Henry Speiser5eed1de2022-04-07 21:52:10 -0700126 starting_position_ = rapid_react_two_spline_.value()[0].starting_position();
127 CHECK(starting_position_);
Ravago Jones81e50632022-03-11 16:23:51 -0800128 }
129
130 is_planned_ = true;
131
132 MaybeSendStartingPosition();
133}
134
135void AutonomousActor::MaybeSendStartingPosition() {
136 if (is_planned_ && user_indicated_safe_to_reset_ &&
137 !sent_starting_position_) {
138 CHECK(starting_position_);
139 SendStartingPosition(starting_position_.value());
140 }
141}
milind-u086d7262022-01-19 20:44:18 -0800142
143void AutonomousActor::Reset() {
144 InitializeEncoders();
145 ResetDrivetrain();
Ravago Jones81e50632022-03-11 16:23:51 -0800146 RetractFrontIntake();
147 RetractBackIntake();
148
149 joystick_state_fetcher_.Fetch();
150 CHECK(joystick_state_fetcher_.get() != nullptr)
151 << "Expect at least one JoystickState message before running auto...";
152 alliance_ = joystick_state_fetcher_->alliance();
milind-u086d7262022-01-19 20:44:18 -0800153}
154
155bool AutonomousActor::RunAction(
156 const ::frc971::autonomous::AutonomousActionParams *params) {
157 Reset();
Ravago Jones81e50632022-03-11 16:23:51 -0800158 if (!user_indicated_safe_to_reset_) {
159 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
160 CHECK(starting_position_);
161 SendStartingPosition(starting_position_.value());
162 }
163 // Clear this so that we don't accidentally resend things as soon as we replan
164 // later.
165 user_indicated_safe_to_reset_ = false;
166 is_planned_ = false;
167 starting_position_.reset();
milind-u086d7262022-01-19 20:44:18 -0800168
169 AOS_LOG(INFO, "Params are %d\n", params->mode());
Ravago Jones81e50632022-03-11 16:23:51 -0800170 if (alliance_ == aos::Alliance::kInvalid) {
171 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
172 return false;
173 }
174 if (FLAGS_spline_auto) {
175 SplineAuto();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800176 } else if (FLAGS_rapid_react) {
177 RapidReact();
Henry Speiser5eed1de2022-04-07 21:52:10 -0700178 } else if (FLAGS_rapid_react_two) {
179 RapidReactTwo();
Ravago Jones81e50632022-03-11 16:23:51 -0800180 }
181
milind-u086d7262022-01-19 20:44:18 -0800182 return true;
183}
184
Ravago Jones81e50632022-03-11 16:23:51 -0800185void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
186 // Set up the starting position for the blue alliance.
187
188 // TODO(james): Resetting the localizer breaks the left/right statespace
189 // controller. That is a bug, but we can fix that later by not resetting.
190 auto builder = localizer_control_sender_.MakeBuilder();
191
192 LocalizerControl::Builder localizer_control_builder =
193 builder.MakeBuilder<LocalizerControl>();
194 localizer_control_builder.add_x(start(0));
195 localizer_control_builder.add_y(start(1));
196 localizer_control_builder.add_theta(start(2));
197 localizer_control_builder.add_theta_uncertainty(0.00001);
198 LOG(INFO) << "User button pressed, x: " << start(0) << " y: " << start(1)
199 << " theta: " << start(2);
200 if (builder.Send(localizer_control_builder.Finish()) !=
201 aos::RawSender::Error::kOk) {
202 AOS_LOG(ERROR, "Failed to reset localizer.\n");
203 }
204}
205
206void AutonomousActor::SplineAuto() {
207 CHECK(test_spline_);
208
209 if (!test_spline_->WaitForPlan()) return;
210 test_spline_->Start();
211
212 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
213}
214
Milind Upadhyaya7793962022-03-11 19:39:36 -0800215void AutonomousActor::RapidReact() {
216 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
217
218 CHECK(rapid_react_splines_);
219
220 auto &splines = *rapid_react_splines_;
221
222 // Tell the superstructure a ball was preloaded
Milind Upadhyaya7793962022-03-11 19:39:36 -0800223 if (!WaitForPreloaded()) return;
Henry Speiser09e8da92022-03-14 20:58:45 -0700224
Henry Speisere23d4de2022-04-05 16:47:47 -0700225 // Fire preloaded ball while driving
Henry Speiser09e8da92022-03-14 20:58:45 -0700226 set_fire_at_will(true);
227 SendSuperstructureGoal();
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700228 if (!WaitForBallsShot()) return;
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700229 LOG(INFO) << "Shot first ball "
230 << chrono::duration<double>(aos::monotonic_clock::now() -
231 start_time)
232 .count()
233 << 's';
Henry Speiser09e8da92022-03-14 20:58:45 -0700234 set_fire_at_will(false);
235 SendSuperstructureGoal();
236
Henry Speisere23d4de2022-04-05 16:47:47 -0700237 // Drive and intake the ball nearest to the starting zone.
238 // Fire while moving.
Henry Speiser09e8da92022-03-14 20:58:45 -0700239 ExtendBackIntake();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800240 if (!splines[0].WaitForPlan()) return;
241 splines[0].Start();
Henry Speisere23d4de2022-04-05 16:47:47 -0700242 // Distance before we don't shoot while moving.
Austin Schuh9651c5a2022-04-17 19:12:42 -0700243 if (!splines[0].WaitForSplineDistanceRemaining(2.1)) return;
244 LOG(INFO) << "Tring to take the shot";
Milind Upadhyaya7793962022-03-11 19:39:36 -0800245
Milind Upadhyaya7793962022-03-11 19:39:36 -0800246 set_fire_at_will(true);
247 SendSuperstructureGoal();
Henry Speisere23d4de2022-04-05 16:47:47 -0700248
249 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
250
Austin Schuh9651c5a2022-04-17 19:12:42 -0700251 std::this_thread::sleep_for(std::chrono::milliseconds(500));
Henry Speisere23d4de2022-04-05 16:47:47 -0700252
253 // Fire the last ball we picked up when stopped.
254 SendSuperstructureGoal();
255 LOG(INFO) << "Close";
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700256 if (!WaitForBallsShot()) return;
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700257 LOG(INFO) << "Shot first 3 balls "
258 << chrono::duration<double>(aos::monotonic_clock::now() -
259 start_time)
260 .count()
261 << 's';
Milind Upadhyaya7793962022-03-11 19:39:36 -0800262
263 // Drive to the human player station while intaking two balls.
264 // Once is already placed down,
265 // and one will be rolled to the robot by the human player
Henry Speiser09e8da92022-03-14 20:58:45 -0700266 if (!splines[1].WaitForPlan()) return;
267 splines[1].Start();
Henry Speisere23d4de2022-04-05 16:47:47 -0700268
269 std::this_thread::sleep_for(std::chrono::milliseconds(1500));
270
271 set_fire_at_will(false);
272 SendSuperstructureGoal();
273
Henry Speiser09e8da92022-03-14 20:58:45 -0700274 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
Henry Speisere23d4de2022-04-05 16:47:47 -0700275 std::this_thread::sleep_for(std::chrono::milliseconds(500));
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700276 LOG(INFO) << "At balls 4/5 "
277 << chrono::duration<double>(aos::monotonic_clock::now() -
278 start_time)
279 .count()
280 << 's';
Milind Upadhyaya7793962022-03-11 19:39:36 -0800281
282 // Drive to the shooting position
Henry Speiser09e8da92022-03-14 20:58:45 -0700283 if (!splines[2].WaitForPlan()) return;
284 splines[2].Start();
285 if (!splines[2].WaitForSplineDistanceRemaining(2.00)) return;
286 RetractFrontIntake();
287
288 if (!splines[2].WaitForSplineDistanceRemaining(0.02)) return;
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700289 LOG(INFO) << "Shooting last balls "
290 << chrono::duration<double>(aos::monotonic_clock::now() -
291 start_time)
292 .count()
293 << 's';
Milind Upadhyaya7793962022-03-11 19:39:36 -0800294
295 // Fire the two balls once we stopped
296 set_fire_at_will(true);
297 SendSuperstructureGoal();
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700298 if (!WaitForBallsShot()) return;
Milind Upadhyaya7793962022-03-11 19:39:36 -0800299
300 LOG(INFO) << "Took "
301 << chrono::duration<double>(aos::monotonic_clock::now() -
302 start_time)
303 .count()
304 << 's';
Austin Schuh9651c5a2022-04-17 19:12:42 -0700305 std::this_thread::sleep_for(std::chrono::milliseconds(500));
306 set_fire_at_will(false);
307 SendSuperstructureGoal();
Milind Upadhyaya7793962022-03-11 19:39:36 -0800308}
309
Henry Speiser5eed1de2022-04-07 21:52:10 -0700310// Rapid React Two Ball Autonomous.
311void AutonomousActor::RapidReactTwo() {
312 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
313
314 CHECK(rapid_react_two_spline_);
315
316 auto &splines = *rapid_react_two_spline_;
317
318 // Tell the superstructure a ball was preloaded
319 if (!WaitForPreloaded()) return;
320 set_fire_at_will(true);
321 SendSuperstructureGoal();
322 if (!WaitForBallsShot()) return;
323 LOG(INFO) << "Shot first ball "
324 << chrono::duration<double>(aos::monotonic_clock::now() -
325 start_time)
326 .count()
327 << 's';
328 set_fire_at_will(false);
329 SendSuperstructureGoal();
330
331 ExtendBackIntake();
332 if (!splines[0].WaitForPlan()) return;
333 splines[0].Start();
334 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
335
Austin Schuhf3413b72022-04-16 19:09:33 -0700336 std::this_thread::sleep_for(std::chrono::milliseconds(300));
337
338 if (!splines[1].WaitForPlan()) return;
339 splines[1].Start();
340 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
341 std::this_thread::sleep_for(std::chrono::milliseconds(500));
342
Henry Speiser5eed1de2022-04-07 21:52:10 -0700343 // Fire the ball once we stopped
Henry Speiser5eed1de2022-04-07 21:52:10 -0700344 set_fire_at_will(true);
345 SendSuperstructureGoal();
346 if (!WaitForBallsShot()) return;
347 LOG(INFO) << "Shot last ball "
348 << chrono::duration<double>(aos::monotonic_clock::now() -
349 start_time)
350 .count()
351 << 's';
352 set_fire_at_will(false);
Austin Schuhf3413b72022-04-16 19:09:33 -0700353 RetractBackIntake();
Henry Speiser5eed1de2022-04-07 21:52:10 -0700354 SendSuperstructureGoal();
355}
356
Milind Upadhyaya7793962022-03-11 19:39:36 -0800357[[nodiscard]] bool AutonomousActor::WaitForPreloaded() {
Milind Upadhyay803bbf02022-03-11 17:56:26 -0800358 set_preloaded(true);
359 SendSuperstructureGoal();
360
361 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
362 event_loop()->monotonic_now(),
363 ActorBase::kLoopOffset);
364
365 bool loaded = false;
366 while (!loaded) {
367 if (ShouldCancel()) {
368 return false;
369 }
370
371 phased_loop.SleepUntilNext();
372 superstructure_status_fetcher_.Fetch();
373 CHECK(superstructure_status_fetcher_.get() != nullptr);
374
375 loaded = (superstructure_status_fetcher_->state() ==
376 control_loops::superstructure::SuperstructureState::LOADED);
377 }
378
379 set_preloaded(false);
380 SendSuperstructureGoal();
381
382 return true;
383}
384
Ravago Jones81e50632022-03-11 16:23:51 -0800385void AutonomousActor::SendSuperstructureGoal() {
386 auto builder = superstructure_goal_sender_.MakeBuilder();
387
388 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
389 intake_front_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
390 *builder.fbb(), intake_front_goal_,
391 CreateProfileParameters(*builder.fbb(), 20.0, 60.0));
392
393 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
394 intake_back_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
395 *builder.fbb(), intake_back_goal_,
396 CreateProfileParameters(*builder.fbb(), 20.0, 60.0));
397
398 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
399 catapult_return_position_offset =
400 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
401 *builder.fbb(), kCatapultReturnPosition,
402 CreateProfileParameters(*builder.fbb(), 9.0, 50.0));
403
404 superstructure::CatapultGoal::Builder catapult_goal_builder(*builder.fbb());
405 catapult_goal_builder.add_shot_position(0.03);
406 catapult_goal_builder.add_shot_velocity(18.0);
407 catapult_goal_builder.add_return_position(catapult_return_position_offset);
408 flatbuffers::Offset<superstructure::CatapultGoal> catapult_goal_offset =
409 catapult_goal_builder.Finish();
410
411 superstructure::Goal::Builder superstructure_builder =
412 builder.MakeBuilder<superstructure::Goal>();
413
414 superstructure_builder.add_intake_front(intake_front_offset);
415 superstructure_builder.add_intake_back(intake_back_offset);
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700416 superstructure_builder.add_roller_speed_compensation(0.0);
Ravago Jones81e50632022-03-11 16:23:51 -0800417 superstructure_builder.add_roller_speed_front(roller_front_voltage_);
418 superstructure_builder.add_roller_speed_back(roller_back_voltage_);
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700419 if (requested_intake_.has_value()) {
420 superstructure_builder.add_turret_intake(*requested_intake_);
421 }
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700422 superstructure_builder.add_transfer_roller_speed(transfer_roller_voltage_);
Ravago Jones81e50632022-03-11 16:23:51 -0800423 superstructure_builder.add_catapult(catapult_goal_offset);
424 superstructure_builder.add_fire(fire_);
Milind Upadhyay803bbf02022-03-11 17:56:26 -0800425 superstructure_builder.add_preloaded(preloaded_);
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700426 superstructure_builder.add_auto_aim(true);
Ravago Jones81e50632022-03-11 16:23:51 -0800427
428 if (builder.Send(superstructure_builder.Finish()) !=
429 aos::RawSender::Error::kOk) {
430 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
431 }
432}
433
434void AutonomousActor::ExtendFrontIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700435 set_requested_intake(RequestedIntake::kFront);
Ravago Jones81e50632022-03-11 16:23:51 -0800436 set_intake_front_goal(kExtendIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700437 set_roller_front_voltage(kIntakeRollerVoltage);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700438 set_transfer_roller_voltage(kRollerVoltage);
Ravago Jones81e50632022-03-11 16:23:51 -0800439 SendSuperstructureGoal();
440}
441
442void AutonomousActor::RetractFrontIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700443 set_requested_intake(std::nullopt);
Ravago Jones81e50632022-03-11 16:23:51 -0800444 set_intake_front_goal(kRetractIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700445 set_roller_front_voltage(0.0);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700446 set_transfer_roller_voltage(0.0);
Ravago Jones81e50632022-03-11 16:23:51 -0800447 SendSuperstructureGoal();
448}
449
450void AutonomousActor::ExtendBackIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700451 set_requested_intake(RequestedIntake::kBack);
Ravago Jones81e50632022-03-11 16:23:51 -0800452 set_intake_back_goal(kExtendIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700453 set_roller_back_voltage(kIntakeRollerVoltage);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700454 set_transfer_roller_voltage(-kRollerVoltage);
Ravago Jones81e50632022-03-11 16:23:51 -0800455 SendSuperstructureGoal();
456}
457
458void AutonomousActor::RetractBackIntake() {
Milind Upadhyayd86b02c2022-03-13 20:57:46 -0700459 set_requested_intake(std::nullopt);
Ravago Jones81e50632022-03-11 16:23:51 -0800460 set_intake_back_goal(kRetractIntakeGoal);
Austin Schuhe1264372022-03-13 20:22:36 -0700461 set_roller_back_voltage(0.0);
Milind Upadhyay29dcc172022-04-02 19:21:30 -0700462 set_transfer_roller_voltage(0.0);
Ravago Jones81e50632022-03-11 16:23:51 -0800463 SendSuperstructureGoal();
464}
465
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700466[[nodiscard]] bool AutonomousActor::WaitForBallsShot() {
Austin Schuh42d7e5f2022-03-16 23:35:09 -0700467 superstructure_status_fetcher_.Fetch();
468 CHECK(superstructure_status_fetcher_.get());
Milind Upadhyayf35bb112022-03-16 23:08:04 -0700469
Ravago Jonesf699d1c2022-03-11 18:39:56 -0800470 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
471 event_loop()->monotonic_now(),
472 ActorBase::kLoopOffset);
473 superstructure_status_fetcher_.Fetch();
474 CHECK(superstructure_status_fetcher_.get() != nullptr);
Henry Speisere23d4de2022-04-05 16:47:47 -0700475
Ravago Jonesf699d1c2022-03-11 18:39:56 -0800476 while (true) {
477 if (ShouldCancel()) {
478 return false;
479 }
480 phased_loop.SleepUntilNext();
481 superstructure_status_fetcher_.Fetch();
482 CHECK(superstructure_status_fetcher_.get() != nullptr);
Henry Speisere23d4de2022-04-05 16:47:47 -0700483
484 if (!superstructure_status_fetcher_->front_intake_has_ball() &&
485 !superstructure_status_fetcher_->back_intake_has_ball() &&
486 superstructure_status_fetcher_->state() ==
487 control_loops::superstructure::SuperstructureState::IDLE) {
Ravago Jonesf699d1c2022-03-11 18:39:56 -0800488 return true;
489 }
490 }
491}
492
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800493} // namespace y2022::actors