blob: c7400d8040045882664c5c8802b9154079214b1f [file] [log] [blame]
Austin Schuh47017412013-03-10 11:50:46 -07001#include "stdio.h"
2
3#include "aos/aos_core.h"
4#include "aos/common/control_loop/Timing.h"
5#include "aos/common/time.h"
Austin Schuh6be011a2013-03-19 10:07:02 +00006#include "aos/common/util/trapezoid_profile.h"
Austin Schuh47017412013-03-10 11:50:46 -07007#include "frc971/autonomous/auto.q.h"
Austin Schuh6be011a2013-03-19 10:07:02 +00008#include "aos/common/messages/RobotState.q.h"
9#include "frc971/constants.h"
10#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuh47017412013-03-10 11:50:46 -070011#include "frc971/control_loops/wrist/wrist_motor.q.h"
12#include "frc971/control_loops/index/index_motor.q.h"
13#include "frc971/control_loops/shooter/shooter_motor.q.h"
14#include "frc971/control_loops/angle_adjust/angle_adjust_motor.q.h"
15
16using ::aos::time::Time;
17
18namespace frc971 {
19namespace autonomous {
20
Austin Schuh6be011a2013-03-19 10:07:02 +000021bool ShouldExitAuto() {
22 ::frc971::autonomous::autonomous.FetchLatest();
23 bool ans = !::frc971::autonomous::autonomous->run_auto;
24 if (ans) {
25 LOG(INFO, "Time to exit auto mode\n");
26 }
27 return ans;
28}
29
Austin Schuh47017412013-03-10 11:50:46 -070030void SetShooterVelocity(double velocity) {
Austin Schuh6be011a2013-03-19 10:07:02 +000031 LOG(INFO, "Setting shooter velocity to %f\n", velocity);
Austin Schuh47017412013-03-10 11:50:46 -070032 control_loops::shooter.goal.MakeWithBuilder()
33 .velocity(velocity).Send();
34}
35
Austin Schuh6be011a2013-03-19 10:07:02 +000036void SetWristGoal(double goal) {
37 LOG(INFO, "Setting wrist to %f\n", goal);
38 control_loops::wrist.goal.MakeWithBuilder()
39 .goal(goal).Send();
40}
41
42void SetAngle_AdjustGoal(double goal) {
43 LOG(INFO, "Setting angle adjust to %f\n", goal);
44 control_loops::angle_adjust.goal.MakeWithBuilder()
45 .goal(goal).Send();
46}
47
48void StartIndex() {
49 LOG(INFO, "Starting index\n");
50 control_loops::index_loop.goal.MakeWithBuilder()
Austin Schuh47017412013-03-10 11:50:46 -070051 .goal_state(2).Send();
52}
53
Austin Schuh6be011a2013-03-19 10:07:02 +000054void PreloadIndex() {
55 LOG(INFO, "Preloading index\n");
56 control_loops::index_loop.goal.MakeWithBuilder()
Austin Schuh47017412013-03-10 11:50:46 -070057 .goal_state(3).Send();
58}
59
Austin Schuh6be011a2013-03-19 10:07:02 +000060void ShootIndex() {
61 LOG(INFO, "Shooting index\n");
62 control_loops::index_loop.goal.MakeWithBuilder()
Austin Schuh47017412013-03-10 11:50:46 -070063 .goal_state(4).Send();
64}
65
Austin Schuh6be011a2013-03-19 10:07:02 +000066void WaitForWrist() {
67 LOG(INFO, "Waiting for the wrist\n");
68 control_loops::wrist.status.FetchLatest();
69
70 while (!control_loops::wrist.status.get()) {
71 LOG(WARNING, "No previous wrist packet, trying to fetch again\n");
72 control_loops::wrist.status.FetchNextBlocking();
73 }
74
75 while (!control_loops::wrist.status->done) {
76 control_loops::wrist.status.FetchNextBlocking();
77 LOG(DEBUG, "Got a new wrist status packet\n");
78 if (ShouldExitAuto()) return;
79 }
80 LOG(INFO, "Done waiting for the wrist\n");
81}
82 // Index_loop has no FetchNextBlocking
83void WaitForIndex() {
84 LOG(INFO, "Waiting for the indexer to be ready to intake\n");
85 control_loops::index_loop.status.FetchLatest();
86
87 while (!control_loops::index_loop.status.get()) {
88 LOG(WARNING, "No previous index packet, trying to fetch again\n");
89 control_loops::index_loop.status.FetchNextBlocking();
90 }
91
92 while (!control_loops::index_loop.status->ready_to_intake) {
93 control_loops::index_loop.status.FetchNextBlocking();
94 if (ShouldExitAuto()) return;
95 }
96 LOG(INFO, "Indexer ready to intake\n");
97}
98
99void WaitForAngle_Adjust() {
100 LOG(INFO, "Waiting for the angle adjuster to finish\n");
101 control_loops::angle_adjust.status.FetchLatest();
102
103 while (!control_loops::angle_adjust.status.get()) {
104 LOG(WARNING, "No previous angle adjust packet, trying to fetch again\n");
105 control_loops::angle_adjust.status.FetchNextBlocking();
106 }
107
108 while (!control_loops::angle_adjust.status->done) {
109 control_loops::angle_adjust.status.FetchNextBlocking();
110 if (ShouldExitAuto()) return;
111 }
112 LOG(INFO, "Angle adjuster done\n");
113}
114
Austin Schuh47017412013-03-10 11:50:46 -0700115void WaitForShooter() {
Austin Schuh6be011a2013-03-19 10:07:02 +0000116 LOG(INFO, "Waiting for the shooter to spin up\n");
Austin Schuh47017412013-03-10 11:50:46 -0700117 control_loops::shooter.status.FetchLatest();
Austin Schuh6be011a2013-03-19 10:07:02 +0000118
119 while (!control_loops::shooter.status.get()) {
120 LOG(WARNING, "No previous shooteracket, trying to fetch again\n");
Austin Schuh47017412013-03-10 11:50:46 -0700121 control_loops::shooter.status.FetchNextBlocking();
122 }
Austin Schuh47017412013-03-10 11:50:46 -0700123
Austin Schuh6be011a2013-03-19 10:07:02 +0000124 while (!control_loops::shooter.status->ready) {
125 control_loops::shooter.status.FetchNextBlocking();
126 if (ShouldExitAuto()) return;
Austin Schuh47017412013-03-10 11:50:46 -0700127 }
Austin Schuh6be011a2013-03-19 10:07:02 +0000128 LOG(INFO, "Shooter ready to shoot\n");
Austin Schuh47017412013-03-10 11:50:46 -0700129}
130
Austin Schuh6be011a2013-03-19 10:07:02 +0000131void ShootNDiscs(int n) {
132 LOG(INFO, "Waiting until %d discs have been shot\n", n);
133 control_loops::index_loop.status.FetchLatest();
134
135 while (!control_loops::index_loop.status.get()) {
136 LOG(WARNING, "No previous index_loop packet, trying to fetch again\n");
137 control_loops::index_loop.status.FetchNextBlocking();
138 }
139
140 int final_disc_count = control_loops::index_loop.status->shot_disc_count + n;
141 LOG(DEBUG, "Disc count should be %d when done\n", final_disc_count);
142 while (final_disc_count > control_loops::index_loop.status->shot_disc_count) {
143 control_loops::index_loop.status.FetchNextBlocking();
144 if (ShouldExitAuto()) return;
145 }
146 LOG(INFO, "Shot %d discs\n", n);
Austin Schuh47017412013-03-10 11:50:46 -0700147}
148
Austin Schuh6be011a2013-03-19 10:07:02 +0000149void StopDrivetrain() {
150 LOG(INFO, "Stopping the drivetrain\n");
Austin Schuh47017412013-03-10 11:50:46 -0700151 control_loops::drivetrain.goal.MakeWithBuilder()
Austin Schuh6be011a2013-03-19 10:07:02 +0000152 .control_loop_driving(false)
153 .highgear(false)
154 .steering(0.0)
155 .throttle(0.0)
156 .quickturn(false)
157 .Send();
158}
159
160void SetDriveGoal(double yoffset) {
161 LOG(INFO, "Going to move %f\n", yoffset);
162
163 // Measured conversion to get the distance right.
164 yoffset *= 0.73;
165 LOG(INFO, "Going to move an adjusted %f\n", yoffset);
166 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
167 ::Eigen::Matrix<double, 2, 1> driveTrainState;
168 const double goal_velocity = 0.0;
169 const double epsilon = 0.01;
170
171 profile.set_maximum_acceleration(2);
172 profile.set_maximum_velocity(0.8);
173
174 control_loops::drivetrain.position.FetchLatest();
175 while (!control_loops::drivetrain.position.get()) {
176 LOG(WARNING, "No previous drivetrain position packet, trying to fetch again\n");
177 control_loops::drivetrain.position.FetchNextBlocking();
178 }
179
180 const double left_initial_position =
181 control_loops::drivetrain.position->left_encoder;
182 const double right_initial_position =
183 control_loops::drivetrain.position->right_encoder;
184
185 while (true) {
186 ::aos::time::PhasedLoop10MS(5000); // wait until next 10ms tick
187 driveTrainState = profile.Update(yoffset, goal_velocity);
188
189 if (::std::abs(driveTrainState(0, 0) - yoffset) < epsilon) return;
190 if (ShouldExitAuto()) return;
191
192 LOG(DEBUG, "Driving left to %f, right to %f\n",
193 driveTrainState(0, 0) + left_initial_position,
194 driveTrainState(0, 0) + right_initial_position);
195 control_loops::drivetrain.goal.MakeWithBuilder()
196 .control_loop_driving(true)
197 .highgear(false)
198 .left_goal(driveTrainState(0, 0) + left_initial_position)
199 .right_goal(driveTrainState(0, 0) + right_initial_position)
200 .left_velocity_goal(driveTrainState(1, 0))
201 .right_velocity_goal(driveTrainState(1, 0))
202 .Send();
203 }
204 LOG(INFO, "Done moving\n");
205}
206
207 // start with N discs in the indexer
208void HandleAuto() {
209 LOG(INFO, "Handling auto mode\n");
210 double WRIST_UP;
211
212 ::aos::robot_state.FetchLatest();
213 if (::aos::robot_state.get() &&
214 !constants::wrist_hall_effect_start_angle(&WRIST_UP)) {
215 LOG(ERROR, "Constants not ready\n");
216 return;
217 }
218 WRIST_UP -= 0.4;
219 LOG(INFO, "Got constants\n");
220 const double WRIST_DOWN = -0.633;
221 const double ANGLE_ONE = 0.50;
222 const double ANGLE_TWO = 0.685;
223
224 StopDrivetrain();
225
226 SetWristGoal(WRIST_UP); // wrist must calibrate itself on power-up
227 SetAngle_AdjustGoal(ANGLE_ONE);
228 SetShooterVelocity(405.0);
229 PreloadIndex(); // spin to top and put 1 disc into loader
230
231 if (ShouldExitAuto()) return;
232 WaitForWrist();
233 if (ShouldExitAuto()) return;
234 WaitForAngle_Adjust();
235 ShootIndex(); // tilt up, shoot, repeat until empty
236 // calls WaitForShooter
237 ShootNDiscs(3); // ShootNDiscs returns if ShouldExitAuto
238 if (ShouldExitAuto()) return;
239 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.25));
240
241 SetWristGoal(WRIST_DOWN);
242 SetAngle_AdjustGoal(ANGLE_TWO);
243 SetShooterVelocity(375.0);
244 StartIndex(); // take in up to 4 discs
245
246 if (ShouldExitAuto()) return;
247 WaitForWrist(); // wrist must be down before moving
248 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.25));
249
250 if (ShouldExitAuto()) return;
251 WaitForIndex(); // ready to pick up discs
252
253 SetDriveGoal(0.75);
254 SetDriveGoal(2.75);
255 if (ShouldExitAuto()) return;
256
257 PreloadIndex();
258 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.4));
259 SetDriveGoal(-1.3);
260
261 if (ShouldExitAuto()) return;
262 WaitForAngle_Adjust();
263 ShootIndex();
Austin Schuh47017412013-03-10 11:50:46 -0700264}
265
266} // namespace autonomous
267} // namespace frc971