blob: 9f0a033b9b37afe15428d88e5116cc9fbeb01eb6 [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 Silverman6f621542014-04-06 16:00:41 -07009#include "aos/common/logging/queue_logging.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"
Daniel Petti3b1e48f2015-02-15 15:57:53 -080014#include "frc971/actors/drivetrain_actor.h"
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070015#include "frc971/control_loops/claw/claw.q.h"
Brian Silverman5bfda6c2015-03-21 23:40:13 -070016#include "frc971/control_loops/fridge/fridge.q.h"
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070017#include "frc971/actors/pickup_actor.h"
18#include "frc971/actors/stack_actor.h"
Austin Schuh47017412013-03-10 11:50:46 -070019
20using ::aos::time::Time;
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070021using ::frc971::control_loops::claw_queue;
Brian Silverman5bfda6c2015-03-21 23:40:13 -070022using ::frc971::control_loops::fridge_queue;
Brian Silverman93936f72015-03-19 23:38:30 -070023using ::frc971::control_loops::drivetrain_queue;
Austin Schuh47017412013-03-10 11:50:46 -070024
25namespace frc971 {
26namespace autonomous {
27
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070028constexpr double kClawAutoVelocity = 3.00;
29constexpr double kClawAutoAcceleration = 6.0;
30constexpr double kAngleEpsilon = 0.10;
31double kClawTotePackAngle = 0.95;
32
Austin Schuh80ff2e12014-03-08 12:06:19 -080033namespace time = ::aos::time;
34
Brian Silverman3b89ed82013-03-22 18:59:16 -070035static double left_initial_position, right_initial_position;
36
Austin Schuh6be011a2013-03-19 10:07:02 +000037bool ShouldExitAuto() {
38 ::frc971::autonomous::autonomous.FetchLatest();
39 bool ans = !::frc971::autonomous::autonomous->run_auto;
40 if (ans) {
41 LOG(INFO, "Time to exit auto mode\n");
42 }
43 return ans;
44}
45
Austin Schuh6be011a2013-03-19 10:07:02 +000046void StopDrivetrain() {
47 LOG(INFO, "Stopping the drivetrain\n");
Brian Silvermanada5f2c2015-02-01 02:41:14 -050048 control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070049 .control_loop_driving(true)
Brian Silvermance86bac2013-03-31 19:07:24 -070050 .left_goal(left_initial_position)
51 .left_velocity_goal(0)
52 .right_goal(right_initial_position)
53 .right_velocity_goal(0)
54 .quickturn(false)
55 .Send();
56}
57
58void ResetDrivetrain() {
59 LOG(INFO, "resetting the drivetrain\n");
Brian Silvermanada5f2c2015-02-01 02:41:14 -050060 control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silvermance86bac2013-03-31 19:07:24 -070061 .control_loop_driving(false)
Brian Silverman93335ae2015-01-26 20:43:39 -050062 //.highgear(false)
Austin Schuh6be011a2013-03-19 10:07:02 +000063 .steering(0.0)
64 .throttle(0.0)
Brian Silverman38ea9bf2014-04-19 22:57:54 -070065 .left_goal(left_initial_position)
66 .left_velocity_goal(0)
67 .right_goal(right_initial_position)
68 .right_velocity_goal(0)
Austin Schuh6be011a2013-03-19 10:07:02 +000069 .Send();
70}
71
Brian Silverman3b89ed82013-03-22 18:59:16 -070072void DriveSpin(double radians) {
73 LOG(INFO, "going to spin %f\n", radians);
74
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080075 // TODO(sensors): update this time thing maybe?
Brian Silverman3b89ed82013-03-22 18:59:16 -070076 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
77 ::Eigen::Matrix<double, 2, 1> driveTrainState;
78 const double goal_velocity = 0.0;
79 const double epsilon = 0.01;
Brian Silverman13be6682013-03-22 21:02:07 -070080 // in drivetrain "meters"
Brian Silverman3b89ed82013-03-22 18:59:16 -070081 const double kRobotWidth = 0.4544;
82
Brian Silverman7992d6e2013-03-24 19:20:54 -070083 profile.set_maximum_acceleration(1.5);
84 profile.set_maximum_velocity(0.8);
Brian Silverman3b89ed82013-03-22 18:59:16 -070085
86 const double side_offset = kRobotWidth * radians / 2.0;
87
88 while (true) {
Brian Silverman547abb32015-02-16 00:37:48 -050089 ::aos::time::PhasedLoopXMS(5, 2500);
Brian Silverman3b89ed82013-03-22 18:59:16 -070090 driveTrainState = profile.Update(side_offset, goal_velocity);
91
92 if (::std::abs(driveTrainState(0, 0) - side_offset) < epsilon) break;
93 if (ShouldExitAuto()) return;
94
95 LOG(DEBUG, "Driving left to %f, right to %f\n",
Brian Silverman7992d6e2013-03-24 19:20:54 -070096 left_initial_position - driveTrainState(0, 0),
97 right_initial_position + driveTrainState(0, 0));
Brian Silvermanada5f2c2015-02-01 02:41:14 -050098 control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070099 .control_loop_driving(true)
Brian Silverman93335ae2015-01-26 20:43:39 -0500100 //.highgear(false)
Brian Silverman7992d6e2013-03-24 19:20:54 -0700101 .left_goal(left_initial_position - driveTrainState(0, 0))
102 .right_goal(right_initial_position + driveTrainState(0, 0))
103 .left_velocity_goal(-driveTrainState(1, 0))
104 .right_velocity_goal(driveTrainState(1, 0))
Brian Silverman3b89ed82013-03-22 18:59:16 -0700105 .Send();
106 }
Brian Silverman7992d6e2013-03-24 19:20:54 -0700107 left_initial_position -= side_offset;
108 right_initial_position += side_offset;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700109 LOG(INFO, "Done moving\n");
110}
111
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800112void WaitUntilDoneOrCanceled(aos::common::actions::Action *action) {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800113 while (true) {
114 // Poll the running bit and auto done bits.
Brian Silverman547abb32015-02-16 00:37:48 -0500115 ::aos::time::PhasedLoopXMS(5, 2500);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800116 if (!action->Running() || ShouldExitAuto()) {
117 return;
118 }
119 }
120}
121
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800122::std::unique_ptr<::frc971::actors::DrivetrainAction> SetDriveGoal(
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700123 double distance, bool slow_acceleration, double maximum_velocity = 0.7,
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800124 double theta = 0) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800125 LOG(INFO, "Driving to %f\n", distance);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800126
127 ::frc971::actors::DrivetrainActionParams params;
128 params.left_initial_position = left_initial_position;
129 params.right_initial_position = right_initial_position;
130 params.y_offset = distance;
131 params.theta_offset = theta;
132 params.maximum_velocity = maximum_velocity;
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700133 params.maximum_acceleration = slow_acceleration ? 0.3 : 0.2;
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800134 auto drivetrain_action = actors::MakeDrivetrainAction(params);
135
Austin Schuh80ff2e12014-03-08 12:06:19 -0800136 drivetrain_action->Start();
Brian Silvermanad9e0002014-04-13 14:55:57 -0700137 left_initial_position +=
138 distance - theta * constants::GetValues().turn_width / 2.0;
139 right_initial_position +=
Daniel Pettib0733be2014-11-14 22:44:03 -0800140 distance + theta * constants::GetValues().turn_width / 2.0;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800141 return ::std::move(drivetrain_action);
142}
143
144void InitializeEncoders() {
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500145 control_loops::drivetrain_queue.status.FetchLatest();
146 while (!control_loops::drivetrain_queue.status.get()) {
Brian Silverman2c1e0342014-04-11 16:15:01 -0700147 LOG(WARNING,
148 "No previous drivetrain position packet, trying to fetch again\n");
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500149 control_loops::drivetrain_queue.status.FetchNextBlocking();
Brian Silverman3b89ed82013-03-22 18:59:16 -0700150 }
151 left_initial_position =
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500152 control_loops::drivetrain_queue.status->filtered_left_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700153 right_initial_position =
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500154 control_loops::drivetrain_queue.status->filtered_right_position;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800155}
156
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700157void SetClawState(double angle, double intake_voltage, double rollers_closed) {
158 auto message = control_loops::claw_queue.goal.MakeMessage();
159 message->angle = angle;
160 message->max_velocity = kClawAutoVelocity;
161 message->max_acceleration = kClawAutoAcceleration;
162 message->angular_velocity = 0.0;
163 message->intake = intake_voltage;
164 message->rollers_closed = rollers_closed;
165
166 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
167 message.Send();
168
169 while (true) {
170 control_loops::claw_queue.status.FetchAnother();
171 const double current_angle = control_loops::claw_queue.status->angle;
172 LOG_STRUCT(DEBUG, "Got claw status", *control_loops::claw_queue.status);
173
174 // I believe all we can care about here is the angle. Other values will
175 // either be set or not, but there is nothing we can do about it. If it
176 // never gets there we do not care, auto is over for us.
177 if (::std::abs(current_angle - angle) < kAngleEpsilon) {
178 break;
179 }
180 }
181}
182
Austin Schuh80ff2e12014-03-08 12:06:19 -0800183void HandleAuto() {
Austin Schuh577edf62014-04-13 10:33:05 -0700184 ::aos::time::Time start_time = ::aos::time::Time::Now();
Brian Silverman20141f92015-01-05 17:39:01 -0800185 LOG(INFO, "Handling auto mode at %f\n", start_time.ToSeconds());
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700186 ::std::unique_ptr<::frc971::actors::DrivetrainAction> drive;
187 ::std::unique_ptr<::frc971::actors::PickupAction> pickup;
188 ::std::unique_ptr<::frc971::actors::StackAction> stack;
189 // TODO(austin): Score!
190 //::std::unique_ptr<ScoreAction> score;
Brian Silverman6f621542014-04-06 16:00:41 -0700191
Austin Schuh80ff2e12014-03-08 12:06:19 -0800192 ResetDrivetrain();
193
194 if (ShouldExitAuto()) return;
195 InitializeEncoders();
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700196
Brian Silverman93936f72015-03-19 23:38:30 -0700197 time::SleepFor(time::Time::InSeconds(0.55));
198
199 if (!drivetrain_queue.goal.MakeWithBuilder()
200 .steering(0)
201 .throttle(0.5)
202 .quickturn(false)
203 .control_loop_driving(false)
204 .Send()) {
205 LOG(WARNING, "sending drivetrain goal failed\n");
206 }
207 time::SleepFor(time::Time::InSeconds(1.0));
208 if (!drivetrain_queue.goal.MakeWithBuilder()
209 .steering(0)
210 .throttle(0)
211 .quickturn(false)
212 .control_loop_driving(false)
213 .Send()) {
214 LOG(WARNING, "sending drivetrain goal failed\n");
215 }
216
217 return;
218
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700219 {
220 auto new_fridge_goal = fridge_queue.goal.MakeMessage();
221 new_fridge_goal->max_velocity = 0.0;
222 new_fridge_goal->max_acceleration = 0.0;
223 new_fridge_goal->profiling_type = 0;
224 new_fridge_goal->height = 0.3;
225 new_fridge_goal->velocity = 0.0;
226 new_fridge_goal->max_angular_velocity = 0.0;
227 new_fridge_goal->max_angular_acceleration = 0.0;
228 new_fridge_goal->angle = 0.0;
229 new_fridge_goal->angular_velocity = 0.0;
230 new_fridge_goal->grabbers.top_front = true;
231 new_fridge_goal->grabbers.top_back = true;
232 new_fridge_goal->grabbers.bottom_front = true;
233 new_fridge_goal->grabbers.bottom_back = true;
234
235 if (!new_fridge_goal.Send()) {
236 LOG(ERROR, "Sending fridge goal failed.\n");
237 return;
238 }
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700239 }
240
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700241 // Pick up the tote.
242 SetClawState(0.0, 7.0, true);
243 if (ShouldExitAuto()) return;
244 time::SleepFor(time::Time::InSeconds(0.1));
245 if (ShouldExitAuto()) return;
246
247 // now pick it up
248 {
249 actors::PickupParams params;
250 // Lift to here initially.
251 params.pickup_angle = 0.9;
252 // Start sucking here
253 params.suck_angle = 0.8;
254 // Go back down to here to finish sucking.
255 params.suck_angle_finish = 0.4;
256 // Pack the box back in here.
257 params.pickup_finish_angle = kClawTotePackAngle;
258 params.intake_time = 0.8;
259 params.intake_voltage = 7.0;
260 pickup = actors::MakePickupAction(params);
261 pickup->Start();
262 WaitUntilDoneOrCanceled(pickup.get());
263 }
264 if (ShouldExitAuto()) return;
265
266 drive = SetDriveGoal(1.0, false);
267 WaitUntilDoneOrCanceled(drive.get());
268
269 SetClawState(0.0, 0.0, true);
270 return;
271
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700272 if (ShouldExitAuto()) return;
273
274 if (false) {
275 // drive up to the next tote
276 drive = SetDriveGoal(1.0, false);
277 WaitUntilDoneOrCanceled(drive.get());
278 if (ShouldExitAuto()) return;
279
280 // suck in the tote
281 SetClawState(0.0, 7.0, true);
282 drive = SetDriveGoal(0.2, false);
283 WaitUntilDoneOrCanceled(drive.get());
284 SetClawState(0.0, 0.0, true);
285 if (ShouldExitAuto()) return;
286
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700287
288 // we should have the tote, now stack it
289 {
290 actors::StackParams params;
291 params.claw_out_angle = 0.6;
292 params.bottom = 0.020;
293 params.over_box_before_place_height = 0.39;
294 stack = actors::MakeStackAction(params);
295 WaitUntilDoneOrCanceled(stack.get());
296 }
297 if (ShouldExitAuto()) return;
298
299 // turn 90
300 DriveSpin(M_PI / 4.0);
301 if (ShouldExitAuto()) return;
302
303 // place the new stack
304 // TODO(austin): Score!
305 // score = MakeScoreAction(score_params);
306 // WaitUntilDoneOrCanceled(score.get());
307 }
Austin Schuh47017412013-03-10 11:50:46 -0700308}
309
310} // namespace autonomous
311} // namespace frc971