blob: 02d68da351a9531b2499a6c782347d8e01c3cf2d [file] [log] [blame]
Stephan Massaltd021f972020-01-05 20:41:23 -08001#include "y2020/actors/autonomous_actor.h"
2
Stephan Massaltd021f972020-01-05 20:41:23 -08003#include <chrono>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07004#include <cinttypes>
Stephan Massaltd021f972020-01-05 20:41:23 -08005#include <cmath>
6
7#include "aos/logging/logging.h"
James Kuszmaulddd2ba62020-03-08 22:17:13 -07008#include "aos/util/math.h"
Stephan Massaltd021f972020-01-05 20:41:23 -08009#include "frc971/control_loops/drivetrain/localizer_generated.h"
James Kuszmaul5f6d1d42020-03-01 18:10:07 -080010#include "y2020/actors/auto_splines.h"
Ravago Jonesc2a08022021-02-06 17:40:54 -080011#include "y2020/control_loops/drivetrain/drivetrain_base.h"
Stephan Massaltd021f972020-01-05 20:41:23 -080012
Austin Schuh3fb9e422021-03-31 20:11:32 -070013DEFINE_bool(spline_auto, false, "If true, define a spline autonomous mode");
Ravago Jones8c5737e2021-10-16 15:36:12 -070014DEFINE_bool(target_aligned, false,
Ravago Jonesa7b3c822021-08-26 12:36:03 -070015 "If true, run the Infinite Recharge autonomous that starts aligned "
16 "with the target");
Ravago Jones8c5737e2021-10-16 15:36:12 -070017DEFINE_bool(target_offset, false,
Ravago Jonesa7b3c822021-08-26 12:36:03 -070018 "If true, run the Infinite Recharge autonomous that starts offset "
19 "from the target");
20DEFINE_bool(just_shoot, false,
21 "If true, run the autonomous that just shoots balls.");
milind upadhyay47a0ab32020-11-25 19:34:41 -080022
Stephan Massaltd021f972020-01-05 20:41:23 -080023namespace y2020 {
24namespace actors {
25
26using ::aos::monotonic_clock;
27using ::frc971::ProfileParametersT;
28using frc971::control_loops::drivetrain::LocalizerControl;
29namespace chrono = ::std::chrono;
30
31AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
32 : frc971::autonomous::BaseAutonomousActor(
James Kuszmaul5f6d1d42020-03-01 18:10:07 -080033 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
Ravago Jonesc2a08022021-02-06 17:40:54 -080034 localizer_control_sender_(
35 event_loop->MakeSender<
36 ::frc971::control_loops::drivetrain::LocalizerControl>(
37 "/drivetrain")),
Austin Schuh67e127e2021-03-27 13:25:23 -070038 superstructure_goal_sender_(
39 event_loop->MakeSender<control_loops::superstructure::Goal>(
40 "/superstructure")),
James Kuszmaulddd2ba62020-03-08 22:17:13 -070041 joystick_state_fetcher_(
Ravago Jonesc2a08022021-02-06 17:40:54 -080042 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
Ravago Jones1f32d622021-08-26 12:20:36 -070043 superstructure_status_fetcher_(
44 event_loop->MakeFetcher<y2020::control_loops::superstructure::Status>(
45 "/superstructure")),
Ravago Jonesc2a08022021-02-06 17:40:54 -080046 auto_splines_() {
milind upadhyay47a0ab32020-11-25 19:34:41 -080047 set_max_drivetrain_voltage(2.0);
James Kuszmaul99af8b52021-03-28 10:50:15 -070048 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
49 event_loop->OnRun([this, event_loop]() {
50 replan_timer_->Setup(event_loop->monotonic_now());
51 });
James Kuszmaul4303a5d2021-10-23 19:58:48 -070052 event_loop->MakeWatcher("/aos", [this](const aos::RobotState &msg) {
53 if (msg.user_button()) {
54 user_indicated_safe_to_reset_ = true;
55 MaybeSendStartingPosition();
56 }
57 });
58 event_loop->MakeWatcher("/aos", [this](const aos::JoystickState &msg) {
59 if (msg.has_alliance() && (msg.alliance() != alliance_)) {
60 alliance_ = msg.alliance();
61 Replan();
62 }
63 });
64}
65
66void AutonomousActor::MaybeSendStartingPosition() {
67 if (user_indicated_safe_to_reset_ && !sent_starting_position_) {
68 CHECK(starting_position_);
69 SendStartingPosition(starting_position_.value());
70 }
James Kuszmaul99af8b52021-03-28 10:50:15 -070071}
72
73void AutonomousActor::Replan() {
James Kuszmaul4303a5d2021-10-23 19:58:48 -070074 sent_starting_position_ = false;
Ravago Jones8c5737e2021-10-16 15:36:12 -070075 if (FLAGS_spline_auto) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -070076 test_spline_ = PlanSpline(std::bind(&AutonomousSplines::TestSpline,
77 &auto_splines_, std::placeholders::_1),
78 SplineDirection::kForward);
James Kuszmaul4303a5d2021-10-23 19:58:48 -070079 starting_position_ = test_spline_->starting_position();
Ravago Jones8c5737e2021-10-16 15:36:12 -070080 } else if (FLAGS_target_offset) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -070081 target_offset_splines_ = {
82 PlanSpline(std::bind(&AutonomousSplines::TargetOffset1, &auto_splines_,
83 std::placeholders::_1),
84 SplineDirection::kForward),
85 PlanSpline(std::bind(&AutonomousSplines::TargetOffset2, &auto_splines_,
86 std::placeholders::_1),
87 SplineDirection::kBackward)};
James Kuszmaul4303a5d2021-10-23 19:58:48 -070088 starting_position_ = target_offset_splines_.value()[0].starting_position();
Ravago Jones8c5737e2021-10-16 15:36:12 -070089 } else if (FLAGS_target_aligned) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -070090 target_aligned_splines_ = {
91 PlanSpline(std::bind(&AutonomousSplines::TargetAligned1, &auto_splines_,
92 std::placeholders::_1),
93 SplineDirection::kForward),
94 PlanSpline(std::bind(&AutonomousSplines::TargetAligned2, &auto_splines_,
95 std::placeholders::_1),
96 SplineDirection::kBackward)};
James Kuszmaul4303a5d2021-10-23 19:58:48 -070097 starting_position_ = target_aligned_splines_.value()[0].starting_position();
98 } else {
99 starting_position_ = Eigen::Vector3d::Zero();
James Kuszmaul99af8b52021-03-28 10:50:15 -0700100 }
James Kuszmaul4303a5d2021-10-23 19:58:48 -0700101 MaybeSendStartingPosition();
milind upadhyay47a0ab32020-11-25 19:34:41 -0800102}
Stephan Massaltd021f972020-01-05 20:41:23 -0800103
104void AutonomousActor::Reset() {
105 InitializeEncoders();
106 ResetDrivetrain();
milind upadhyayb2e840a2021-03-27 13:54:49 -0700107 RetractIntake();
James Kuszmaul5f6d1d42020-03-01 18:10:07 -0800108
James Kuszmaulddd2ba62020-03-08 22:17:13 -0700109 joystick_state_fetcher_.Fetch();
110 CHECK(joystick_state_fetcher_.get() != nullptr)
111 << "Expect at least one JoystickState message before running auto...";
112 alliance_ = joystick_state_fetcher_->alliance();
Stephan Massaltd021f972020-01-05 20:41:23 -0800113}
114
115bool AutonomousActor::RunAction(
Austin Schuh6fb0a6d2021-01-23 15:43:17 -0800116 const ::frc971::autonomous::AutonomousActionParams *params) {
Stephan Massaltd021f972020-01-05 20:41:23 -0800117 Reset();
James Kuszmaul4303a5d2021-10-23 19:58:48 -0700118 if (!user_indicated_safe_to_reset_) {
119 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
120 SendStartingPosition(starting_position_.value());
121 }
James Kuszmaul99af8b52021-03-28 10:50:15 -0700122
123 // Queue up a replan to occur as soon as this action completes.
124 // TODO(james): Modify this so we don't replan during teleop.
125 replan_timer_->Setup(monotonic_now());
126
milind upadhyay47a0ab32020-11-25 19:34:41 -0800127 AOS_LOG(INFO, "Params are %d\n", params->mode());
James Kuszmaulddd2ba62020-03-08 22:17:13 -0700128 if (alliance_ == aos::Alliance::kInvalid) {
129 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
130 return false;
131 }
Ravago Jones8c5737e2021-10-16 15:36:12 -0700132 if (FLAGS_target_aligned) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700133 TargetAligned();
Ravago Jones8c5737e2021-10-16 15:36:12 -0700134 } else if (FLAGS_target_offset) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700135 TargetOffset();
136 } else if (FLAGS_just_shoot) {
137 JustShoot();
kyle96c406e2021-02-27 14:07:22 -0800138 } else if (FLAGS_spline_auto) {
milind upadhyay47a0ab32020-11-25 19:34:41 -0800139 SplineAuto();
140 } else {
141 return DriveFwd();
142 }
143 return true;
144}
Stephan Massaltd021f972020-01-05 20:41:23 -0800145
James Kuszmaul99af8b52021-03-28 10:50:15 -0700146void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
kyle96c406e2021-02-27 14:07:22 -0800147 // Set up the starting position for the blue alliance.
kyle96c406e2021-02-27 14:07:22 -0800148
149 // TODO(james): Resetting the localizer breaks the left/right statespace
150 // controller. That is a bug, but we can fix that later by not resetting.
151 auto builder = localizer_control_sender_.MakeBuilder();
152
153 LocalizerControl::Builder localizer_control_builder =
154 builder.MakeBuilder<LocalizerControl>();
James Kuszmaul99af8b52021-03-28 10:50:15 -0700155 localizer_control_builder.add_x(start(0));
156 localizer_control_builder.add_y(start(1));
157 localizer_control_builder.add_theta(start(2));
kyle96c406e2021-02-27 14:07:22 -0800158 localizer_control_builder.add_theta_uncertainty(0.00001);
159 if (!builder.Send(localizer_control_builder.Finish())) {
160 AOS_LOG(ERROR, "Failed to reset localizer.\n");
161 }
162}
163
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700164void AutonomousActor::TargetAligned() {
165 CHECK(target_aligned_splines_);
166 auto &splines = *target_aligned_splines_;
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700167
168 // shoot pre-loaded balls
169 set_shooter_tracking(true);
170 set_shooting(true);
171 SendSuperstructureGoal();
172
173 if (!WaitForBallsShot(3)) return;
174
175 set_shooting(false);
176 SendSuperstructureGoal();
177
178 ExtendIntake();
179
180 // pickup 3 more balls
181 if (!splines[0].WaitForPlan()) return;
182 splines[0].Start();
183
184 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
185 RetractIntake();
186
187 if (!splines[1].WaitForPlan()) return;
188 splines[1].Start();
189
190 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
191
192 // shoot the new balls in front of the goal.
193 set_shooting(true);
194 SendSuperstructureGoal();
195
196 if (!WaitForBallsShot(3)) return;
197
198 set_shooting(false);
199 set_shooter_tracking(false);
200 SendSuperstructureGoal();
201}
202
203void AutonomousActor::JustShoot() {
204 // shoot pre-loaded balls
205 set_shooter_tracking(true);
206 set_shooting(true);
207 SendSuperstructureGoal();
208
209 if (!WaitForBallsShot(3)) return;
210
211 set_shooting(false);
212 set_shooter_tracking(true);
213 SendSuperstructureGoal();
214}
215
216void AutonomousActor::TargetOffset() {
217 CHECK(target_offset_splines_);
218 auto &splines = *target_offset_splines_;
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700219
220 // spin up shooter
221 set_shooter_tracking(true);
222 SendSuperstructureGoal();
223 ExtendIntake();
224
225 // pickup 2 more balls in front of the trench run
226 if (!splines[0].WaitForPlan()) return;
227 splines[0].Start();
228
229 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
230 RetractIntake();
231
232 if (!splines[1].WaitForPlan()) return;
233 splines[1].Start();
234
235 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
236
237 // shoot the balls from in front of the goal.
238 set_shooting(true);
239 SendSuperstructureGoal();
240
241 if (!WaitForBallsShot(5)) return;
242
243 set_shooting(false);
244 set_shooter_tracking(false);
245 SendSuperstructureGoal();
246}
247
milind upadhyay47a0ab32020-11-25 19:34:41 -0800248void AutonomousActor::SplineAuto() {
James Kuszmaul99af8b52021-03-28 10:50:15 -0700249 CHECK(test_spline_);
James Kuszmaul5f6d1d42020-03-01 18:10:07 -0800250
James Kuszmaul99af8b52021-03-28 10:50:15 -0700251 if (!test_spline_->WaitForPlan()) return;
252 test_spline_->Start();
Stephan Massaltd021f972020-01-05 20:41:23 -0800253
James Kuszmaul99af8b52021-03-28 10:50:15 -0700254 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
kyle96c406e2021-02-27 14:07:22 -0800255}
256
milind upadhyay47a0ab32020-11-25 19:34:41 -0800257ProfileParametersT MakeProfileParametersT(const float max_velocity,
258 const float max_acceleration) {
259 ProfileParametersT params;
260 params.max_velocity = max_velocity;
261 params.max_acceleration = max_acceleration;
262 return params;
263}
264
265bool AutonomousActor::DriveFwd() {
Austin Schuhfd1715f2021-01-30 16:58:24 -0800266 const ProfileParametersT kDrive = MakeProfileParametersT(0.3f, 1.0f);
milind upadhyay47a0ab32020-11-25 19:34:41 -0800267 const ProfileParametersT kTurn = MakeProfileParametersT(5.0f, 15.0f);
Austin Schuhfd1715f2021-01-30 16:58:24 -0800268 StartDrive(1.0, 0.0, kDrive, kTurn);
milind upadhyay47a0ab32020-11-25 19:34:41 -0800269 return WaitForDriveDone();
270}
Sabina Leavera0b43b42021-03-03 20:30:04 -0800271
272void AutonomousActor::SendSuperstructureGoal() {
Sabina Leavera0b43b42021-03-03 20:30:04 -0800273 auto builder = superstructure_goal_sender_.MakeBuilder();
274
275 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
276 intake_offset;
milind upadhyayb9dec712021-03-20 15:47:51 -0700277
Sabina Leavera0b43b42021-03-03 20:30:04 -0800278 {
279 StaticZeroingSingleDOFProfiledSubsystemGoal::Builder intake_builder =
280 builder.MakeBuilder<StaticZeroingSingleDOFProfiledSubsystemGoal>();
281
milind upadhyayb9dec712021-03-20 15:47:51 -0700282 frc971::ProfileParameters::Builder profile_params_builder =
Sabina Leavera0b43b42021-03-03 20:30:04 -0800283 builder.MakeBuilder<frc971::ProfileParameters>();
Austin Schuhb39a21c2021-03-31 20:12:18 -0700284 profile_params_builder.add_max_velocity(20.0);
285 profile_params_builder.add_max_acceleration(60.0);
milind upadhyayb9dec712021-03-20 15:47:51 -0700286 flatbuffers::Offset<frc971::ProfileParameters> profile_params_offset =
Sabina Leavera0b43b42021-03-03 20:30:04 -0800287 profile_params_builder.Finish();
288 intake_builder.add_unsafe_goal(intake_goal_);
289 intake_builder.add_profile_params(profile_params_offset);
290 intake_offset = intake_builder.Finish();
291 }
292
293 superstructure::Goal::Builder superstructure_builder =
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700294 builder.MakeBuilder<superstructure::Goal>();
milind upadhyayb9dec712021-03-20 15:47:51 -0700295
Sabina Leavera0b43b42021-03-03 20:30:04 -0800296 superstructure_builder.add_intake(intake_offset);
Ravago Jonesf8b7bfe2021-10-09 16:25:29 -0700297 superstructure_builder.add_intake_preloading(intake_preloading_);
Sabina Leavera0b43b42021-03-03 20:30:04 -0800298 superstructure_builder.add_roller_voltage(roller_voltage_);
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700299 superstructure_builder.add_roller_speed_compensation(
300 kRollerSpeedCompensation);
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700301 superstructure_builder.add_hood_tracking(shooter_tracking_);
302 superstructure_builder.add_turret_tracking(shooter_tracking_);
303 superstructure_builder.add_shooter_tracking(shooter_tracking_);
304 superstructure_builder.add_shooting(shooting_);
Sabina Leavera0b43b42021-03-03 20:30:04 -0800305
306 if (!builder.Send(superstructure_builder.Finish())) {
307 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
308 }
Sabina Leavera0b43b42021-03-03 20:30:04 -0800309}
milind upadhyay5e589d72021-03-27 13:47:18 -0700310
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700311void AutonomousActor::ExtendIntake() {
312 set_intake_goal(1.25);
313 set_roller_voltage(12.0);
314 set_intake_preloading(true);
315 SendSuperstructureGoal();
316}
317
milind upadhyay5e589d72021-03-27 13:47:18 -0700318void AutonomousActor::RetractIntake() {
319 set_intake_goal(-0.89);
320 set_roller_voltage(0.0);
Ravago Jonesf8b7bfe2021-10-09 16:25:29 -0700321 set_intake_preloading(false);
milind upadhyay5e589d72021-03-27 13:47:18 -0700322 SendSuperstructureGoal();
323}
324
Ravago Jones1f32d622021-08-26 12:20:36 -0700325bool AutonomousActor::WaitForBallsShot(int num_wanted) {
326 superstructure_status_fetcher_.Fetch();
327 CHECK(superstructure_status_fetcher_.get() != nullptr);
328 const int initial_balls_shot =
329 superstructure_status_fetcher_->shooter()->balls_shot();
330 int balls_shot = initial_balls_shot;
331
332 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
333 event_loop()->monotonic_now(),
334 frc971::controls::kLoopFrequency / 2);
335 while (true) {
336 if (ShouldCancel()) {
337 return false;
338 }
339 phased_loop.SleepUntilNext();
340 superstructure_status_fetcher_.Fetch();
341 balls_shot = superstructure_status_fetcher_->shooter()->balls_shot();
342 if ((balls_shot - initial_balls_shot) >= num_wanted) {
343 return true;
344 }
345 }
346}
347
Stephan Massaltd021f972020-01-05 20:41:23 -0800348} // namespace actors
349} // namespace y2020