blob: ad8350ebc594497fad8703b233261450666411b7 [file] [log] [blame]
Austin Schuh80ff2e12014-03-08 12:06:19 -08001#include <stdio.h>
2
3#include <memory>
Austin Schuh47017412013-03-10 11:50:46 -07004
Brian3afd6fc2014-04-02 20:41:49 -07005#include "aos/common/util/phased_loop.h"
Austin Schuh47017412013-03-10 11:50:46 -07006#include "aos/common/time.h"
Austin Schuh6be011a2013-03-19 10:07:02 +00007#include "aos/common/util/trapezoid_profile.h"
Brian Silverman598800f2013-05-09 17:08:42 -07008#include "aos/common/logging/logging.h"
Brian Silverman96d9cea2013-11-12 21:10:50 -08009#include "aos/common/network/team_number.h"
Brian Silverman598800f2013-05-09 17:08:42 -070010
11#include "frc971/autonomous/auto.q.h"
Austin Schuh6be011a2013-03-19 10:07:02 +000012#include "frc971/constants.h"
13#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuh80ff2e12014-03-08 12:06:19 -080014#include "frc971/control_loops/shooter/shooter.q.h"
15#include "frc971/control_loops/claw/claw.q.h"
16#include "frc971/actions/action_client.h"
17#include "frc971/actions/shoot_action.h"
18#include "frc971/actions/drivetrain_action.h"
Austin Schuh47017412013-03-10 11:50:46 -070019
20using ::aos::time::Time;
21
22namespace frc971 {
23namespace autonomous {
24
Austin Schuh80ff2e12014-03-08 12:06:19 -080025namespace time = ::aos::time;
26
Brian Silverman3b89ed82013-03-22 18:59:16 -070027static double left_initial_position, right_initial_position;
28
Austin Schuh6be011a2013-03-19 10:07:02 +000029bool ShouldExitAuto() {
30 ::frc971::autonomous::autonomous.FetchLatest();
31 bool ans = !::frc971::autonomous::autonomous->run_auto;
32 if (ans) {
33 LOG(INFO, "Time to exit auto mode\n");
34 }
35 return ans;
36}
37
Austin Schuh6be011a2013-03-19 10:07:02 +000038void StopDrivetrain() {
39 LOG(INFO, "Stopping the drivetrain\n");
Austin Schuh47017412013-03-10 11:50:46 -070040 control_loops::drivetrain.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070041 .control_loop_driving(true)
Brian Silvermance86bac2013-03-31 19:07:24 -070042 .left_goal(left_initial_position)
43 .left_velocity_goal(0)
44 .right_goal(right_initial_position)
45 .right_velocity_goal(0)
46 .quickturn(false)
47 .Send();
48}
49
50void ResetDrivetrain() {
51 LOG(INFO, "resetting the drivetrain\n");
52 control_loops::drivetrain.goal.MakeWithBuilder()
53 .control_loop_driving(false)
Austin Schuh6be011a2013-03-19 10:07:02 +000054 .highgear(false)
55 .steering(0.0)
56 .throttle(0.0)
Austin Schuh6be011a2013-03-19 10:07:02 +000057 .Send();
58}
59
Brian Silverman3b89ed82013-03-22 18:59:16 -070060void DriveSpin(double radians) {
61 LOG(INFO, "going to spin %f\n", radians);
62
63 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
64 ::Eigen::Matrix<double, 2, 1> driveTrainState;
65 const double goal_velocity = 0.0;
66 const double epsilon = 0.01;
Brian Silverman13be6682013-03-22 21:02:07 -070067 // in drivetrain "meters"
Brian Silverman3b89ed82013-03-22 18:59:16 -070068 const double kRobotWidth = 0.4544;
69
Brian Silverman7992d6e2013-03-24 19:20:54 -070070 profile.set_maximum_acceleration(1.5);
71 profile.set_maximum_velocity(0.8);
Brian Silverman3b89ed82013-03-22 18:59:16 -070072
73 const double side_offset = kRobotWidth * radians / 2.0;
74
75 while (true) {
Brian Silverman7f09f972013-03-22 23:11:39 -070076 ::aos::time::PhasedLoop10MS(5000); // wait until next 10ms tick
Brian Silverman3b89ed82013-03-22 18:59:16 -070077 driveTrainState = profile.Update(side_offset, goal_velocity);
78
79 if (::std::abs(driveTrainState(0, 0) - side_offset) < epsilon) break;
80 if (ShouldExitAuto()) return;
81
82 LOG(DEBUG, "Driving left to %f, right to %f\n",
Brian Silverman7992d6e2013-03-24 19:20:54 -070083 left_initial_position - driveTrainState(0, 0),
84 right_initial_position + driveTrainState(0, 0));
Brian Silverman3b89ed82013-03-22 18:59:16 -070085 control_loops::drivetrain.goal.MakeWithBuilder()
86 .control_loop_driving(true)
87 .highgear(false)
Brian Silverman7992d6e2013-03-24 19:20:54 -070088 .left_goal(left_initial_position - driveTrainState(0, 0))
89 .right_goal(right_initial_position + driveTrainState(0, 0))
90 .left_velocity_goal(-driveTrainState(1, 0))
91 .right_velocity_goal(driveTrainState(1, 0))
Brian Silverman3b89ed82013-03-22 18:59:16 -070092 .Send();
93 }
Brian Silverman7992d6e2013-03-24 19:20:54 -070094 left_initial_position -= side_offset;
95 right_initial_position += side_offset;
Brian Silverman3b89ed82013-03-22 18:59:16 -070096 LOG(INFO, "Done moving\n");
97}
98
Austin Schuh80ff2e12014-03-08 12:06:19 -080099void PositionClawVertically(double intake_power = 0.0, double centering_power = 0.0) {
100 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
101 .bottom_angle(0.0)
102 .separation_angle(0.0)
103 .intake(intake_power)
104 .centering(centering_power)
105 .Send()) {
106 LOG(WARNING, "sending claw goal failed\n");
107 }
108}
Brian Silvermance86bac2013-03-31 19:07:24 -0700109
Austin Schuh80ff2e12014-03-08 12:06:19 -0800110void PositionClawBackIntake() {
111 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
112 .bottom_angle(-2.273474)
113 .separation_angle(0.0)
114 .intake(12.0)
115 .centering(12.0)
116 .Send()) {
117 LOG(WARNING, "sending claw goal failed\n");
118 }
119}
Brian Silvermance86bac2013-03-31 19:07:24 -0700120
Austin Schuh80ff2e12014-03-08 12:06:19 -0800121void PositionClawForShot() {
122 // Turn the claw on, keep it straight up until the ball has been grabbed.
123 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
Brian Silverman31b5b822014-03-14 18:50:39 -0700124 .bottom_angle(0.86)
Austin Schuha4faacc2014-03-09 00:50:50 -0800125 .separation_angle(0.10)
126 .intake(4.0)
Austin Schuh80ff2e12014-03-08 12:06:19 -0800127 .centering(1.0)
128 .Send()) {
129 LOG(WARNING, "sending claw goal failed\n");
130 }
131}
132
133void SetShotPower(double power) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800134 LOG(INFO, "Setting shot power to %f\n", power);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800135 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
136 .shot_power(power)
137 .shot_requested(false)
138 .unload_requested(false)
139 .load_requested(false)
140 .Send()) {
141 LOG(WARNING, "sending shooter goal failed\n");
142 }
143}
144
145void WaitUntilDoneOrCanceled(Action *action) {
146 while (true) {
147 // Poll the running bit and auto done bits.
148 ::aos::time::PhasedLoop10MS(5000);
149 if (!action->Running() || ShouldExitAuto()) {
150 return;
151 }
152 }
153}
154
155void Shoot() {
156 // Shoot.
157 auto shoot_action = actions::MakeShootAction();
158 shoot_action->Start();
159 WaitUntilDoneOrCanceled(shoot_action.get());
160}
161
162::std::unique_ptr<TypedAction< ::frc971::actions::DrivetrainActionQueueGroup>>
Brian Silvermanad9e0002014-04-13 14:55:57 -0700163SetDriveGoal(double distance, double maximum_velocity = 1.7, double theta = 0) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800164 LOG(INFO, "Driving to %f\n", distance);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800165 auto drivetrain_action = actions::MakeDrivetrainAction();
166 drivetrain_action->GetGoal()->left_initial_position = left_initial_position;
167 drivetrain_action->GetGoal()->right_initial_position = right_initial_position;
168 drivetrain_action->GetGoal()->y_offset = distance;
Brian Silvermanad9e0002014-04-13 14:55:57 -0700169 drivetrain_action->GetGoal()->theta_offset = theta;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800170 drivetrain_action->GetGoal()->maximum_velocity = maximum_velocity;
171 drivetrain_action->Start();
Brian Silvermanad9e0002014-04-13 14:55:57 -0700172 left_initial_position +=
173 distance - theta * constants::GetValues().turn_width / 2.0;
174 right_initial_position +=
175 distance + theta * constants::GetValues().turn_width / 2. -
176 theta * constants::GetValues().turn_width / 2.00;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800177 return ::std::move(drivetrain_action);
178}
179
180void InitializeEncoders() {
Austin Schuh577edf62014-04-13 10:33:05 -0700181 control_loops::drivetrain.status.FetchLatest();
182 while (!control_loops::drivetrain.status.get()) {
Brian Silverman2c1e0342014-04-11 16:15:01 -0700183 LOG(WARNING,
184 "No previous drivetrain position packet, trying to fetch again\n");
Austin Schuh577edf62014-04-13 10:33:05 -0700185 control_loops::drivetrain.status.FetchNextBlocking();
Brian Silverman3b89ed82013-03-22 18:59:16 -0700186 }
187 left_initial_position =
Austin Schuh577edf62014-04-13 10:33:05 -0700188 control_loops::drivetrain.status->filtered_left_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700189 right_initial_position =
Austin Schuh577edf62014-04-13 10:33:05 -0700190 control_loops::drivetrain.status->filtered_right_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700191
Austin Schuh80ff2e12014-03-08 12:06:19 -0800192}
193
Austin Schuha4faacc2014-03-09 00:50:50 -0800194void WaitUntilClawDone() {
195 while (true) {
196 // Poll the running bit and auto done bits.
197 ::aos::time::PhasedLoop10MS(5000);
198 control_loops::claw_queue_group.status.FetchLatest();
199 control_loops::claw_queue_group.goal.FetchLatest();
200 if (ShouldExitAuto()) {
201 return;
202 }
203 if (control_loops::claw_queue_group.status.get() == nullptr ||
204 control_loops::claw_queue_group.goal.get() == nullptr) {
205 continue;
206 }
207 bool ans =
208 control_loops::claw_queue_group.status->zeroed &&
209 (::std::abs(control_loops::claw_queue_group.status->bottom_velocity) <
210 1.0) &&
211 (::std::abs(control_loops::claw_queue_group.status->bottom -
212 control_loops::claw_queue_group.goal->bottom_angle) <
213 0.10) &&
214 (::std::abs(control_loops::claw_queue_group.status->separation -
215 control_loops::claw_queue_group.goal->separation_angle) <
216 0.4);
217 if (ans) {
218 return;
219 }
220 }
221}
222
Austin Schuh80ff2e12014-03-08 12:06:19 -0800223void HandleAuto() {
Austin Schuha4faacc2014-03-09 00:50:50 -0800224 // The front of the robot is 1.854 meters from the wall
Brian Silvermanad9e0002014-04-13 14:55:57 -0700225 static const double kShootDistance = 3.15;
226 static const double kPickupDistance = 0.5;
227 static const double kTurnAngle = 0.3;
Austin Schuh577edf62014-04-13 10:33:05 -0700228 ::aos::time::Time start_time = ::aos::time::Time::Now();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800229 LOG(INFO, "Handling auto mode\n");
230 ResetDrivetrain();
231
232 if (ShouldExitAuto()) return;
233 InitializeEncoders();
234
235 // Turn the claw on, keep it straight up until the ball has been grabbed.
Austin Schuh577edf62014-04-13 10:33:05 -0700236 LOG(INFO, "Claw going up at %f\n",
237 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800238 PositionClawVertically(12.0, 4.0);
Austin Schuha4faacc2014-03-09 00:50:50 -0800239 SetShotPower(115.0);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800240
241 // Wait for the ball to enter the claw.
Austin Schuha4faacc2014-03-09 00:50:50 -0800242 time::SleepFor(time::Time::InSeconds(0.25));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800243 if (ShouldExitAuto()) return;
Austin Schuh577edf62014-04-13 10:33:05 -0700244 LOG(INFO, "Readying claw for shot at %f\n",
245 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800246
247 {
248 if (ShouldExitAuto()) return;
249 // Drive to the goal.
Brian Silvermanb94069c2014-04-17 14:34:24 -0700250 auto drivetrain_action = SetDriveGoal(-kShootDistance, 2.5);
Austin Schuha4faacc2014-03-09 00:50:50 -0800251 time::SleepFor(time::Time::InSeconds(0.75));
252 PositionClawForShot();
253 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800254 WaitUntilDoneOrCanceled(drivetrain_action.get());
255 if (ShouldExitAuto()) return;
256 }
Brian Silvermanad9e0002014-04-13 14:55:57 -0700257
258 {
259 if (ShouldExitAuto()) return;
260 auto drivetrain_action = SetDriveGoal(0, 0, kTurnAngle);
261 WaitUntilDoneOrCanceled(drivetrain_action.get());
262 if (ShouldExitAuto()) return;
263 }
Austin Schuh80ff2e12014-03-08 12:06:19 -0800264
265 // Shoot.
Brian Silvermanad9e0002014-04-13 14:55:57 -0700266 LOG(INFO, "Shooting at %f\n",
267 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800268 Shoot();
Austin Schuh577edf62014-04-13 10:33:05 -0700269 time::SleepFor(time::Time::InSeconds(0.05));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800270
271 {
272 if (ShouldExitAuto()) return;
Brian Silvermanad9e0002014-04-13 14:55:57 -0700273 auto drivetrain_action = SetDriveGoal(0, 0, -kTurnAngle);
274 WaitUntilDoneOrCanceled(drivetrain_action.get());
275 if (ShouldExitAuto()) return;
276 }
277
278 {
279 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800280 // Intake the new ball.
Austin Schuh577edf62014-04-13 10:33:05 -0700281 LOG(INFO, "Claw ready for intake at %f\n",
282 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800283 PositionClawBackIntake();
Brian Silvermanb94069c2014-04-17 14:34:24 -0700284 auto drivetrain_action =
285 SetDriveGoal(kShootDistance + kPickupDistance, 2.5);
Austin Schuha4faacc2014-03-09 00:50:50 -0800286 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800287 WaitUntilDoneOrCanceled(drivetrain_action.get());
288 if (ShouldExitAuto()) return;
Austin Schuh577edf62014-04-13 10:33:05 -0700289 LOG(INFO, "Wait for the claw at %f\n",
290 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuha4faacc2014-03-09 00:50:50 -0800291 WaitUntilClawDone();
292 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800293 }
294
295 // Drive back.
296 {
Austin Schuh577edf62014-04-13 10:33:05 -0700297 LOG(INFO, "Driving back at %f\n",
298 (::aos::time::Time::Now() - start_time).ToSeconds());
Brian Silvermanb94069c2014-04-17 14:34:24 -0700299 auto drivetrain_action =
300 SetDriveGoal(-(kShootDistance + kPickupDistance), 2.5);
Austin Schuh577edf62014-04-13 10:33:05 -0700301 time::SleepFor(time::Time::InSeconds(0.3));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800302 if (ShouldExitAuto()) return;
303 PositionClawForShot();
Austin Schuha4faacc2014-03-09 00:50:50 -0800304 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800305 WaitUntilDoneOrCanceled(drivetrain_action.get());
Austin Schuha4faacc2014-03-09 00:50:50 -0800306 WaitUntilClawDone();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800307 if (ShouldExitAuto()) return;
308 }
309
Brian Silvermanad9e0002014-04-13 14:55:57 -0700310 {
311 if (ShouldExitAuto()) return;
312 auto drivetrain_action = SetDriveGoal(0, 0, -kTurnAngle);
313 WaitUntilDoneOrCanceled(drivetrain_action.get());
314 if (ShouldExitAuto()) return;
315 }
316
Austin Schuh577edf62014-04-13 10:33:05 -0700317 LOG(INFO, "Shooting at %f\n",
318 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800319 // Shoot
320 Shoot();
321 if (ShouldExitAuto()) return;
322
323 // Get ready to zero when we come back up.
Austin Schuh577edf62014-04-13 10:33:05 -0700324 time::SleepFor(time::Time::InSeconds(0.05));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800325 PositionClawVertically(0.0, 0.0);
Austin Schuh47017412013-03-10 11:50:46 -0700326}
327
328} // namespace autonomous
329} // namespace frc971