blob: e420aa6e66edb18dad7610467142bb976561fddc [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;
Austin Schuh47017412013-03-10 11:50:46 -070023
24namespace frc971 {
25namespace autonomous {
26
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070027constexpr double kClawAutoVelocity = 3.00;
28constexpr double kClawAutoAcceleration = 6.0;
29constexpr double kAngleEpsilon = 0.10;
30double kClawTotePackAngle = 0.95;
31
Austin Schuh80ff2e12014-03-08 12:06:19 -080032namespace time = ::aos::time;
33
Brian Silverman3b89ed82013-03-22 18:59:16 -070034static double left_initial_position, right_initial_position;
35
Austin Schuh6be011a2013-03-19 10:07:02 +000036bool ShouldExitAuto() {
37 ::frc971::autonomous::autonomous.FetchLatest();
38 bool ans = !::frc971::autonomous::autonomous->run_auto;
39 if (ans) {
40 LOG(INFO, "Time to exit auto mode\n");
41 }
42 return ans;
43}
44
Austin Schuh6be011a2013-03-19 10:07:02 +000045void StopDrivetrain() {
46 LOG(INFO, "Stopping the drivetrain\n");
Brian Silvermanada5f2c2015-02-01 02:41:14 -050047 control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070048 .control_loop_driving(true)
Brian Silvermance86bac2013-03-31 19:07:24 -070049 .left_goal(left_initial_position)
50 .left_velocity_goal(0)
51 .right_goal(right_initial_position)
52 .right_velocity_goal(0)
53 .quickturn(false)
54 .Send();
55}
56
57void ResetDrivetrain() {
58 LOG(INFO, "resetting the drivetrain\n");
Brian Silvermanada5f2c2015-02-01 02:41:14 -050059 control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silvermance86bac2013-03-31 19:07:24 -070060 .control_loop_driving(false)
Brian Silverman93335ae2015-01-26 20:43:39 -050061 //.highgear(false)
Austin Schuh6be011a2013-03-19 10:07:02 +000062 .steering(0.0)
63 .throttle(0.0)
Brian Silverman38ea9bf2014-04-19 22:57:54 -070064 .left_goal(left_initial_position)
65 .left_velocity_goal(0)
66 .right_goal(right_initial_position)
67 .right_velocity_goal(0)
Austin Schuh6be011a2013-03-19 10:07:02 +000068 .Send();
69}
70
Brian Silverman3b89ed82013-03-22 18:59:16 -070071void DriveSpin(double radians) {
72 LOG(INFO, "going to spin %f\n", radians);
73
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080074 // TODO(sensors): update this time thing maybe?
Brian Silverman3b89ed82013-03-22 18:59:16 -070075 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
76 ::Eigen::Matrix<double, 2, 1> driveTrainState;
77 const double goal_velocity = 0.0;
78 const double epsilon = 0.01;
Brian Silverman13be6682013-03-22 21:02:07 -070079 // in drivetrain "meters"
Brian Silverman3b89ed82013-03-22 18:59:16 -070080 const double kRobotWidth = 0.4544;
81
Brian Silverman7992d6e2013-03-24 19:20:54 -070082 profile.set_maximum_acceleration(1.5);
83 profile.set_maximum_velocity(0.8);
Brian Silverman3b89ed82013-03-22 18:59:16 -070084
85 const double side_offset = kRobotWidth * radians / 2.0;
86
87 while (true) {
Brian Silverman547abb32015-02-16 00:37:48 -050088 ::aos::time::PhasedLoopXMS(5, 2500);
Brian Silverman3b89ed82013-03-22 18:59:16 -070089 driveTrainState = profile.Update(side_offset, goal_velocity);
90
91 if (::std::abs(driveTrainState(0, 0) - side_offset) < epsilon) break;
92 if (ShouldExitAuto()) return;
93
94 LOG(DEBUG, "Driving left to %f, right to %f\n",
Brian Silverman7992d6e2013-03-24 19:20:54 -070095 left_initial_position - driveTrainState(0, 0),
96 right_initial_position + driveTrainState(0, 0));
Brian Silvermanada5f2c2015-02-01 02:41:14 -050097 control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070098 .control_loop_driving(true)
Brian Silverman93335ae2015-01-26 20:43:39 -050099 //.highgear(false)
Brian Silverman7992d6e2013-03-24 19:20:54 -0700100 .left_goal(left_initial_position - driveTrainState(0, 0))
101 .right_goal(right_initial_position + driveTrainState(0, 0))
102 .left_velocity_goal(-driveTrainState(1, 0))
103 .right_velocity_goal(driveTrainState(1, 0))
Brian Silverman3b89ed82013-03-22 18:59:16 -0700104 .Send();
105 }
Brian Silverman7992d6e2013-03-24 19:20:54 -0700106 left_initial_position -= side_offset;
107 right_initial_position += side_offset;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700108 LOG(INFO, "Done moving\n");
109}
110
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800111void WaitUntilDoneOrCanceled(aos::common::actions::Action *action) {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800112 while (true) {
113 // Poll the running bit and auto done bits.
Brian Silverman547abb32015-02-16 00:37:48 -0500114 ::aos::time::PhasedLoopXMS(5, 2500);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800115 if (!action->Running() || ShouldExitAuto()) {
116 return;
117 }
118 }
119}
120
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800121::std::unique_ptr<::frc971::actors::DrivetrainAction> SetDriveGoal(
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700122 double distance, bool slow_acceleration, double maximum_velocity = 0.7,
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800123 double theta = 0) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800124 LOG(INFO, "Driving to %f\n", distance);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800125
126 ::frc971::actors::DrivetrainActionParams params;
127 params.left_initial_position = left_initial_position;
128 params.right_initial_position = right_initial_position;
129 params.y_offset = distance;
130 params.theta_offset = theta;
131 params.maximum_velocity = maximum_velocity;
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700132 params.maximum_acceleration = slow_acceleration ? 0.3 : 0.2;
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800133 auto drivetrain_action = actors::MakeDrivetrainAction(params);
134
Austin Schuh80ff2e12014-03-08 12:06:19 -0800135 drivetrain_action->Start();
Brian Silvermanad9e0002014-04-13 14:55:57 -0700136 left_initial_position +=
137 distance - theta * constants::GetValues().turn_width / 2.0;
138 right_initial_position +=
Daniel Pettib0733be2014-11-14 22:44:03 -0800139 distance + theta * constants::GetValues().turn_width / 2.0;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800140 return ::std::move(drivetrain_action);
141}
142
143void InitializeEncoders() {
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500144 control_loops::drivetrain_queue.status.FetchLatest();
145 while (!control_loops::drivetrain_queue.status.get()) {
Brian Silverman2c1e0342014-04-11 16:15:01 -0700146 LOG(WARNING,
147 "No previous drivetrain position packet, trying to fetch again\n");
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500148 control_loops::drivetrain_queue.status.FetchNextBlocking();
Brian Silverman3b89ed82013-03-22 18:59:16 -0700149 }
150 left_initial_position =
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500151 control_loops::drivetrain_queue.status->filtered_left_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700152 right_initial_position =
Brian Silvermanada5f2c2015-02-01 02:41:14 -0500153 control_loops::drivetrain_queue.status->filtered_right_position;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800154}
155
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700156void SetClawState(double angle, double intake_voltage, double rollers_closed) {
157 auto message = control_loops::claw_queue.goal.MakeMessage();
158 message->angle = angle;
159 message->max_velocity = kClawAutoVelocity;
160 message->max_acceleration = kClawAutoAcceleration;
161 message->angular_velocity = 0.0;
162 message->intake = intake_voltage;
163 message->rollers_closed = rollers_closed;
164
165 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
166 message.Send();
167
168 while (true) {
169 control_loops::claw_queue.status.FetchAnother();
170 const double current_angle = control_loops::claw_queue.status->angle;
171 LOG_STRUCT(DEBUG, "Got claw status", *control_loops::claw_queue.status);
172
173 // I believe all we can care about here is the angle. Other values will
174 // either be set or not, but there is nothing we can do about it. If it
175 // never gets there we do not care, auto is over for us.
176 if (::std::abs(current_angle - angle) < kAngleEpsilon) {
177 break;
178 }
179 }
180}
181
Austin Schuh80ff2e12014-03-08 12:06:19 -0800182void HandleAuto() {
Austin Schuh577edf62014-04-13 10:33:05 -0700183 ::aos::time::Time start_time = ::aos::time::Time::Now();
Brian Silverman20141f92015-01-05 17:39:01 -0800184 LOG(INFO, "Handling auto mode at %f\n", start_time.ToSeconds());
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700185 ::std::unique_ptr<::frc971::actors::DrivetrainAction> drive;
186 ::std::unique_ptr<::frc971::actors::PickupAction> pickup;
187 ::std::unique_ptr<::frc971::actors::StackAction> stack;
188 // TODO(austin): Score!
189 //::std::unique_ptr<ScoreAction> score;
Brian Silverman6f621542014-04-06 16:00:41 -0700190
Austin Schuh80ff2e12014-03-08 12:06:19 -0800191 ResetDrivetrain();
192
193 if (ShouldExitAuto()) return;
194 InitializeEncoders();
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700195
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700196 {
197 auto new_fridge_goal = fridge_queue.goal.MakeMessage();
198 new_fridge_goal->max_velocity = 0.0;
199 new_fridge_goal->max_acceleration = 0.0;
200 new_fridge_goal->profiling_type = 0;
201 new_fridge_goal->height = 0.3;
202 new_fridge_goal->velocity = 0.0;
203 new_fridge_goal->max_angular_velocity = 0.0;
204 new_fridge_goal->max_angular_acceleration = 0.0;
205 new_fridge_goal->angle = 0.0;
206 new_fridge_goal->angular_velocity = 0.0;
207 new_fridge_goal->grabbers.top_front = true;
208 new_fridge_goal->grabbers.top_back = true;
209 new_fridge_goal->grabbers.bottom_front = true;
210 new_fridge_goal->grabbers.bottom_back = true;
211
212 if (!new_fridge_goal.Send()) {
213 LOG(ERROR, "Sending fridge goal failed.\n");
214 return;
215 }
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700216 }
217
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700218 // Pick up the tote.
219 SetClawState(0.0, 7.0, true);
220 if (ShouldExitAuto()) return;
221 time::SleepFor(time::Time::InSeconds(0.1));
222 if (ShouldExitAuto()) return;
223
224 // now pick it up
225 {
226 actors::PickupParams params;
227 // Lift to here initially.
228 params.pickup_angle = 0.9;
229 // Start sucking here
230 params.suck_angle = 0.8;
231 // Go back down to here to finish sucking.
232 params.suck_angle_finish = 0.4;
233 // Pack the box back in here.
234 params.pickup_finish_angle = kClawTotePackAngle;
235 params.intake_time = 0.8;
236 params.intake_voltage = 7.0;
237 pickup = actors::MakePickupAction(params);
238 pickup->Start();
239 WaitUntilDoneOrCanceled(pickup.get());
240 }
241 if (ShouldExitAuto()) return;
242
243 drive = SetDriveGoal(1.0, false);
244 WaitUntilDoneOrCanceled(drive.get());
245
246 SetClawState(0.0, 0.0, true);
247 return;
248
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700249 if (ShouldExitAuto()) return;
250
251 if (false) {
252 // drive up to the next tote
253 drive = SetDriveGoal(1.0, false);
254 WaitUntilDoneOrCanceled(drive.get());
255 if (ShouldExitAuto()) return;
256
257 // suck in the tote
258 SetClawState(0.0, 7.0, true);
259 drive = SetDriveGoal(0.2, false);
260 WaitUntilDoneOrCanceled(drive.get());
261 SetClawState(0.0, 0.0, true);
262 if (ShouldExitAuto()) return;
263
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700264
265 // we should have the tote, now stack it
266 {
267 actors::StackParams params;
268 params.claw_out_angle = 0.6;
269 params.bottom = 0.020;
270 params.over_box_before_place_height = 0.39;
271 stack = actors::MakeStackAction(params);
272 WaitUntilDoneOrCanceled(stack.get());
273 }
274 if (ShouldExitAuto()) return;
275
276 // turn 90
277 DriveSpin(M_PI / 4.0);
278 if (ShouldExitAuto()) return;
279
280 // place the new stack
281 // TODO(austin): Score!
282 // score = MakeScoreAction(score_params);
283 // WaitUntilDoneOrCanceled(score.get());
284 }
Austin Schuh47017412013-03-10 11:50:46 -0700285}
286
287} // namespace autonomous
288} // namespace frc971