blob: afa602e6db888e23d12f4aa6ca134b0fbf02701a [file] [log] [blame]
Brian Silverman756f9ff2014-01-17 23:40:23 -08001#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <math.h>
5
6#include "aos/linux_code/init.h"
7#include "aos/prime/input/joystick_input.h"
Austin Schuh06cbbf12014-02-22 02:07:31 -08008#include "aos/common/input/driver_station_data.h"
Brian Silverman756f9ff2014-01-17 23:40:23 -08009#include "aos/common/logging/logging.h"
Brian Silvermana379f002014-03-22 19:34:53 -070010#include "aos/common/util/log_interval.h"
11#include "aos/common/time.h"
Brian Silverman756f9ff2014-01-17 23:40:23 -080012
13#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuh5d8c5e72014-03-07 20:24:34 -080014#include "frc971/constants.h"
Brian Silverman6bf0d3c2014-03-08 12:52:54 -080015#include "frc971/queues/other_sensors.q.h"
Brian Silverman756f9ff2014-01-17 23:40:23 -080016#include "frc971/autonomous/auto.q.h"
Brian Silvermanfac5c292014-02-17 15:26:57 -080017#include "frc971/control_loops/claw/claw.q.h"
18#include "frc971/control_loops/shooter/shooter.q.h"
Ben Fredricksonaa450452014-03-01 09:41:18 +000019#include "frc971/actions/shoot_action.q.h"
Austin Schuh80ff2e12014-03-08 12:06:19 -080020#include "frc971/actions/action_client.h"
21#include "frc971/actions/catch_action.q.h"
22#include "frc971/actions/shoot_action.h"
Brian Silverman756f9ff2014-01-17 23:40:23 -080023
24using ::frc971::control_loops::drivetrain;
Brian Silverman6bf0d3c2014-03-08 12:52:54 -080025using ::frc971::sensors::gyro_reading;
Brian Silverman756f9ff2014-01-17 23:40:23 -080026
27using ::aos::input::driver_station::ButtonLocation;
28using ::aos::input::driver_station::JoystickAxis;
29using ::aos::input::driver_station::ControlBit;
30
31namespace frc971 {
32namespace input {
33namespace joysticks {
34
35const ButtonLocation kDriveControlLoopEnable1(1, 7),
36 kDriveControlLoopEnable2(1, 11);
37const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
38const ButtonLocation kShiftHigh(2, 1), kShiftLow(2, 3);
39const ButtonLocation kQuickTurn(1, 5);
Austin Schuh58d23682014-02-23 01:39:50 -080040
Austin Schuh80ff2e12014-03-08 12:06:19 -080041const ButtonLocation kCatch(3, 10);
42
43const ButtonLocation kFire(3, 9);
Brian6faa7822014-03-31 18:00:28 -070044const ButtonLocation kUnload(1, 4);
45const ButtonLocation kReload(1, 2);
Austin Schuh58d23682014-02-23 01:39:50 -080046
Austin Schuh80ff2e12014-03-08 12:06:19 -080047const ButtonLocation kRollersOut(3, 8);
48const ButtonLocation kRollersIn(3, 3);
Austin Schuh58d23682014-02-23 01:39:50 -080049
Austin Schuh80ff2e12014-03-08 12:06:19 -080050const ButtonLocation kTuck(3, 4);
51const ButtonLocation kIntakePosition(3, 5);
52const ButtonLocation kIntakeOpenPosition(3, 11);
Brian6faa7822014-03-31 18:00:28 -070053const ButtonLocation kVerticalTuck(2, 6);
Austin Schuh80ff2e12014-03-08 12:06:19 -080054const JoystickAxis kFlipRobot(3, 3);
Austin Schuh58d23682014-02-23 01:39:50 -080055
Austin Schuh80ff2e12014-03-08 12:06:19 -080056const ButtonLocation kLongShot(3, 7);
57const ButtonLocation kMediumShot(3, 6);
58const ButtonLocation kShortShot(3, 2);
Brian6faa7822014-03-31 18:00:28 -070059const ButtonLocation kTrussShot(2, 11);
60const ButtonLocation kHumanPlayerShot(3, 1);
61
62const ButtonLocation kUserLeft(2, 7);
63const ButtonLocation kUserRight(2, 10);
Austin Schuh58d23682014-02-23 01:39:50 -080064
Brian Silverman18f6e642014-03-13 18:52:47 -070065const JoystickAxis kAdjustClawGoal(3, 2);
66const JoystickAxis kAdjustClawSeparation(3, 1);
67
Austin Schuh58d23682014-02-23 01:39:50 -080068struct ClawGoal {
69 double angle;
70 double separation;
71};
72
Austin Schuh5d8c5e72014-03-07 20:24:34 -080073struct ShotGoal {
74 ClawGoal claw;
75 double shot_power;
Brian Silvermana379f002014-03-22 19:34:53 -070076 double velocity_compensation;
Austin Schuh5d8c5e72014-03-07 20:24:34 -080077 double intake_power;
78};
79
Brian Silverman545f2ad2014-03-14 12:31:42 -070080const double kIntakePower = 4.0;
Brian Silvermanb3cf0ef2014-03-22 12:45:55 -070081// TODO(brians): This wants to be -0.04 on the comp bot. Make them both the
82// same.
83const double kGrabSeparation = 0;
Brian Silverman545f2ad2014-03-14 12:31:42 -070084const double kShootSeparation = 0.11 + kGrabSeparation;
85
Austin Schuh58d23682014-02-23 01:39:50 -080086const ClawGoal kTuckGoal = {-2.273474, -0.749484};
Brian6faa7822014-03-31 18:00:28 -070087const ClawGoal kVerticalTuckGoal = {0, kGrabSeparation};
Brian Silverman63ec7502014-03-30 18:09:10 -070088const ClawGoal kIntakeGoal = {-2.24, kGrabSeparation};
89const ClawGoal kIntakeOpenGoal = {-2.0, 1.1};
Austin Schuh58d23682014-02-23 01:39:50 -080090
Austin Schuh80ff2e12014-03-08 12:06:19 -080091// TODO(austin): Tune these by hand...
92const ClawGoal kFlippedTuckGoal = {2.733474, -0.75};
Brian Silverman545f2ad2014-03-14 12:31:42 -070093const ClawGoal kFlippedIntakeGoal = {2.0, kGrabSeparation};
Austin Schuh80ff2e12014-03-08 12:06:19 -080094const ClawGoal kFlippedIntakeOpenGoal = {0.95, 1.0};
95
Brian Silverman0e7c03e2014-03-23 17:06:24 -070096// 34" between near edge of colored line and rear edge of bumper
Austin Schuh5d8c5e72014-03-07 20:24:34 -080097const ShotGoal kLongShotGoal = {
Brian Silvermanedcfd2d2014-04-03 13:04:16 -070098 {-1.06, kShootSeparation}, 140, 0.04, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -070099// 3/4" plunger {-1.04, kShootSeparation}, 140, 0.04, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -0800100const ShotGoal kFlippedLongShotGoal = {
Brian Silverman73c48392014-04-05 07:07:41 -0700101 {0.96, kShootSeparation}, 140, 0.09, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700102// 3/4 " plunger {0.97, kShootSeparation}, 140, 0.08, kIntakePower};
103
104// 78" between near edge of colored line and rear edge of bumper
105const ShotGoal kMediumShotGoal = {
106 {-0.95, kShootSeparation}, 105, 0.2, kIntakePower};
107// 3/4" plunger {-0.90, kShootSeparation}, 105, 0.2, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -0800108const ShotGoal kFlippedMediumShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -0700109 {0.905, kShootSeparation}, 120, 0.2, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700110// 3/4" plunger {0.80, kShootSeparation}, 105, 0.2, kIntakePower};
111
112const ShotGoal kShortShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -0700113 {0.67, kShootSeparation}, 115.0, 0.4, kIntakePower};
Brian Silverman73c48392014-04-05 07:07:41 -0700114const ShotGoal kFlippedShortShotGoal = kShortShotGoal;
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700115
Brian Silverman63ec7502014-03-30 18:09:10 -0700116const ShotGoal kHumanShotGoal = {
117 {-0.90, kShootSeparation}, 140, 0.04, kIntakePower};
Brian Silverman73c48392014-04-05 07:07:41 -0700118const ShotGoal kFlippedHumanShotGoal = {
119 {0.90, kShootSeparation}, 140, 0, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700120const ShotGoal kTrussShotGoal = {
Brian Silverman73c48392014-04-05 07:07:41 -0700121 {-0.68, kShootSeparation}, 77.0, 0.4, kIntakePower};
122const ShotGoal kFlippedTrussShotGoal = {
123 {0.68, kShootSeparation}, 77.0, 0.4, kIntakePower};
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800124
125// Makes a new ShootAction action.
Austin Schuh80ff2e12014-03-08 12:06:19 -0800126::std::unique_ptr<TypedAction< ::frc971::actions::CatchActionGroup>>
127MakeCatchAction() {
128 return ::std::unique_ptr<TypedAction< ::frc971::actions::CatchActionGroup>>(
129 new TypedAction< ::frc971::actions::CatchActionGroup>(
130 &::frc971::actions::catch_action));
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800131}
132
133// A queue which queues Actions and cancels them.
134class ActionQueue {
135 public:
136 // Queues up an action for sending.
137 void QueueAction(::std::unique_ptr<Action> action) {
138 if (current_action_) {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800139 LOG(INFO, "Queueing action, canceling prior\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800140 current_action_->Cancel();
141 next_action_ = ::std::move(action);
142 } else {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800143 LOG(INFO, "Queueing action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800144 current_action_ = ::std::move(action);
145 current_action_->Start();
146 }
147 }
148
149 // Cancels the current action, and runs the next one when the current one has
150 // finished.
151 void CancelCurrentAction() {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800152 LOG(INFO, "Canceling current action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800153 if (current_action_) {
154 current_action_->Cancel();
155 }
156 }
157
158 // Cancels all running actions.
159 void CancelAllActions() {
Brian Silverman101b9642014-03-08 12:45:16 -0800160 LOG(DEBUG, "Cancelling all actions\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800161 if (current_action_) {
162 current_action_->Cancel();
163 }
164 next_action_.reset();
165 }
166
167 // Runs the next action when the current one is finished running.
168 void Tick() {
169 if (current_action_) {
170 if (!current_action_->Running()) {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800171 LOG(INFO, "Action is done.\n");
172 current_action_ = ::std::move(next_action_);
173 if (current_action_) {
174 LOG(INFO, "Running next action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800175 current_action_->Start();
176 }
177 }
178 }
179 }
180
181 // Returns true if any action is running or could be running.
182 // For a one cycle faster response, call Tick before running this.
183 bool Running() { return (bool)current_action_; }
184
185 private:
186 ::std::unique_ptr<Action> current_action_;
187 ::std::unique_ptr<Action> next_action_;
188};
189
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800190
Brian Silverman756f9ff2014-01-17 23:40:23 -0800191class Reader : public ::aos::input::JoystickInput {
192 public:
Austin Schuh58d23682014-02-23 01:39:50 -0800193 Reader()
194 : is_high_gear_(false),
Austin Schuh9cb836e2014-02-23 19:25:55 -0800195 shot_power_(80.0),
Austin Schuh58d23682014-02-23 01:39:50 -0800196 goal_angle_(0.0),
Brian Silverman545f2ad2014-03-14 12:31:42 -0700197 separation_angle_(kGrabSeparation),
Brian Silvermana379f002014-03-22 19:34:53 -0700198 velocity_compensation_(0.0),
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800199 intake_power_(0.0),
200 was_running_(false) {}
Brian Silverman756f9ff2014-01-17 23:40:23 -0800201
202 virtual void RunIteration(const ::aos::input::driver_station::Data &data) {
Brian Silverman756f9ff2014-01-17 23:40:23 -0800203 if (data.GetControlBit(ControlBit::kAutonomous)) {
204 if (data.PosEdge(ControlBit::kEnabled)){
205 LOG(INFO, "Starting auto mode\n");
206 ::frc971::autonomous::autonomous.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800207 .run_auto(true)
208 .Send();
Brian Silverman756f9ff2014-01-17 23:40:23 -0800209 } else if (data.NegEdge(ControlBit::kEnabled)) {
210 LOG(INFO, "Stopping auto mode\n");
211 ::frc971::autonomous::autonomous.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800212 .run_auto(false)
213 .Send();
Brian Silverman756f9ff2014-01-17 23:40:23 -0800214 }
Austin Schuh58d23682014-02-23 01:39:50 -0800215 } else {
216 HandleTeleop(data);
Brian Silverman756f9ff2014-01-17 23:40:23 -0800217 }
218 }
Austin Schuh58d23682014-02-23 01:39:50 -0800219
220 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
221 bool is_control_loop_driving = false;
222 double left_goal = 0.0;
223 double right_goal = 0.0;
224 const double wheel = -data.GetAxis(kSteeringWheel);
225 const double throttle = -data.GetAxis(kDriveThrottle);
226 const double kThrottleGain = 1.0 / 2.5;
227 if (false && (data.IsPressed(kDriveControlLoopEnable1) ||
228 data.IsPressed(kDriveControlLoopEnable2))) {
229 // TODO(austin): Static sucks!
230 static double distance = 0.0;
231 static double angle = 0.0;
232 static double filtered_goal_distance = 0.0;
233 if (data.PosEdge(kDriveControlLoopEnable1) ||
234 data.PosEdge(kDriveControlLoopEnable2)) {
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800235 if (drivetrain.position.FetchLatest() && gyro_reading.FetchLatest()) {
Austin Schuh58d23682014-02-23 01:39:50 -0800236 distance = (drivetrain.position->left_encoder +
237 drivetrain.position->right_encoder) /
238 2.0 -
239 throttle * kThrottleGain / 2.0;
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800240 angle = gyro_reading->angle;
Austin Schuh58d23682014-02-23 01:39:50 -0800241 filtered_goal_distance = distance;
242 }
243 }
244 is_control_loop_driving = true;
245
246 // const double gyro_angle = Gyro.View().angle;
247 const double goal_theta = angle - wheel * 0.27;
248 const double goal_distance = distance + throttle * kThrottleGain;
249 const double robot_width = 22.0 / 100.0 * 2.54;
250 const double kMaxVelocity = 0.6;
251 if (goal_distance > kMaxVelocity * 0.02 + filtered_goal_distance) {
252 filtered_goal_distance += kMaxVelocity * 0.02;
253 } else if (goal_distance <
254 -kMaxVelocity * 0.02 + filtered_goal_distance) {
255 filtered_goal_distance -= kMaxVelocity * 0.02;
256 } else {
257 filtered_goal_distance = goal_distance;
258 }
259 left_goal = filtered_goal_distance - robot_width * goal_theta / 2.0;
260 right_goal = filtered_goal_distance + robot_width * goal_theta / 2.0;
261 is_high_gear_ = false;
262
263 LOG(DEBUG, "Left goal %f Right goal %f\n", left_goal, right_goal);
264 }
265 if (!drivetrain.goal.MakeWithBuilder()
266 .steering(wheel)
267 .throttle(throttle)
268 .highgear(is_high_gear_)
269 .quickturn(data.IsPressed(kQuickTurn))
270 .control_loop_driving(is_control_loop_driving)
271 .left_goal(left_goal)
272 .right_goal(right_goal)
273 .Send()) {
274 LOG(WARNING, "sending stick values failed\n");
275 }
276 if (data.PosEdge(kShiftHigh)) {
277 is_high_gear_ = false;
278 }
279 if (data.PosEdge(kShiftLow)) {
280 is_high_gear_ = true;
281 }
282 }
283
284 void SetGoal(ClawGoal goal) {
285 goal_angle_ = goal.angle;
286 separation_angle_ = goal.separation;
Brian7e294392014-03-31 12:39:13 -0700287 moving_for_shot_ = false;
Brian Silvermana379f002014-03-22 19:34:53 -0700288 velocity_compensation_ = 0.0;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800289 intake_power_ = 0.0;
290 }
291
292 void SetGoal(ShotGoal goal) {
293 goal_angle_ = goal.claw.angle;
Brian7e294392014-03-31 12:39:13 -0700294 shot_separation_angle_ = goal.claw.separation;
295 separation_angle_ = kGrabSeparation;
296 moving_for_shot_ = true;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800297 shot_power_ = goal.shot_power;
298 velocity_compensation_ = goal.velocity_compensation;
299 intake_power_ = goal.intake_power;
Austin Schuh58d23682014-02-23 01:39:50 -0800300 }
301
302 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
303 HandleDrivetrain(data);
Austin Schuhc95c2b72014-03-02 11:56:49 -0800304 if (!data.GetControlBit(ControlBit::kEnabled)) {
305 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800306 LOG(DEBUG, "Canceling\n");
Austin Schuhc95c2b72014-03-02 11:56:49 -0800307 }
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800308 if (data.IsPressed(kRollersIn) || data.IsPressed(kRollersOut)) {
309 intake_power_ = 0.0;
Brian Silverman545f2ad2014-03-14 12:31:42 -0700310 separation_angle_ = kGrabSeparation;
Brian7e294392014-03-31 12:39:13 -0700311 moving_for_shot_ = false;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800312 }
Austin Schuh58d23682014-02-23 01:39:50 -0800313
Brian Silverman18f6e642014-03-13 18:52:47 -0700314 static const double kAdjustClawGoalDeadband = 0.08;
315 double claw_goal_adjust = data.GetAxis(kAdjustClawGoal);
316 if (::std::abs(claw_goal_adjust) < kAdjustClawGoalDeadband) {
317 claw_goal_adjust = 0;
318 } else {
319 claw_goal_adjust = (claw_goal_adjust -
320 ((claw_goal_adjust < 0) ? -kAdjustClawGoalDeadband
321 : kAdjustClawGoalDeadband)) *
322 0.035;
323 }
324 double claw_separation_adjust = data.GetAxis(kAdjustClawSeparation);
325 if (::std::abs(claw_separation_adjust) < kAdjustClawGoalDeadband) {
326 claw_separation_adjust = 0;
327 } else {
328 claw_separation_adjust =
329 (claw_separation_adjust -
330 ((claw_separation_adjust < 0) ? -kAdjustClawGoalDeadband
331 : kAdjustClawGoalDeadband)) *
332 -0.035;
333 }
334
Brian6faa7822014-03-31 18:00:28 -0700335 if (data.GetAxis(kFlipRobot) > 0.9) {
Brian Silverman18f6e642014-03-13 18:52:47 -0700336 claw_goal_adjust += claw_separation_adjust;
337 claw_goal_adjust *= -1;
338
Austin Schuh80ff2e12014-03-08 12:06:19 -0800339 if (data.IsPressed(kIntakeOpenPosition)) {
340 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800341 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800342 SetGoal(kFlippedIntakeOpenGoal);
343 } else if (data.IsPressed(kIntakePosition)) {
344 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800345 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800346 SetGoal(kFlippedIntakeGoal);
Brian6faa7822014-03-31 18:00:28 -0700347 } else if (data.IsPressed(kVerticalTuck)) {
348 action_queue_.CancelAllActions();
349 LOG(DEBUG, "Canceling\n");
350 SetGoal(kVerticalTuckGoal);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800351 } else if (data.IsPressed(kTuck)) {
352 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800353 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800354 SetGoal(kFlippedTuckGoal);
355 } else if (data.PosEdge(kLongShot)) {
356 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800357 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800358 SetGoal(kFlippedLongShotGoal);
359 } else if (data.PosEdge(kMediumShot)) {
360 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800361 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800362 SetGoal(kFlippedMediumShotGoal);
363 } else if (data.PosEdge(kShortShot)) {
364 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800365 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800366 SetGoal(kFlippedShortShotGoal);
Brian6faa7822014-03-31 18:00:28 -0700367 } else if (data.PosEdge(kHumanPlayerShot)) {
368 action_queue_.CancelAllActions();
369 LOG(DEBUG, "Canceling\n");
Brian Silverman73c48392014-04-05 07:07:41 -0700370 SetGoal(kFlippedHumanShotGoal);
Austin Schuhade6d082014-03-09 00:53:06 -0800371 } else if (data.PosEdge(kTrussShot)) {
372 action_queue_.CancelAllActions();
373 LOG(DEBUG, "Canceling\n");
Brian Silverman73c48392014-04-05 07:07:41 -0700374 SetGoal(kFlippedTrussShotGoal);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800375 }
376 } else {
377 if (data.IsPressed(kIntakeOpenPosition)) {
378 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800379 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800380 SetGoal(kIntakeOpenGoal);
381 } else if (data.IsPressed(kIntakePosition)) {
382 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800383 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800384 SetGoal(kIntakeGoal);
Brian6faa7822014-03-31 18:00:28 -0700385 } else if (data.IsPressed(kVerticalTuck)) {
386 action_queue_.CancelAllActions();
387 LOG(DEBUG, "Canceling\n");
388 SetGoal(kVerticalTuckGoal);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800389 } else if (data.IsPressed(kTuck)) {
390 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800391 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800392 SetGoal(kTuckGoal);
393 } else if (data.PosEdge(kLongShot)) {
394 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800395 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800396 SetGoal(kLongShotGoal);
397 } else if (data.PosEdge(kMediumShot)) {
398 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800399 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800400 SetGoal(kMediumShotGoal);
401 } else if (data.PosEdge(kShortShot)) {
402 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800403 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800404 SetGoal(kShortShotGoal);
Brian6faa7822014-03-31 18:00:28 -0700405 } else if (data.PosEdge(kHumanPlayerShot)) {
406 action_queue_.CancelAllActions();
407 LOG(DEBUG, "Canceling\n");
408 SetGoal(kHumanShotGoal);
Austin Schuhade6d082014-03-09 00:53:06 -0800409 } else if (data.PosEdge(kTrussShot)) {
410 action_queue_.CancelAllActions();
411 LOG(DEBUG, "Canceling\n");
412 SetGoal(kTrussShotGoal);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800413 }
Austin Schuh58d23682014-02-23 01:39:50 -0800414 }
415
Austin Schuhade6d082014-03-09 00:53:06 -0800416 /*
Austin Schuh80ff2e12014-03-08 12:06:19 -0800417 if (data.PosEdge(kCatch)) {
418 auto catch_action = MakeCatchAction();
419 catch_action->GetGoal()->catch_angle = goal_angle_;
420 action_queue_.QueueAction(::std::move(catch_action));
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800421 }
Austin Schuhade6d082014-03-09 00:53:06 -0800422 */
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800423
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800424 if (data.PosEdge(kFire)) {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800425 action_queue_.QueueAction(actions::MakeShootAction());
Brian Silverman9f863a02014-03-29 17:42:36 -0700426 } else if (data.NegEdge(kFire)) {
427 action_queue_.CancelCurrentAction();
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800428 }
429
430 action_queue_.Tick();
Austin Schuhc95c2b72014-03-02 11:56:49 -0800431 if (data.IsPressed(kUnload) || data.IsPressed(kReload)) {
432 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800433 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800434 intake_power_ = 0.0;
Brian Silvermana379f002014-03-22 19:34:53 -0700435 velocity_compensation_ = 0.0;
Austin Schuhc95c2b72014-03-02 11:56:49 -0800436 }
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800437
438 // Send out the claw and shooter goals if no actions are running.
439 if (!action_queue_.Running()) {
Brian Silverman18f6e642014-03-13 18:52:47 -0700440 goal_angle_ += claw_goal_adjust;
441 separation_angle_ += claw_separation_adjust;
442
Austin Schuh80ff2e12014-03-08 12:06:19 -0800443 // If the action just ended, turn the intake off and stop velocity
444 // compensating.
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800445 if (was_running_) {
446 intake_power_ = 0.0;
Brian Silvermana379f002014-03-22 19:34:53 -0700447 velocity_compensation_ = 0.0;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800448 }
449
450 control_loops::drivetrain.status.FetchLatest();
Brian Silvermana379f002014-03-22 19:34:53 -0700451 double goal_angle = goal_angle_;
452 if (control_loops::drivetrain.status.get()) {
453 goal_angle +=
454 SpeedToAngleOffset(control_loops::drivetrain.status->robot_speed);
455 } else {
456 LOG_INTERVAL(no_drivetrain_status_);
457 }
Brian7e294392014-03-31 12:39:13 -0700458
459 if (moving_for_shot_) {
460 auto &claw_status = control_loops::claw_queue_group.status;
461 claw_status.FetchLatest();
462 if (claw_status.get()) {
Brian6faa7822014-03-31 18:00:28 -0700463 if (::std::abs(claw_status->bottom - goal_angle) < 0.2) {
Brian7e294392014-03-31 12:39:13 -0700464 moving_for_shot_ = false;
465 separation_angle_ = shot_separation_angle_;
466 }
467 }
468 }
469
Austin Schuhade6d082014-03-09 00:53:06 -0800470 double separation_angle = separation_angle_;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800471
Austin Schuhade6d082014-03-09 00:53:06 -0800472 if (data.IsPressed(kCatch)) {
473 const double kCatchSeparation = 1.0;
474 goal_angle -= kCatchSeparation / 2.0;
475 separation_angle = kCatchSeparation;
476 }
477
478 bool intaking =
479 data.IsPressed(kRollersIn) || data.IsPressed(kIntakePosition) ||
480 data.IsPressed(kIntakeOpenPosition) || data.IsPressed(kCatch);
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800481 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800482 .bottom_angle(goal_angle)
Austin Schuhade6d082014-03-09 00:53:06 -0800483 .separation_angle(separation_angle)
Austin Schuh80ff2e12014-03-08 12:06:19 -0800484 .intake(intaking ? 12.0
485 : (data.IsPressed(kRollersOut) ? -12.0
486 : intake_power_))
487 .centering(intaking ? 12.0 : 0.0)
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800488 .Send()) {
489 LOG(WARNING, "sending claw goal failed\n");
490 }
491
492 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
493 .shot_power(shot_power_)
494 .shot_requested(data.IsPressed(kFire))
495 .unload_requested(data.IsPressed(kUnload))
496 .load_requested(data.IsPressed(kReload))
497 .Send()) {
498 LOG(WARNING, "sending shooter goal failed\n");
499 }
Austin Schuh58d23682014-02-23 01:39:50 -0800500 }
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800501 was_running_ = action_queue_.Running();
502 }
503
504 double SpeedToAngleOffset(double speed) {
505 const frc971::constants::Values &values = frc971::constants::GetValues();
506 // scale speed to a [0.0-1.0] on something close to the max
507 // TODO(austin): Change the scale factor for different shots.
Brian Silvermana379f002014-03-22 19:34:53 -0700508 return (speed / values.drivetrain_max_speed) * velocity_compensation_;
Austin Schuh58d23682014-02-23 01:39:50 -0800509 }
510
Austin Schuh01c652b2014-02-21 23:13:42 -0800511 private:
Austin Schuh58d23682014-02-23 01:39:50 -0800512 bool is_high_gear_;
513 double shot_power_;
514 double goal_angle_;
Brian7e294392014-03-31 12:39:13 -0700515 double separation_angle_, shot_separation_angle_;
Brian Silvermana379f002014-03-22 19:34:53 -0700516 double velocity_compensation_;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800517 double intake_power_;
518 bool was_running_;
Brian7e294392014-03-31 12:39:13 -0700519 bool moving_for_shot_ = false;
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800520
521 ActionQueue action_queue_;
Brian Silvermana379f002014-03-22 19:34:53 -0700522
523 ::aos::util::SimpleLogInterval no_drivetrain_status_ =
524 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.2), WARNING,
525 "no drivetrain status");
Brian Silverman756f9ff2014-01-17 23:40:23 -0800526};
527
528} // namespace joysticks
529} // namespace input
530} // namespace frc971
531
532int main() {
533 ::aos::Init();
534 ::frc971::input::joysticks::Reader reader;
535 reader.Run();
536 ::aos::Cleanup();
537}