blob: b9f52d3c86f94481dd6d57fc63566f5f121bd1f7 [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 Silverman6f621542014-04-06 16:00:41 -070010#include "aos/common/logging/queue_logging.h"
Brian Silverman598800f2013-05-09 17:08:42 -070011
12#include "frc971/autonomous/auto.q.h"
Austin Schuh6be011a2013-03-19 10:07:02 +000013#include "frc971/constants.h"
14#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuh80ff2e12014-03-08 12:06:19 -080015#include "frc971/control_loops/shooter/shooter.q.h"
16#include "frc971/control_loops/claw/claw.q.h"
17#include "frc971/actions/action_client.h"
18#include "frc971/actions/shoot_action.h"
19#include "frc971/actions/drivetrain_action.h"
Brian Silverman6f621542014-04-06 16:00:41 -070020#include "frc971/queues/hot_goal.q.h"
Austin Schuh47017412013-03-10 11:50:46 -070021
22using ::aos::time::Time;
23
24namespace frc971 {
25namespace autonomous {
26
Austin Schuh80ff2e12014-03-08 12:06:19 -080027namespace time = ::aos::time;
28
Brian Silverman3b89ed82013-03-22 18:59:16 -070029static double left_initial_position, right_initial_position;
30
Austin Schuh6be011a2013-03-19 10:07:02 +000031bool ShouldExitAuto() {
32 ::frc971::autonomous::autonomous.FetchLatest();
33 bool ans = !::frc971::autonomous::autonomous->run_auto;
34 if (ans) {
35 LOG(INFO, "Time to exit auto mode\n");
36 }
37 return ans;
38}
39
Austin Schuh6be011a2013-03-19 10:07:02 +000040void StopDrivetrain() {
41 LOG(INFO, "Stopping the drivetrain\n");
Austin Schuh47017412013-03-10 11:50:46 -070042 control_loops::drivetrain.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070043 .control_loop_driving(true)
Brian Silvermance86bac2013-03-31 19:07:24 -070044 .left_goal(left_initial_position)
45 .left_velocity_goal(0)
46 .right_goal(right_initial_position)
47 .right_velocity_goal(0)
48 .quickturn(false)
49 .Send();
50}
51
52void ResetDrivetrain() {
53 LOG(INFO, "resetting the drivetrain\n");
54 control_loops::drivetrain.goal.MakeWithBuilder()
55 .control_loop_driving(false)
Austin Schuh6be011a2013-03-19 10:07:02 +000056 .highgear(false)
57 .steering(0.0)
58 .throttle(0.0)
Austin Schuh6be011a2013-03-19 10:07:02 +000059 .Send();
60}
61
Brian Silverman3b89ed82013-03-22 18:59:16 -070062void DriveSpin(double radians) {
63 LOG(INFO, "going to spin %f\n", radians);
64
65 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
66 ::Eigen::Matrix<double, 2, 1> driveTrainState;
67 const double goal_velocity = 0.0;
68 const double epsilon = 0.01;
Brian Silverman13be6682013-03-22 21:02:07 -070069 // in drivetrain "meters"
Brian Silverman3b89ed82013-03-22 18:59:16 -070070 const double kRobotWidth = 0.4544;
71
Brian Silverman7992d6e2013-03-24 19:20:54 -070072 profile.set_maximum_acceleration(1.5);
73 profile.set_maximum_velocity(0.8);
Brian Silverman3b89ed82013-03-22 18:59:16 -070074
75 const double side_offset = kRobotWidth * radians / 2.0;
76
77 while (true) {
Brian Silverman7f09f972013-03-22 23:11:39 -070078 ::aos::time::PhasedLoop10MS(5000); // wait until next 10ms tick
Brian Silverman3b89ed82013-03-22 18:59:16 -070079 driveTrainState = profile.Update(side_offset, goal_velocity);
80
81 if (::std::abs(driveTrainState(0, 0) - side_offset) < epsilon) break;
82 if (ShouldExitAuto()) return;
83
84 LOG(DEBUG, "Driving left to %f, right to %f\n",
Brian Silverman7992d6e2013-03-24 19:20:54 -070085 left_initial_position - driveTrainState(0, 0),
86 right_initial_position + driveTrainState(0, 0));
Brian Silverman3b89ed82013-03-22 18:59:16 -070087 control_loops::drivetrain.goal.MakeWithBuilder()
88 .control_loop_driving(true)
89 .highgear(false)
Brian Silverman7992d6e2013-03-24 19:20:54 -070090 .left_goal(left_initial_position - driveTrainState(0, 0))
91 .right_goal(right_initial_position + driveTrainState(0, 0))
92 .left_velocity_goal(-driveTrainState(1, 0))
93 .right_velocity_goal(driveTrainState(1, 0))
Brian Silverman3b89ed82013-03-22 18:59:16 -070094 .Send();
95 }
Brian Silverman7992d6e2013-03-24 19:20:54 -070096 left_initial_position -= side_offset;
97 right_initial_position += side_offset;
Brian Silverman3b89ed82013-03-22 18:59:16 -070098 LOG(INFO, "Done moving\n");
99}
100
Austin Schuh80ff2e12014-03-08 12:06:19 -0800101void PositionClawVertically(double intake_power = 0.0, double centering_power = 0.0) {
102 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
103 .bottom_angle(0.0)
104 .separation_angle(0.0)
105 .intake(intake_power)
106 .centering(centering_power)
107 .Send()) {
108 LOG(WARNING, "sending claw goal failed\n");
109 }
110}
Brian Silvermance86bac2013-03-31 19:07:24 -0700111
Austin Schuh80ff2e12014-03-08 12:06:19 -0800112void PositionClawBackIntake() {
113 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
114 .bottom_angle(-2.273474)
115 .separation_angle(0.0)
116 .intake(12.0)
117 .centering(12.0)
118 .Send()) {
119 LOG(WARNING, "sending claw goal failed\n");
120 }
121}
Brian Silvermance86bac2013-03-31 19:07:24 -0700122
Austin Schuh80ff2e12014-03-08 12:06:19 -0800123void PositionClawForShot() {
124 // Turn the claw on, keep it straight up until the ball has been grabbed.
125 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
Brian Silverman31b5b822014-03-14 18:50:39 -0700126 .bottom_angle(0.86)
Austin Schuha4faacc2014-03-09 00:50:50 -0800127 .separation_angle(0.10)
128 .intake(4.0)
Austin Schuh80ff2e12014-03-08 12:06:19 -0800129 .centering(1.0)
130 .Send()) {
131 LOG(WARNING, "sending claw goal failed\n");
132 }
133}
134
135void SetShotPower(double power) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800136 LOG(INFO, "Setting shot power to %f\n", power);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800137 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
138 .shot_power(power)
139 .shot_requested(false)
140 .unload_requested(false)
141 .load_requested(false)
142 .Send()) {
143 LOG(WARNING, "sending shooter goal failed\n");
144 }
145}
146
147void WaitUntilDoneOrCanceled(Action *action) {
148 while (true) {
149 // Poll the running bit and auto done bits.
150 ::aos::time::PhasedLoop10MS(5000);
151 if (!action->Running() || ShouldExitAuto()) {
152 return;
153 }
154 }
155}
156
157void Shoot() {
158 // Shoot.
159 auto shoot_action = actions::MakeShootAction();
160 shoot_action->Start();
161 WaitUntilDoneOrCanceled(shoot_action.get());
162}
163
164::std::unique_ptr<TypedAction< ::frc971::actions::DrivetrainActionQueueGroup>>
Brian Silvermanad9e0002014-04-13 14:55:57 -0700165SetDriveGoal(double distance, double maximum_velocity = 1.7, double theta = 0) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800166 LOG(INFO, "Driving to %f\n", distance);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800167 auto drivetrain_action = actions::MakeDrivetrainAction();
168 drivetrain_action->GetGoal()->left_initial_position = left_initial_position;
169 drivetrain_action->GetGoal()->right_initial_position = right_initial_position;
170 drivetrain_action->GetGoal()->y_offset = distance;
Brian Silvermanad9e0002014-04-13 14:55:57 -0700171 drivetrain_action->GetGoal()->theta_offset = theta;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800172 drivetrain_action->GetGoal()->maximum_velocity = maximum_velocity;
173 drivetrain_action->Start();
Brian Silvermanad9e0002014-04-13 14:55:57 -0700174 left_initial_position +=
175 distance - theta * constants::GetValues().turn_width / 2.0;
176 right_initial_position +=
177 distance + theta * constants::GetValues().turn_width / 2. -
178 theta * constants::GetValues().turn_width / 2.00;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800179 return ::std::move(drivetrain_action);
180}
181
182void InitializeEncoders() {
Austin Schuh577edf62014-04-13 10:33:05 -0700183 control_loops::drivetrain.status.FetchLatest();
184 while (!control_loops::drivetrain.status.get()) {
Brian Silverman2c1e0342014-04-11 16:15:01 -0700185 LOG(WARNING,
186 "No previous drivetrain position packet, trying to fetch again\n");
Austin Schuh577edf62014-04-13 10:33:05 -0700187 control_loops::drivetrain.status.FetchNextBlocking();
Brian Silverman3b89ed82013-03-22 18:59:16 -0700188 }
189 left_initial_position =
Austin Schuh577edf62014-04-13 10:33:05 -0700190 control_loops::drivetrain.status->filtered_left_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700191 right_initial_position =
Austin Schuh577edf62014-04-13 10:33:05 -0700192 control_loops::drivetrain.status->filtered_right_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700193
Austin Schuh80ff2e12014-03-08 12:06:19 -0800194}
195
Austin Schuha4faacc2014-03-09 00:50:50 -0800196void WaitUntilClawDone() {
197 while (true) {
198 // Poll the running bit and auto done bits.
199 ::aos::time::PhasedLoop10MS(5000);
200 control_loops::claw_queue_group.status.FetchLatest();
201 control_loops::claw_queue_group.goal.FetchLatest();
202 if (ShouldExitAuto()) {
203 return;
204 }
205 if (control_loops::claw_queue_group.status.get() == nullptr ||
206 control_loops::claw_queue_group.goal.get() == nullptr) {
207 continue;
208 }
209 bool ans =
210 control_loops::claw_queue_group.status->zeroed &&
211 (::std::abs(control_loops::claw_queue_group.status->bottom_velocity) <
212 1.0) &&
213 (::std::abs(control_loops::claw_queue_group.status->bottom -
214 control_loops::claw_queue_group.goal->bottom_angle) <
215 0.10) &&
216 (::std::abs(control_loops::claw_queue_group.status->separation -
217 control_loops::claw_queue_group.goal->separation_angle) <
218 0.4);
219 if (ans) {
220 return;
221 }
222 }
223}
224
Austin Schuh80ff2e12014-03-08 12:06:19 -0800225void HandleAuto() {
Austin Schuha4faacc2014-03-09 00:50:50 -0800226 // The front of the robot is 1.854 meters from the wall
Brian Silvermanad9e0002014-04-13 14:55:57 -0700227 static const double kShootDistance = 3.15;
228 static const double kPickupDistance = 0.5;
229 static const double kTurnAngle = 0.3;
Austin Schuh577edf62014-04-13 10:33:05 -0700230 ::aos::time::Time start_time = ::aos::time::Time::Now();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800231 LOG(INFO, "Handling auto mode\n");
Brian Silvermanb36ae1f2014-04-17 15:13:41 -0700232
Brian Silverman6f621542014-04-06 16:00:41 -0700233 ::frc971::HotGoal start_counts;
234 hot_goal.FetchLatest();
Brian Silvermanb36ae1f2014-04-17 15:13:41 -0700235 bool start_counts_valid = true;
Brian Silverman6f621542014-04-06 16:00:41 -0700236 if (!hot_goal.get()) {
Brian Silvermanb36ae1f2014-04-17 15:13:41 -0700237 LOG(WARNING, "no hot goal message. will ignore\n");
238 start_counts_valid = false;
Brian Silverman6f621542014-04-06 16:00:41 -0700239 } else {
240 memcpy(&start_counts, hot_goal.get(), sizeof(start_counts));
241 LOG_STRUCT(INFO, "counts at start", start_counts);
242 }
Brian Silvermanb36ae1f2014-04-17 15:13:41 -0700243 (void)start_counts_valid;
Brian Silverman6f621542014-04-06 16:00:41 -0700244
Austin Schuh80ff2e12014-03-08 12:06:19 -0800245 ResetDrivetrain();
246
247 if (ShouldExitAuto()) return;
248 InitializeEncoders();
249
250 // Turn the claw on, keep it straight up until the ball has been grabbed.
Austin Schuh577edf62014-04-13 10:33:05 -0700251 LOG(INFO, "Claw going up at %f\n",
252 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800253 PositionClawVertically(12.0, 4.0);
Austin Schuha4faacc2014-03-09 00:50:50 -0800254 SetShotPower(115.0);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800255
256 // Wait for the ball to enter the claw.
Austin Schuha4faacc2014-03-09 00:50:50 -0800257 time::SleepFor(time::Time::InSeconds(0.25));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800258 if (ShouldExitAuto()) return;
Austin Schuh577edf62014-04-13 10:33:05 -0700259 LOG(INFO, "Readying claw for shot at %f\n",
260 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800261
262 {
263 if (ShouldExitAuto()) return;
264 // Drive to the goal.
Brian Silvermanb94069c2014-04-17 14:34:24 -0700265 auto drivetrain_action = SetDriveGoal(-kShootDistance, 2.5);
Austin Schuha4faacc2014-03-09 00:50:50 -0800266 time::SleepFor(time::Time::InSeconds(0.75));
267 PositionClawForShot();
268 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800269 WaitUntilDoneOrCanceled(drivetrain_action.get());
270 if (ShouldExitAuto()) return;
271 }
Brian Silvermanad9e0002014-04-13 14:55:57 -0700272
273 {
274 if (ShouldExitAuto()) return;
275 auto drivetrain_action = SetDriveGoal(0, 0, kTurnAngle);
276 WaitUntilDoneOrCanceled(drivetrain_action.get());
277 if (ShouldExitAuto()) return;
278 }
Austin Schuh80ff2e12014-03-08 12:06:19 -0800279
280 // Shoot.
Brian Silvermanad9e0002014-04-13 14:55:57 -0700281 LOG(INFO, "Shooting at %f\n",
282 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800283 Shoot();
Austin Schuh577edf62014-04-13 10:33:05 -0700284 time::SleepFor(time::Time::InSeconds(0.05));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800285
286 {
287 if (ShouldExitAuto()) return;
Brian Silvermanad9e0002014-04-13 14:55:57 -0700288 auto drivetrain_action = SetDriveGoal(0, 0, -kTurnAngle);
289 WaitUntilDoneOrCanceled(drivetrain_action.get());
290 if (ShouldExitAuto()) return;
291 }
292
293 {
294 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800295 // Intake the new ball.
Austin Schuh577edf62014-04-13 10:33:05 -0700296 LOG(INFO, "Claw ready for intake at %f\n",
297 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800298 PositionClawBackIntake();
Brian Silvermanb94069c2014-04-17 14:34:24 -0700299 auto drivetrain_action =
300 SetDriveGoal(kShootDistance + kPickupDistance, 2.5);
Austin Schuha4faacc2014-03-09 00:50:50 -0800301 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800302 WaitUntilDoneOrCanceled(drivetrain_action.get());
303 if (ShouldExitAuto()) return;
Austin Schuh577edf62014-04-13 10:33:05 -0700304 LOG(INFO, "Wait for the claw at %f\n",
305 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuha4faacc2014-03-09 00:50:50 -0800306 WaitUntilClawDone();
307 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800308 }
309
310 // Drive back.
311 {
Austin Schuh577edf62014-04-13 10:33:05 -0700312 LOG(INFO, "Driving back at %f\n",
313 (::aos::time::Time::Now() - start_time).ToSeconds());
Brian Silvermanb94069c2014-04-17 14:34:24 -0700314 auto drivetrain_action =
315 SetDriveGoal(-(kShootDistance + kPickupDistance), 2.5);
Austin Schuh577edf62014-04-13 10:33:05 -0700316 time::SleepFor(time::Time::InSeconds(0.3));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800317 if (ShouldExitAuto()) return;
318 PositionClawForShot();
Austin Schuha4faacc2014-03-09 00:50:50 -0800319 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800320 WaitUntilDoneOrCanceled(drivetrain_action.get());
Austin Schuha4faacc2014-03-09 00:50:50 -0800321 WaitUntilClawDone();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800322 if (ShouldExitAuto()) return;
323 }
324
Brian Silvermanad9e0002014-04-13 14:55:57 -0700325 {
326 if (ShouldExitAuto()) return;
327 auto drivetrain_action = SetDriveGoal(0, 0, -kTurnAngle);
328 WaitUntilDoneOrCanceled(drivetrain_action.get());
329 if (ShouldExitAuto()) return;
330 }
331
Austin Schuh577edf62014-04-13 10:33:05 -0700332 LOG(INFO, "Shooting at %f\n",
333 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800334 // Shoot
335 Shoot();
336 if (ShouldExitAuto()) return;
337
338 // Get ready to zero when we come back up.
Austin Schuh577edf62014-04-13 10:33:05 -0700339 time::SleepFor(time::Time::InSeconds(0.05));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800340 PositionClawVertically(0.0, 0.0);
Austin Schuh47017412013-03-10 11:50:46 -0700341}
342
343} // namespace autonomous
344} // namespace frc971