blob: 82f53b4f63c84a51d408893cd2060b2aa9905978 [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);
Austin Schuh9cb836e2014-02-23 19:25:55 -080044const ButtonLocation kUnload(2, 11);
45const ButtonLocation kReload(2, 6);
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);
Austin Schuh80ff2e12014-03-08 12:06:19 -080053const JoystickAxis kFlipRobot(3, 3);
Austin Schuh58d23682014-02-23 01:39:50 -080054
Austin Schuh80ff2e12014-03-08 12:06:19 -080055const ButtonLocation kLongShot(3, 7);
56const ButtonLocation kMediumShot(3, 6);
57const ButtonLocation kShortShot(3, 2);
Austin Schuhade6d082014-03-09 00:53:06 -080058const ButtonLocation kTrussShot(3, 1);
Austin Schuh58d23682014-02-23 01:39:50 -080059
Brian Silverman18f6e642014-03-13 18:52:47 -070060const JoystickAxis kAdjustClawGoal(3, 2);
61const JoystickAxis kAdjustClawSeparation(3, 1);
62
Austin Schuh58d23682014-02-23 01:39:50 -080063struct ClawGoal {
64 double angle;
65 double separation;
66};
67
Austin Schuh5d8c5e72014-03-07 20:24:34 -080068struct ShotGoal {
69 ClawGoal claw;
70 double shot_power;
Brian Silvermana379f002014-03-22 19:34:53 -070071 double velocity_compensation;
Austin Schuh5d8c5e72014-03-07 20:24:34 -080072 double intake_power;
73};
74
Brian Silverman545f2ad2014-03-14 12:31:42 -070075const double kIntakePower = 4.0;
Brian Silvermanb3cf0ef2014-03-22 12:45:55 -070076// TODO(brians): This wants to be -0.04 on the comp bot. Make them both the
77// same.
78const double kGrabSeparation = 0;
Brian Silverman545f2ad2014-03-14 12:31:42 -070079const double kShootSeparation = 0.11 + kGrabSeparation;
80
Austin Schuh58d23682014-02-23 01:39:50 -080081const ClawGoal kTuckGoal = {-2.273474, -0.749484};
Brian Silverman545f2ad2014-03-14 12:31:42 -070082const ClawGoal kIntakeGoal = {-2.273474, kGrabSeparation};
Austin Schuh9cb836e2014-02-23 19:25:55 -080083const ClawGoal kIntakeOpenGoal = {-2.0, 1.2};
Austin Schuh58d23682014-02-23 01:39:50 -080084
Austin Schuh80ff2e12014-03-08 12:06:19 -080085// TODO(austin): Tune these by hand...
86const ClawGoal kFlippedTuckGoal = {2.733474, -0.75};
Brian Silverman545f2ad2014-03-14 12:31:42 -070087const ClawGoal kFlippedIntakeGoal = {2.0, kGrabSeparation};
Austin Schuh80ff2e12014-03-08 12:06:19 -080088const ClawGoal kFlippedIntakeOpenGoal = {0.95, 1.0};
89
Brian Silverman0e7c03e2014-03-23 17:06:24 -070090// 34" between near edge of colored line and rear edge of bumper
Austin Schuh5d8c5e72014-03-07 20:24:34 -080091const ShotGoal kLongShotGoal = {
Brian Silverman0e7c03e2014-03-23 17:06:24 -070092 {-1.06, kShootSeparation}, 140, 0.04, kIntakePower};
93// 3/4" plunger {-1.04, kShootSeparation}, 140, 0.04, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -080094const ShotGoal kFlippedLongShotGoal = {
Brian Silverman9f863a02014-03-29 17:42:36 -070095 {0.90, kShootSeparation}, 140, 0.09, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -070096// 3/4 " plunger {0.97, kShootSeparation}, 140, 0.08, kIntakePower};
97
98// 78" between near edge of colored line and rear edge of bumper
99const ShotGoal kMediumShotGoal = {
100 {-0.95, kShootSeparation}, 105, 0.2, kIntakePower};
101// 3/4" plunger {-0.90, kShootSeparation}, 105, 0.2, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -0800102const ShotGoal kFlippedMediumShotGoal = {
Brian Silvermana379f002014-03-22 19:34:53 -0700103 {0.80, kShootSeparation}, 105, 0.2, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700104// 3/4" plunger {0.80, kShootSeparation}, 105, 0.2, kIntakePower};
105
106const ShotGoal kShortShotGoal = {
Brian Silverman9f863a02014-03-29 17:42:36 -0700107 {-0.670, kShootSeparation}, 72.0, 0.4, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -0800108const ShotGoal kFlippedShortShotGoal = {
Brian Silverman9f863a02014-03-29 17:42:36 -0700109 {0.57, kShootSeparation}, 82.0, 0.4, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700110
111const ShotGoal kTrussShotGoal = {
112 {-0.05, kShootSeparation}, 73.0, 0, kIntakePower};
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800113
114// Makes a new ShootAction action.
Austin Schuh80ff2e12014-03-08 12:06:19 -0800115::std::unique_ptr<TypedAction< ::frc971::actions::CatchActionGroup>>
116MakeCatchAction() {
117 return ::std::unique_ptr<TypedAction< ::frc971::actions::CatchActionGroup>>(
118 new TypedAction< ::frc971::actions::CatchActionGroup>(
119 &::frc971::actions::catch_action));
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800120}
121
122// A queue which queues Actions and cancels them.
123class ActionQueue {
124 public:
125 // Queues up an action for sending.
126 void QueueAction(::std::unique_ptr<Action> action) {
127 if (current_action_) {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800128 LOG(INFO, "Queueing action, canceling prior\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800129 current_action_->Cancel();
130 next_action_ = ::std::move(action);
131 } else {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800132 LOG(INFO, "Queueing action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800133 current_action_ = ::std::move(action);
134 current_action_->Start();
135 }
136 }
137
138 // Cancels the current action, and runs the next one when the current one has
139 // finished.
140 void CancelCurrentAction() {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800141 LOG(INFO, "Canceling current action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800142 if (current_action_) {
143 current_action_->Cancel();
144 }
145 }
146
147 // Cancels all running actions.
148 void CancelAllActions() {
Brian Silverman101b9642014-03-08 12:45:16 -0800149 LOG(DEBUG, "Cancelling all actions\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800150 if (current_action_) {
151 current_action_->Cancel();
152 }
153 next_action_.reset();
154 }
155
156 // Runs the next action when the current one is finished running.
157 void Tick() {
158 if (current_action_) {
159 if (!current_action_->Running()) {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800160 LOG(INFO, "Action is done.\n");
161 current_action_ = ::std::move(next_action_);
162 if (current_action_) {
163 LOG(INFO, "Running next action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800164 current_action_->Start();
165 }
166 }
167 }
168 }
169
170 // Returns true if any action is running or could be running.
171 // For a one cycle faster response, call Tick before running this.
172 bool Running() { return (bool)current_action_; }
173
174 private:
175 ::std::unique_ptr<Action> current_action_;
176 ::std::unique_ptr<Action> next_action_;
177};
178
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800179
Brian Silverman756f9ff2014-01-17 23:40:23 -0800180class Reader : public ::aos::input::JoystickInput {
181 public:
Austin Schuh58d23682014-02-23 01:39:50 -0800182 Reader()
183 : is_high_gear_(false),
Austin Schuh9cb836e2014-02-23 19:25:55 -0800184 shot_power_(80.0),
Austin Schuh58d23682014-02-23 01:39:50 -0800185 goal_angle_(0.0),
Brian Silverman545f2ad2014-03-14 12:31:42 -0700186 separation_angle_(kGrabSeparation),
Brian Silvermana379f002014-03-22 19:34:53 -0700187 velocity_compensation_(0.0),
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800188 intake_power_(0.0),
189 was_running_(false) {}
Brian Silverman756f9ff2014-01-17 23:40:23 -0800190
191 virtual void RunIteration(const ::aos::input::driver_station::Data &data) {
Brian Silverman756f9ff2014-01-17 23:40:23 -0800192 if (data.GetControlBit(ControlBit::kAutonomous)) {
193 if (data.PosEdge(ControlBit::kEnabled)){
194 LOG(INFO, "Starting auto mode\n");
195 ::frc971::autonomous::autonomous.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800196 .run_auto(true)
197 .Send();
Brian Silverman756f9ff2014-01-17 23:40:23 -0800198 } else if (data.NegEdge(ControlBit::kEnabled)) {
199 LOG(INFO, "Stopping auto mode\n");
200 ::frc971::autonomous::autonomous.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800201 .run_auto(false)
202 .Send();
Brian Silverman756f9ff2014-01-17 23:40:23 -0800203 }
Austin Schuh58d23682014-02-23 01:39:50 -0800204 } else {
205 HandleTeleop(data);
Brian Silverman756f9ff2014-01-17 23:40:23 -0800206 }
207 }
Austin Schuh58d23682014-02-23 01:39:50 -0800208
209 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
210 bool is_control_loop_driving = false;
211 double left_goal = 0.0;
212 double right_goal = 0.0;
213 const double wheel = -data.GetAxis(kSteeringWheel);
214 const double throttle = -data.GetAxis(kDriveThrottle);
215 const double kThrottleGain = 1.0 / 2.5;
216 if (false && (data.IsPressed(kDriveControlLoopEnable1) ||
217 data.IsPressed(kDriveControlLoopEnable2))) {
218 // TODO(austin): Static sucks!
219 static double distance = 0.0;
220 static double angle = 0.0;
221 static double filtered_goal_distance = 0.0;
222 if (data.PosEdge(kDriveControlLoopEnable1) ||
223 data.PosEdge(kDriveControlLoopEnable2)) {
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800224 if (drivetrain.position.FetchLatest() && gyro_reading.FetchLatest()) {
Austin Schuh58d23682014-02-23 01:39:50 -0800225 distance = (drivetrain.position->left_encoder +
226 drivetrain.position->right_encoder) /
227 2.0 -
228 throttle * kThrottleGain / 2.0;
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800229 angle = gyro_reading->angle;
Austin Schuh58d23682014-02-23 01:39:50 -0800230 filtered_goal_distance = distance;
231 }
232 }
233 is_control_loop_driving = true;
234
235 // const double gyro_angle = Gyro.View().angle;
236 const double goal_theta = angle - wheel * 0.27;
237 const double goal_distance = distance + throttle * kThrottleGain;
238 const double robot_width = 22.0 / 100.0 * 2.54;
239 const double kMaxVelocity = 0.6;
240 if (goal_distance > kMaxVelocity * 0.02 + filtered_goal_distance) {
241 filtered_goal_distance += kMaxVelocity * 0.02;
242 } else if (goal_distance <
243 -kMaxVelocity * 0.02 + filtered_goal_distance) {
244 filtered_goal_distance -= kMaxVelocity * 0.02;
245 } else {
246 filtered_goal_distance = goal_distance;
247 }
248 left_goal = filtered_goal_distance - robot_width * goal_theta / 2.0;
249 right_goal = filtered_goal_distance + robot_width * goal_theta / 2.0;
250 is_high_gear_ = false;
251
252 LOG(DEBUG, "Left goal %f Right goal %f\n", left_goal, right_goal);
253 }
254 if (!drivetrain.goal.MakeWithBuilder()
255 .steering(wheel)
256 .throttle(throttle)
257 .highgear(is_high_gear_)
258 .quickturn(data.IsPressed(kQuickTurn))
259 .control_loop_driving(is_control_loop_driving)
260 .left_goal(left_goal)
261 .right_goal(right_goal)
262 .Send()) {
263 LOG(WARNING, "sending stick values failed\n");
264 }
265 if (data.PosEdge(kShiftHigh)) {
266 is_high_gear_ = false;
267 }
268 if (data.PosEdge(kShiftLow)) {
269 is_high_gear_ = true;
270 }
271 }
272
273 void SetGoal(ClawGoal goal) {
274 goal_angle_ = goal.angle;
275 separation_angle_ = goal.separation;
Brian Silvermana379f002014-03-22 19:34:53 -0700276 velocity_compensation_ = 0.0;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800277 intake_power_ = 0.0;
278 }
279
280 void SetGoal(ShotGoal goal) {
281 goal_angle_ = goal.claw.angle;
282 separation_angle_ = goal.claw.separation;
283 shot_power_ = goal.shot_power;
284 velocity_compensation_ = goal.velocity_compensation;
285 intake_power_ = goal.intake_power;
Austin Schuh58d23682014-02-23 01:39:50 -0800286 }
287
288 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
289 HandleDrivetrain(data);
Austin Schuhc95c2b72014-03-02 11:56:49 -0800290 if (!data.GetControlBit(ControlBit::kEnabled)) {
291 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800292 LOG(DEBUG, "Canceling\n");
Austin Schuhc95c2b72014-03-02 11:56:49 -0800293 }
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800294 if (data.IsPressed(kRollersIn) || data.IsPressed(kRollersOut)) {
295 intake_power_ = 0.0;
Brian Silverman545f2ad2014-03-14 12:31:42 -0700296 separation_angle_ = kGrabSeparation;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800297 }
Austin Schuh58d23682014-02-23 01:39:50 -0800298
Brian Silverman18f6e642014-03-13 18:52:47 -0700299 static const double kAdjustClawGoalDeadband = 0.08;
300 double claw_goal_adjust = data.GetAxis(kAdjustClawGoal);
301 if (::std::abs(claw_goal_adjust) < kAdjustClawGoalDeadband) {
302 claw_goal_adjust = 0;
303 } else {
304 claw_goal_adjust = (claw_goal_adjust -
305 ((claw_goal_adjust < 0) ? -kAdjustClawGoalDeadband
306 : kAdjustClawGoalDeadband)) *
307 0.035;
308 }
309 double claw_separation_adjust = data.GetAxis(kAdjustClawSeparation);
310 if (::std::abs(claw_separation_adjust) < kAdjustClawGoalDeadband) {
311 claw_separation_adjust = 0;
312 } else {
313 claw_separation_adjust =
314 (claw_separation_adjust -
315 ((claw_separation_adjust < 0) ? -kAdjustClawGoalDeadband
316 : kAdjustClawGoalDeadband)) *
317 -0.035;
318 }
319
Brian Silverman4d1795d2014-03-13 15:53:40 -0700320 if (data.GetAxis(kFlipRobot) > 0.5) {
Brian Silverman18f6e642014-03-13 18:52:47 -0700321 claw_goal_adjust += claw_separation_adjust;
322 claw_goal_adjust *= -1;
323
Austin Schuh80ff2e12014-03-08 12:06:19 -0800324 if (data.IsPressed(kIntakeOpenPosition)) {
325 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800326 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800327 SetGoal(kFlippedIntakeOpenGoal);
328 } else if (data.IsPressed(kIntakePosition)) {
329 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800330 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800331 SetGoal(kFlippedIntakeGoal);
332 } else if (data.IsPressed(kTuck)) {
333 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800334 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800335 SetGoal(kFlippedTuckGoal);
336 } else if (data.PosEdge(kLongShot)) {
337 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800338 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800339 SetGoal(kFlippedLongShotGoal);
340 } else if (data.PosEdge(kMediumShot)) {
341 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800342 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800343 SetGoal(kFlippedMediumShotGoal);
344 } else if (data.PosEdge(kShortShot)) {
345 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800346 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800347 SetGoal(kFlippedShortShotGoal);
Austin Schuhade6d082014-03-09 00:53:06 -0800348 } else if (data.PosEdge(kTrussShot)) {
349 action_queue_.CancelAllActions();
350 LOG(DEBUG, "Canceling\n");
351 SetGoal(kTrussShotGoal);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800352 }
353 } else {
354 if (data.IsPressed(kIntakeOpenPosition)) {
355 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800356 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800357 SetGoal(kIntakeOpenGoal);
358 } else if (data.IsPressed(kIntakePosition)) {
359 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800360 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800361 SetGoal(kIntakeGoal);
362 } else if (data.IsPressed(kTuck)) {
363 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800364 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800365 SetGoal(kTuckGoal);
366 } else if (data.PosEdge(kLongShot)) {
367 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800368 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800369 SetGoal(kLongShotGoal);
370 } else if (data.PosEdge(kMediumShot)) {
371 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800372 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800373 SetGoal(kMediumShotGoal);
374 } else if (data.PosEdge(kShortShot)) {
375 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800376 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800377 SetGoal(kShortShotGoal);
Austin Schuhade6d082014-03-09 00:53:06 -0800378 } else if (data.PosEdge(kTrussShot)) {
379 action_queue_.CancelAllActions();
380 LOG(DEBUG, "Canceling\n");
381 SetGoal(kTrussShotGoal);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800382 }
Austin Schuh58d23682014-02-23 01:39:50 -0800383 }
384
Austin Schuhade6d082014-03-09 00:53:06 -0800385 /*
Austin Schuh80ff2e12014-03-08 12:06:19 -0800386 if (data.PosEdge(kCatch)) {
387 auto catch_action = MakeCatchAction();
388 catch_action->GetGoal()->catch_angle = goal_angle_;
389 action_queue_.QueueAction(::std::move(catch_action));
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800390 }
Austin Schuhade6d082014-03-09 00:53:06 -0800391 */
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800392
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800393 if (data.PosEdge(kFire)) {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800394 action_queue_.QueueAction(actions::MakeShootAction());
Brian Silverman9f863a02014-03-29 17:42:36 -0700395 } else if (data.NegEdge(kFire)) {
396 action_queue_.CancelCurrentAction();
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800397 }
398
399 action_queue_.Tick();
Austin Schuhc95c2b72014-03-02 11:56:49 -0800400 if (data.IsPressed(kUnload) || data.IsPressed(kReload)) {
401 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800402 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800403 intake_power_ = 0.0;
Brian Silvermana379f002014-03-22 19:34:53 -0700404 velocity_compensation_ = 0.0;
Austin Schuhc95c2b72014-03-02 11:56:49 -0800405 }
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800406
407 // Send out the claw and shooter goals if no actions are running.
408 if (!action_queue_.Running()) {
Brian Silverman18f6e642014-03-13 18:52:47 -0700409 goal_angle_ += claw_goal_adjust;
410 separation_angle_ += claw_separation_adjust;
411
Austin Schuh80ff2e12014-03-08 12:06:19 -0800412 // If the action just ended, turn the intake off and stop velocity
413 // compensating.
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800414 if (was_running_) {
415 intake_power_ = 0.0;
Brian Silvermana379f002014-03-22 19:34:53 -0700416 velocity_compensation_ = 0.0;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800417 }
418
419 control_loops::drivetrain.status.FetchLatest();
Brian Silvermana379f002014-03-22 19:34:53 -0700420 double goal_angle = goal_angle_;
421 if (control_loops::drivetrain.status.get()) {
422 goal_angle +=
423 SpeedToAngleOffset(control_loops::drivetrain.status->robot_speed);
424 } else {
425 LOG_INTERVAL(no_drivetrain_status_);
426 }
Austin Schuhade6d082014-03-09 00:53:06 -0800427 double separation_angle = separation_angle_;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800428
Austin Schuhade6d082014-03-09 00:53:06 -0800429 if (data.IsPressed(kCatch)) {
430 const double kCatchSeparation = 1.0;
431 goal_angle -= kCatchSeparation / 2.0;
432 separation_angle = kCatchSeparation;
433 }
434
435 bool intaking =
436 data.IsPressed(kRollersIn) || data.IsPressed(kIntakePosition) ||
437 data.IsPressed(kIntakeOpenPosition) || data.IsPressed(kCatch);
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800438 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800439 .bottom_angle(goal_angle)
Austin Schuhade6d082014-03-09 00:53:06 -0800440 .separation_angle(separation_angle)
Austin Schuh80ff2e12014-03-08 12:06:19 -0800441 .intake(intaking ? 12.0
442 : (data.IsPressed(kRollersOut) ? -12.0
443 : intake_power_))
444 .centering(intaking ? 12.0 : 0.0)
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800445 .Send()) {
446 LOG(WARNING, "sending claw goal failed\n");
447 }
448
449 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
450 .shot_power(shot_power_)
451 .shot_requested(data.IsPressed(kFire))
452 .unload_requested(data.IsPressed(kUnload))
453 .load_requested(data.IsPressed(kReload))
454 .Send()) {
455 LOG(WARNING, "sending shooter goal failed\n");
456 }
Austin Schuh58d23682014-02-23 01:39:50 -0800457 }
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800458 was_running_ = action_queue_.Running();
459 }
460
461 double SpeedToAngleOffset(double speed) {
462 const frc971::constants::Values &values = frc971::constants::GetValues();
463 // scale speed to a [0.0-1.0] on something close to the max
464 // TODO(austin): Change the scale factor for different shots.
Brian Silvermana379f002014-03-22 19:34:53 -0700465 return (speed / values.drivetrain_max_speed) * velocity_compensation_;
Austin Schuh58d23682014-02-23 01:39:50 -0800466 }
467
Austin Schuh01c652b2014-02-21 23:13:42 -0800468 private:
Austin Schuh58d23682014-02-23 01:39:50 -0800469 bool is_high_gear_;
470 double shot_power_;
471 double goal_angle_;
472 double separation_angle_;
Brian Silvermana379f002014-03-22 19:34:53 -0700473 double velocity_compensation_;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800474 double intake_power_;
475 bool was_running_;
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800476
477 ActionQueue action_queue_;
Brian Silvermana379f002014-03-22 19:34:53 -0700478
479 ::aos::util::SimpleLogInterval no_drivetrain_status_ =
480 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.2), WARNING,
481 "no drivetrain status");
Brian Silverman756f9ff2014-01-17 23:40:23 -0800482};
483
484} // namespace joysticks
485} // namespace input
486} // namespace frc971
487
488int main() {
489 ::aos::Init();
490 ::frc971::input::joysticks::Reader reader;
491 reader.Run();
492 ::aos::Cleanup();
493}