blob: fb127b2f55eb0d06b913fba1c87790d1de4149d0 [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
Brian Silvermanb8d389f2013-03-19 22:54:06 -070066void ResetIndex() {
67 LOG(INFO, "Resetting index\n");
68 control_loops::index_loop.goal.MakeWithBuilder()
69 .goal_state(5).Send();
70}
71
72void WaitForIndexReset() {
73 LOG(INFO, "Waiting for the indexer to reset\n");
74 control_loops::index_loop.status.FetchLatest();
75
76 // Fetch a couple index status packets to make sure that the indexer has run.
77 for (int i = 0; i < 5; ++i) {
78 LOG(DEBUG, "Fetching another index status packet\n");
79 control_loops::index_loop.status.FetchNextBlocking();
80 if (ShouldExitAuto()) return;
81 }
82 LOG(INFO, "Indexer is now reset.\n");
83}
84
Austin Schuh6be011a2013-03-19 10:07:02 +000085void WaitForWrist() {
86 LOG(INFO, "Waiting for the wrist\n");
87 control_loops::wrist.status.FetchLatest();
88
89 while (!control_loops::wrist.status.get()) {
90 LOG(WARNING, "No previous wrist packet, trying to fetch again\n");
91 control_loops::wrist.status.FetchNextBlocking();
92 }
93
94 while (!control_loops::wrist.status->done) {
95 control_loops::wrist.status.FetchNextBlocking();
96 LOG(DEBUG, "Got a new wrist status packet\n");
97 if (ShouldExitAuto()) return;
98 }
99 LOG(INFO, "Done waiting for the wrist\n");
100}
101 // Index_loop has no FetchNextBlocking
102void WaitForIndex() {
103 LOG(INFO, "Waiting for the indexer to be ready to intake\n");
104 control_loops::index_loop.status.FetchLatest();
105
106 while (!control_loops::index_loop.status.get()) {
107 LOG(WARNING, "No previous index packet, trying to fetch again\n");
108 control_loops::index_loop.status.FetchNextBlocking();
109 }
110
111 while (!control_loops::index_loop.status->ready_to_intake) {
112 control_loops::index_loop.status.FetchNextBlocking();
113 if (ShouldExitAuto()) return;
114 }
115 LOG(INFO, "Indexer ready to intake\n");
116}
117
118void WaitForAngle_Adjust() {
119 LOG(INFO, "Waiting for the angle adjuster to finish\n");
120 control_loops::angle_adjust.status.FetchLatest();
121
122 while (!control_loops::angle_adjust.status.get()) {
123 LOG(WARNING, "No previous angle adjust packet, trying to fetch again\n");
124 control_loops::angle_adjust.status.FetchNextBlocking();
125 }
126
127 while (!control_loops::angle_adjust.status->done) {
128 control_loops::angle_adjust.status.FetchNextBlocking();
129 if (ShouldExitAuto()) return;
130 }
131 LOG(INFO, "Angle adjuster done\n");
132}
133
Austin Schuh47017412013-03-10 11:50:46 -0700134void WaitForShooter() {
Austin Schuh6be011a2013-03-19 10:07:02 +0000135 LOG(INFO, "Waiting for the shooter to spin up\n");
Austin Schuh47017412013-03-10 11:50:46 -0700136 control_loops::shooter.status.FetchLatest();
Austin Schuh6be011a2013-03-19 10:07:02 +0000137
138 while (!control_loops::shooter.status.get()) {
139 LOG(WARNING, "No previous shooteracket, trying to fetch again\n");
Austin Schuh47017412013-03-10 11:50:46 -0700140 control_loops::shooter.status.FetchNextBlocking();
141 }
Austin Schuh47017412013-03-10 11:50:46 -0700142
Austin Schuh6be011a2013-03-19 10:07:02 +0000143 while (!control_loops::shooter.status->ready) {
144 control_loops::shooter.status.FetchNextBlocking();
145 if (ShouldExitAuto()) return;
Austin Schuh47017412013-03-10 11:50:46 -0700146 }
Austin Schuh6be011a2013-03-19 10:07:02 +0000147 LOG(INFO, "Shooter ready to shoot\n");
Austin Schuh47017412013-03-10 11:50:46 -0700148}
149
Austin Schuh6be011a2013-03-19 10:07:02 +0000150void ShootNDiscs(int n) {
151 LOG(INFO, "Waiting until %d discs have been shot\n", n);
152 control_loops::index_loop.status.FetchLatest();
153
154 while (!control_loops::index_loop.status.get()) {
155 LOG(WARNING, "No previous index_loop packet, trying to fetch again\n");
156 control_loops::index_loop.status.FetchNextBlocking();
157 }
158
159 int final_disc_count = control_loops::index_loop.status->shot_disc_count + n;
160 LOG(DEBUG, "Disc count should be %d when done\n", final_disc_count);
161 while (final_disc_count > control_loops::index_loop.status->shot_disc_count) {
162 control_loops::index_loop.status.FetchNextBlocking();
163 if (ShouldExitAuto()) return;
164 }
165 LOG(INFO, "Shot %d discs\n", n);
Austin Schuh47017412013-03-10 11:50:46 -0700166}
167
Austin Schuh6be011a2013-03-19 10:07:02 +0000168void StopDrivetrain() {
169 LOG(INFO, "Stopping the drivetrain\n");
Austin Schuh47017412013-03-10 11:50:46 -0700170 control_loops::drivetrain.goal.MakeWithBuilder()
Austin Schuh6be011a2013-03-19 10:07:02 +0000171 .control_loop_driving(false)
172 .highgear(false)
173 .steering(0.0)
174 .throttle(0.0)
175 .quickturn(false)
176 .Send();
177}
178
179void SetDriveGoal(double yoffset) {
180 LOG(INFO, "Going to move %f\n", yoffset);
181
182 // Measured conversion to get the distance right.
183 yoffset *= 0.73;
184 LOG(INFO, "Going to move an adjusted %f\n", yoffset);
185 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
186 ::Eigen::Matrix<double, 2, 1> driveTrainState;
187 const double goal_velocity = 0.0;
188 const double epsilon = 0.01;
189
Brian Silvermanc5277542013-03-22 13:33:07 -0700190 profile.set_maximum_acceleration(1);
191 profile.set_maximum_velocity(0.6);
Austin Schuh6be011a2013-03-19 10:07:02 +0000192
193 control_loops::drivetrain.position.FetchLatest();
194 while (!control_loops::drivetrain.position.get()) {
195 LOG(WARNING, "No previous drivetrain position packet, trying to fetch again\n");
196 control_loops::drivetrain.position.FetchNextBlocking();
197 }
198
199 const double left_initial_position =
200 control_loops::drivetrain.position->left_encoder;
201 const double right_initial_position =
202 control_loops::drivetrain.position->right_encoder;
203
204 while (true) {
205 ::aos::time::PhasedLoop10MS(5000); // wait until next 10ms tick
206 driveTrainState = profile.Update(yoffset, goal_velocity);
207
208 if (::std::abs(driveTrainState(0, 0) - yoffset) < epsilon) return;
209 if (ShouldExitAuto()) return;
210
211 LOG(DEBUG, "Driving left to %f, right to %f\n",
212 driveTrainState(0, 0) + left_initial_position,
213 driveTrainState(0, 0) + right_initial_position);
214 control_loops::drivetrain.goal.MakeWithBuilder()
215 .control_loop_driving(true)
216 .highgear(false)
217 .left_goal(driveTrainState(0, 0) + left_initial_position)
218 .right_goal(driveTrainState(0, 0) + right_initial_position)
219 .left_velocity_goal(driveTrainState(1, 0))
220 .right_velocity_goal(driveTrainState(1, 0))
221 .Send();
222 }
223 LOG(INFO, "Done moving\n");
224}
225
226 // start with N discs in the indexer
227void HandleAuto() {
228 LOG(INFO, "Handling auto mode\n");
229 double WRIST_UP;
230
231 ::aos::robot_state.FetchLatest();
Brian Silvermanc5277542013-03-22 13:33:07 -0700232 if (!::aos::robot_state.get() ||
Austin Schuh6be011a2013-03-19 10:07:02 +0000233 !constants::wrist_hall_effect_start_angle(&WRIST_UP)) {
234 LOG(ERROR, "Constants not ready\n");
235 return;
236 }
237 WRIST_UP -= 0.4;
238 LOG(INFO, "Got constants\n");
239 const double WRIST_DOWN = -0.633;
Brian Silvermanc5277542013-03-22 13:33:07 -0700240 const double ANGLE_ONE = 0.5101;
Austin Schuh6be011a2013-03-19 10:07:02 +0000241 const double ANGLE_TWO = 0.685;
242
243 StopDrivetrain();
Brian Silvermanb8d389f2013-03-19 22:54:06 -0700244 ResetIndex();
Austin Schuh6be011a2013-03-19 10:07:02 +0000245
246 SetWristGoal(WRIST_UP); // wrist must calibrate itself on power-up
247 SetAngle_AdjustGoal(ANGLE_ONE);
Brian Silvermanc5277542013-03-22 13:33:07 -0700248 SetShooterVelocity(410.0);
Brian Silvermanb8d389f2013-03-19 22:54:06 -0700249 WaitForIndexReset();
Brian Silvermanc5277542013-03-22 13:33:07 -0700250
251 // Wait to get some more air pressure in the thing.
252 ::aos::time::SleepFor(::aos::time::Time::InSeconds(5.0));
Brian Silvermanb8d389f2013-03-19 22:54:06 -0700253
Austin Schuh6be011a2013-03-19 10:07:02 +0000254 PreloadIndex(); // spin to top and put 1 disc into loader
255
256 if (ShouldExitAuto()) return;
257 WaitForWrist();
258 if (ShouldExitAuto()) return;
259 WaitForAngle_Adjust();
260 ShootIndex(); // tilt up, shoot, repeat until empty
261 // calls WaitForShooter
262 ShootNDiscs(3); // ShootNDiscs returns if ShouldExitAuto
263 if (ShouldExitAuto()) return;
264 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.25));
265
Brian Silvermanc5277542013-03-22 13:33:07 -0700266 return;
267
Austin Schuh6be011a2013-03-19 10:07:02 +0000268 SetWristGoal(WRIST_DOWN);
269 SetAngle_AdjustGoal(ANGLE_TWO);
270 SetShooterVelocity(375.0);
271 StartIndex(); // take in up to 4 discs
272
273 if (ShouldExitAuto()) return;
274 WaitForWrist(); // wrist must be down before moving
275 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.25));
276
277 if (ShouldExitAuto()) return;
278 WaitForIndex(); // ready to pick up discs
279
Brian Silvermanc5277542013-03-22 13:33:07 -0700280 SetDriveGoal(3.5);
281 //SetDriveGoal(0.6);
282 //::aos::time::SleepFor(::aos::time::Time::InSeconds(0.25));
283 //SetDriveGoal(2.9);
Austin Schuh6be011a2013-03-19 10:07:02 +0000284 if (ShouldExitAuto()) return;
285
286 PreloadIndex();
287 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.4));
288 SetDriveGoal(-1.3);
289
290 if (ShouldExitAuto()) return;
291 WaitForAngle_Adjust();
292 ShootIndex();
Austin Schuh47017412013-03-10 11:50:46 -0700293}
294
295} // namespace autonomous
296} // namespace frc971