blob: fc4257019518b1d81c4dd2e8264cbf1b54c8c1e9 [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 });
52}
53
54void AutonomousActor::Replan() {
Ravago Jones8c5737e2021-10-16 15:36:12 -070055 if (FLAGS_spline_auto) {
Tyler Chatowbf0609c2021-07-31 16:13:27 -070056 test_spline_ = PlanSpline(std::bind(&AutonomousSplines::TestSpline,
57 &auto_splines_, std::placeholders::_1),
58 SplineDirection::kForward);
Ravago Jones8c5737e2021-10-16 15:36:12 -070059 } else if (FLAGS_target_offset) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -070060 target_offset_splines_ = {
61 PlanSpline(std::bind(&AutonomousSplines::TargetOffset1, &auto_splines_,
62 std::placeholders::_1),
63 SplineDirection::kForward),
64 PlanSpline(std::bind(&AutonomousSplines::TargetOffset2, &auto_splines_,
65 std::placeholders::_1),
66 SplineDirection::kBackward)};
Ravago Jones8c5737e2021-10-16 15:36:12 -070067 } else if (FLAGS_target_aligned) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -070068 target_aligned_splines_ = {
69 PlanSpline(std::bind(&AutonomousSplines::TargetAligned1, &auto_splines_,
70 std::placeholders::_1),
71 SplineDirection::kForward),
72 PlanSpline(std::bind(&AutonomousSplines::TargetAligned2, &auto_splines_,
73 std::placeholders::_1),
74 SplineDirection::kBackward)};
James Kuszmaul99af8b52021-03-28 10:50:15 -070075 }
milind upadhyay47a0ab32020-11-25 19:34:41 -080076}
Stephan Massaltd021f972020-01-05 20:41:23 -080077
78void AutonomousActor::Reset() {
79 InitializeEncoders();
80 ResetDrivetrain();
milind upadhyayb2e840a2021-03-27 13:54:49 -070081 RetractIntake();
James Kuszmaul5f6d1d42020-03-01 18:10:07 -080082
James Kuszmaulddd2ba62020-03-08 22:17:13 -070083 joystick_state_fetcher_.Fetch();
84 CHECK(joystick_state_fetcher_.get() != nullptr)
85 << "Expect at least one JoystickState message before running auto...";
86 alliance_ = joystick_state_fetcher_->alliance();
Stephan Massaltd021f972020-01-05 20:41:23 -080087}
88
89bool AutonomousActor::RunAction(
Austin Schuh6fb0a6d2021-01-23 15:43:17 -080090 const ::frc971::autonomous::AutonomousActionParams *params) {
Stephan Massaltd021f972020-01-05 20:41:23 -080091 Reset();
James Kuszmaul99af8b52021-03-28 10:50:15 -070092
93 // Queue up a replan to occur as soon as this action completes.
94 // TODO(james): Modify this so we don't replan during teleop.
95 replan_timer_->Setup(monotonic_now());
96
milind upadhyay47a0ab32020-11-25 19:34:41 -080097 AOS_LOG(INFO, "Params are %d\n", params->mode());
James Kuszmaulddd2ba62020-03-08 22:17:13 -070098 if (alliance_ == aos::Alliance::kInvalid) {
99 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
100 return false;
101 }
Ravago Jones8c5737e2021-10-16 15:36:12 -0700102 if (FLAGS_target_aligned) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700103 TargetAligned();
Ravago Jones8c5737e2021-10-16 15:36:12 -0700104 } else if (FLAGS_target_offset) {
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700105 TargetOffset();
106 } else if (FLAGS_just_shoot) {
107 JustShoot();
kyle96c406e2021-02-27 14:07:22 -0800108 } else if (FLAGS_spline_auto) {
milind upadhyay47a0ab32020-11-25 19:34:41 -0800109 SplineAuto();
110 } else {
111 return DriveFwd();
112 }
113 return true;
114}
Stephan Massaltd021f972020-01-05 20:41:23 -0800115
James Kuszmaul99af8b52021-03-28 10:50:15 -0700116void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
kyle96c406e2021-02-27 14:07:22 -0800117 // Set up the starting position for the blue alliance.
kyle96c406e2021-02-27 14:07:22 -0800118
119 // TODO(james): Resetting the localizer breaks the left/right statespace
120 // controller. That is a bug, but we can fix that later by not resetting.
121 auto builder = localizer_control_sender_.MakeBuilder();
122
123 LocalizerControl::Builder localizer_control_builder =
124 builder.MakeBuilder<LocalizerControl>();
James Kuszmaul99af8b52021-03-28 10:50:15 -0700125 localizer_control_builder.add_x(start(0));
126 localizer_control_builder.add_y(start(1));
127 localizer_control_builder.add_theta(start(2));
kyle96c406e2021-02-27 14:07:22 -0800128 localizer_control_builder.add_theta_uncertainty(0.00001);
129 if (!builder.Send(localizer_control_builder.Finish())) {
130 AOS_LOG(ERROR, "Failed to reset localizer.\n");
131 }
132}
133
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700134void AutonomousActor::TargetAligned() {
135 CHECK(target_aligned_splines_);
136 auto &splines = *target_aligned_splines_;
137 SendStartingPosition(splines[0].starting_position());
138
139 // shoot pre-loaded balls
140 set_shooter_tracking(true);
141 set_shooting(true);
142 SendSuperstructureGoal();
143
144 if (!WaitForBallsShot(3)) return;
145
146 set_shooting(false);
147 SendSuperstructureGoal();
148
149 ExtendIntake();
150
151 // pickup 3 more balls
152 if (!splines[0].WaitForPlan()) return;
153 splines[0].Start();
154
155 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
156 RetractIntake();
157
158 if (!splines[1].WaitForPlan()) return;
159 splines[1].Start();
160
161 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
162
163 // shoot the new balls in front of the goal.
164 set_shooting(true);
165 SendSuperstructureGoal();
166
167 if (!WaitForBallsShot(3)) return;
168
169 set_shooting(false);
170 set_shooter_tracking(false);
171 SendSuperstructureGoal();
172}
173
174void AutonomousActor::JustShoot() {
175 // shoot pre-loaded balls
176 set_shooter_tracking(true);
177 set_shooting(true);
178 SendSuperstructureGoal();
179
180 if (!WaitForBallsShot(3)) return;
181
182 set_shooting(false);
183 set_shooter_tracking(true);
184 SendSuperstructureGoal();
185}
186
187void AutonomousActor::TargetOffset() {
188 CHECK(target_offset_splines_);
189 auto &splines = *target_offset_splines_;
190 SendStartingPosition(splines[0].starting_position());
191
192 // spin up shooter
193 set_shooter_tracking(true);
194 SendSuperstructureGoal();
195 ExtendIntake();
196
197 // pickup 2 more balls in front of the trench run
198 if (!splines[0].WaitForPlan()) return;
199 splines[0].Start();
200
201 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
202 RetractIntake();
203
204 if (!splines[1].WaitForPlan()) return;
205 splines[1].Start();
206
207 if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
208
209 // shoot the balls from in front of the goal.
210 set_shooting(true);
211 SendSuperstructureGoal();
212
213 if (!WaitForBallsShot(5)) return;
214
215 set_shooting(false);
216 set_shooter_tracking(false);
217 SendSuperstructureGoal();
218}
219
milind upadhyay47a0ab32020-11-25 19:34:41 -0800220void AutonomousActor::SplineAuto() {
James Kuszmaul99af8b52021-03-28 10:50:15 -0700221 CHECK(test_spline_);
James Kuszmaul5f6d1d42020-03-01 18:10:07 -0800222
James Kuszmaul99af8b52021-03-28 10:50:15 -0700223 SendStartingPosition(test_spline_->starting_position());
James Kuszmaul5f6d1d42020-03-01 18:10:07 -0800224
James Kuszmaul99af8b52021-03-28 10:50:15 -0700225 if (!test_spline_->WaitForPlan()) return;
226 test_spline_->Start();
Stephan Massaltd021f972020-01-05 20:41:23 -0800227
James Kuszmaul99af8b52021-03-28 10:50:15 -0700228 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
kyle96c406e2021-02-27 14:07:22 -0800229}
230
milind upadhyay47a0ab32020-11-25 19:34:41 -0800231ProfileParametersT MakeProfileParametersT(const float max_velocity,
232 const float max_acceleration) {
233 ProfileParametersT params;
234 params.max_velocity = max_velocity;
235 params.max_acceleration = max_acceleration;
236 return params;
237}
238
239bool AutonomousActor::DriveFwd() {
James Kuszmaul99af8b52021-03-28 10:50:15 -0700240 SendStartingPosition({0, 0, 0});
Austin Schuhfd1715f2021-01-30 16:58:24 -0800241 const ProfileParametersT kDrive = MakeProfileParametersT(0.3f, 1.0f);
milind upadhyay47a0ab32020-11-25 19:34:41 -0800242 const ProfileParametersT kTurn = MakeProfileParametersT(5.0f, 15.0f);
Austin Schuhfd1715f2021-01-30 16:58:24 -0800243 StartDrive(1.0, 0.0, kDrive, kTurn);
milind upadhyay47a0ab32020-11-25 19:34:41 -0800244 return WaitForDriveDone();
245}
Sabina Leavera0b43b42021-03-03 20:30:04 -0800246
247void AutonomousActor::SendSuperstructureGoal() {
Sabina Leavera0b43b42021-03-03 20:30:04 -0800248 auto builder = superstructure_goal_sender_.MakeBuilder();
249
250 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
251 intake_offset;
milind upadhyayb9dec712021-03-20 15:47:51 -0700252
Sabina Leavera0b43b42021-03-03 20:30:04 -0800253 {
254 StaticZeroingSingleDOFProfiledSubsystemGoal::Builder intake_builder =
255 builder.MakeBuilder<StaticZeroingSingleDOFProfiledSubsystemGoal>();
256
milind upadhyayb9dec712021-03-20 15:47:51 -0700257 frc971::ProfileParameters::Builder profile_params_builder =
Sabina Leavera0b43b42021-03-03 20:30:04 -0800258 builder.MakeBuilder<frc971::ProfileParameters>();
Austin Schuhb39a21c2021-03-31 20:12:18 -0700259 profile_params_builder.add_max_velocity(20.0);
260 profile_params_builder.add_max_acceleration(60.0);
milind upadhyayb9dec712021-03-20 15:47:51 -0700261 flatbuffers::Offset<frc971::ProfileParameters> profile_params_offset =
Sabina Leavera0b43b42021-03-03 20:30:04 -0800262 profile_params_builder.Finish();
263 intake_builder.add_unsafe_goal(intake_goal_);
264 intake_builder.add_profile_params(profile_params_offset);
265 intake_offset = intake_builder.Finish();
266 }
267
268 superstructure::Goal::Builder superstructure_builder =
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700269 builder.MakeBuilder<superstructure::Goal>();
milind upadhyayb9dec712021-03-20 15:47:51 -0700270
Sabina Leavera0b43b42021-03-03 20:30:04 -0800271 superstructure_builder.add_intake(intake_offset);
Ravago Jonesf8b7bfe2021-10-09 16:25:29 -0700272 superstructure_builder.add_intake_preloading(intake_preloading_);
Sabina Leavera0b43b42021-03-03 20:30:04 -0800273 superstructure_builder.add_roller_voltage(roller_voltage_);
Tyler Chatowbf0609c2021-07-31 16:13:27 -0700274 superstructure_builder.add_roller_speed_compensation(
275 kRollerSpeedCompensation);
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700276 superstructure_builder.add_hood_tracking(shooter_tracking_);
277 superstructure_builder.add_turret_tracking(shooter_tracking_);
278 superstructure_builder.add_shooter_tracking(shooter_tracking_);
279 superstructure_builder.add_shooting(shooting_);
Sabina Leavera0b43b42021-03-03 20:30:04 -0800280
281 if (!builder.Send(superstructure_builder.Finish())) {
282 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
283 }
Sabina Leavera0b43b42021-03-03 20:30:04 -0800284}
milind upadhyay5e589d72021-03-27 13:47:18 -0700285
Ravago Jonesa7b3c822021-08-26 12:36:03 -0700286void AutonomousActor::ExtendIntake() {
287 set_intake_goal(1.25);
288 set_roller_voltage(12.0);
289 set_intake_preloading(true);
290 SendSuperstructureGoal();
291}
292
milind upadhyay5e589d72021-03-27 13:47:18 -0700293void AutonomousActor::RetractIntake() {
294 set_intake_goal(-0.89);
295 set_roller_voltage(0.0);
Ravago Jonesf8b7bfe2021-10-09 16:25:29 -0700296 set_intake_preloading(false);
milind upadhyay5e589d72021-03-27 13:47:18 -0700297 SendSuperstructureGoal();
298}
299
Ravago Jones1f32d622021-08-26 12:20:36 -0700300bool AutonomousActor::WaitForBallsShot(int num_wanted) {
301 superstructure_status_fetcher_.Fetch();
302 CHECK(superstructure_status_fetcher_.get() != nullptr);
303 const int initial_balls_shot =
304 superstructure_status_fetcher_->shooter()->balls_shot();
305 int balls_shot = initial_balls_shot;
306
307 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
308 event_loop()->monotonic_now(),
309 frc971::controls::kLoopFrequency / 2);
310 while (true) {
311 if (ShouldCancel()) {
312 return false;
313 }
314 phased_loop.SleepUntilNext();
315 superstructure_status_fetcher_.Fetch();
316 balls_shot = superstructure_status_fetcher_->shooter()->balls_shot();
317 if ((balls_shot - initial_balls_shot) >= num_wanted) {
318 return true;
319 }
320 }
321}
322
Stephan Massaltd021f972020-01-05 20:41:23 -0800323} // namespace actors
324} // namespace y2020