blob: 9572cd37f25e4d446e817ba5aef4253eaae28a28 [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
Brian Silverman63ec7502014-03-30 18:09:10 -070031#define ENABLE_HUMAN 0
32
Brian Silverman756f9ff2014-01-17 23:40:23 -080033namespace frc971 {
34namespace input {
35namespace joysticks {
36
37const ButtonLocation kDriveControlLoopEnable1(1, 7),
38 kDriveControlLoopEnable2(1, 11);
39const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
40const ButtonLocation kShiftHigh(2, 1), kShiftLow(2, 3);
41const ButtonLocation kQuickTurn(1, 5);
Austin Schuh58d23682014-02-23 01:39:50 -080042
Austin Schuh80ff2e12014-03-08 12:06:19 -080043const ButtonLocation kCatch(3, 10);
44
45const ButtonLocation kFire(3, 9);
Austin Schuh9cb836e2014-02-23 19:25:55 -080046const ButtonLocation kUnload(2, 11);
47const ButtonLocation kReload(2, 6);
Austin Schuh58d23682014-02-23 01:39:50 -080048
Austin Schuh80ff2e12014-03-08 12:06:19 -080049const ButtonLocation kRollersOut(3, 8);
50const ButtonLocation kRollersIn(3, 3);
Austin Schuh58d23682014-02-23 01:39:50 -080051
Austin Schuh80ff2e12014-03-08 12:06:19 -080052const ButtonLocation kTuck(3, 4);
53const ButtonLocation kIntakePosition(3, 5);
54const ButtonLocation kIntakeOpenPosition(3, 11);
Austin Schuh80ff2e12014-03-08 12:06:19 -080055const JoystickAxis kFlipRobot(3, 3);
Austin Schuh58d23682014-02-23 01:39:50 -080056
Austin Schuh80ff2e12014-03-08 12:06:19 -080057const ButtonLocation kLongShot(3, 7);
58const ButtonLocation kMediumShot(3, 6);
59const ButtonLocation kShortShot(3, 2);
Brian Silverman63ec7502014-03-30 18:09:10 -070060#if ENABLE_HUMAN
61// Currently human player shot.
62#endif
Austin Schuhade6d082014-03-09 00:53:06 -080063const ButtonLocation kTrussShot(3, 1);
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};
Brian Silverman63ec7502014-03-30 18:09:10 -070087const ClawGoal kIntakeGoal = {-2.24, kGrabSeparation};
88const ClawGoal kIntakeOpenGoal = {-2.0, 1.1};
Austin Schuh58d23682014-02-23 01:39:50 -080089
Austin Schuh80ff2e12014-03-08 12:06:19 -080090// TODO(austin): Tune these by hand...
91const ClawGoal kFlippedTuckGoal = {2.733474, -0.75};
Brian Silverman545f2ad2014-03-14 12:31:42 -070092const ClawGoal kFlippedIntakeGoal = {2.0, kGrabSeparation};
Austin Schuh80ff2e12014-03-08 12:06:19 -080093const ClawGoal kFlippedIntakeOpenGoal = {0.95, 1.0};
94
Brian Silverman0e7c03e2014-03-23 17:06:24 -070095// 34" between near edge of colored line and rear edge of bumper
Austin Schuh5d8c5e72014-03-07 20:24:34 -080096const ShotGoal kLongShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -070097 {-1.04, kShootSeparation}, 140, 0.04, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -070098// 3/4" plunger {-1.04, kShootSeparation}, 140, 0.04, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -080099const ShotGoal kFlippedLongShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -0700100 {0.96, kShootSeparation}, 140, 0.09, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700101// 3/4 " plunger {0.97, kShootSeparation}, 140, 0.08, kIntakePower};
102
103// 78" between near edge of colored line and rear edge of bumper
104const ShotGoal kMediumShotGoal = {
105 {-0.95, kShootSeparation}, 105, 0.2, kIntakePower};
106// 3/4" plunger {-0.90, kShootSeparation}, 105, 0.2, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -0800107const ShotGoal kFlippedMediumShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -0700108 {0.905, kShootSeparation}, 120, 0.2, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700109// 3/4" plunger {0.80, kShootSeparation}, 105, 0.2, kIntakePower};
110
111const ShotGoal kShortShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -0700112 {-0.670, kShootSeparation}, 77.0, 0.4, kIntakePower};
Austin Schuh80ff2e12014-03-08 12:06:19 -0800113const ShotGoal kFlippedShortShotGoal = {
Brian Silverman63ec7502014-03-30 18:09:10 -0700114 {0.67, kShootSeparation}, 115.0, 0.4, kIntakePower};
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700115
Brian Silverman63ec7502014-03-30 18:09:10 -0700116#if ENABLE_HUMAN
117const ShotGoal kHumanShotGoal = {
118 {-0.90, kShootSeparation}, 140, 0.04, kIntakePower};
119#else
Brian Silverman0e7c03e2014-03-23 17:06:24 -0700120const ShotGoal kTrussShotGoal = {
121 {-0.05, kShootSeparation}, 73.0, 0, kIntakePower};
Brian Silverman63ec7502014-03-30 18:09:10 -0700122#endif
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800123
124// Makes a new ShootAction action.
Austin Schuh80ff2e12014-03-08 12:06:19 -0800125::std::unique_ptr<TypedAction< ::frc971::actions::CatchActionGroup>>
126MakeCatchAction() {
127 return ::std::unique_ptr<TypedAction< ::frc971::actions::CatchActionGroup>>(
128 new TypedAction< ::frc971::actions::CatchActionGroup>(
129 &::frc971::actions::catch_action));
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800130}
131
132// A queue which queues Actions and cancels them.
133class ActionQueue {
134 public:
135 // Queues up an action for sending.
136 void QueueAction(::std::unique_ptr<Action> action) {
137 if (current_action_) {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800138 LOG(INFO, "Queueing action, canceling prior\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800139 current_action_->Cancel();
140 next_action_ = ::std::move(action);
141 } else {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800142 LOG(INFO, "Queueing action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800143 current_action_ = ::std::move(action);
144 current_action_->Start();
145 }
146 }
147
148 // Cancels the current action, and runs the next one when the current one has
149 // finished.
150 void CancelCurrentAction() {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800151 LOG(INFO, "Canceling current action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800152 if (current_action_) {
153 current_action_->Cancel();
154 }
155 }
156
157 // Cancels all running actions.
158 void CancelAllActions() {
Brian Silverman101b9642014-03-08 12:45:16 -0800159 LOG(DEBUG, "Cancelling all actions\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800160 if (current_action_) {
161 current_action_->Cancel();
162 }
163 next_action_.reset();
164 }
165
166 // Runs the next action when the current one is finished running.
167 void Tick() {
168 if (current_action_) {
169 if (!current_action_->Running()) {
Austin Schuhc95c2b72014-03-02 11:56:49 -0800170 LOG(INFO, "Action is done.\n");
171 current_action_ = ::std::move(next_action_);
172 if (current_action_) {
173 LOG(INFO, "Running next action\n");
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800174 current_action_->Start();
175 }
176 }
177 }
178 }
179
180 // Returns true if any action is running or could be running.
181 // For a one cycle faster response, call Tick before running this.
182 bool Running() { return (bool)current_action_; }
183
184 private:
185 ::std::unique_ptr<Action> current_action_;
186 ::std::unique_ptr<Action> next_action_;
187};
188
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800189
Brian Silverman756f9ff2014-01-17 23:40:23 -0800190class Reader : public ::aos::input::JoystickInput {
191 public:
Austin Schuh58d23682014-02-23 01:39:50 -0800192 Reader()
193 : is_high_gear_(false),
Austin Schuh9cb836e2014-02-23 19:25:55 -0800194 shot_power_(80.0),
Austin Schuh58d23682014-02-23 01:39:50 -0800195 goal_angle_(0.0),
Brian Silverman545f2ad2014-03-14 12:31:42 -0700196 separation_angle_(kGrabSeparation),
Brian Silvermana379f002014-03-22 19:34:53 -0700197 velocity_compensation_(0.0),
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800198 intake_power_(0.0),
199 was_running_(false) {}
Brian Silverman756f9ff2014-01-17 23:40:23 -0800200
201 virtual void RunIteration(const ::aos::input::driver_station::Data &data) {
Brian Silverman756f9ff2014-01-17 23:40:23 -0800202 if (data.GetControlBit(ControlBit::kAutonomous)) {
203 if (data.PosEdge(ControlBit::kEnabled)){
204 LOG(INFO, "Starting auto mode\n");
205 ::frc971::autonomous::autonomous.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800206 .run_auto(true)
207 .Send();
Brian Silverman756f9ff2014-01-17 23:40:23 -0800208 } else if (data.NegEdge(ControlBit::kEnabled)) {
209 LOG(INFO, "Stopping auto mode\n");
210 ::frc971::autonomous::autonomous.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800211 .run_auto(false)
212 .Send();
Brian Silverman756f9ff2014-01-17 23:40:23 -0800213 }
Austin Schuh58d23682014-02-23 01:39:50 -0800214 } else {
215 HandleTeleop(data);
Brian Silverman756f9ff2014-01-17 23:40:23 -0800216 }
217 }
Austin Schuh58d23682014-02-23 01:39:50 -0800218
219 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
220 bool is_control_loop_driving = false;
221 double left_goal = 0.0;
222 double right_goal = 0.0;
223 const double wheel = -data.GetAxis(kSteeringWheel);
224 const double throttle = -data.GetAxis(kDriveThrottle);
225 const double kThrottleGain = 1.0 / 2.5;
226 if (false && (data.IsPressed(kDriveControlLoopEnable1) ||
227 data.IsPressed(kDriveControlLoopEnable2))) {
228 // TODO(austin): Static sucks!
229 static double distance = 0.0;
230 static double angle = 0.0;
231 static double filtered_goal_distance = 0.0;
232 if (data.PosEdge(kDriveControlLoopEnable1) ||
233 data.PosEdge(kDriveControlLoopEnable2)) {
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800234 if (drivetrain.position.FetchLatest() && gyro_reading.FetchLatest()) {
Austin Schuh58d23682014-02-23 01:39:50 -0800235 distance = (drivetrain.position->left_encoder +
236 drivetrain.position->right_encoder) /
237 2.0 -
238 throttle * kThrottleGain / 2.0;
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800239 angle = gyro_reading->angle;
Austin Schuh58d23682014-02-23 01:39:50 -0800240 filtered_goal_distance = distance;
241 }
242 }
243 is_control_loop_driving = true;
244
245 // const double gyro_angle = Gyro.View().angle;
246 const double goal_theta = angle - wheel * 0.27;
247 const double goal_distance = distance + throttle * kThrottleGain;
248 const double robot_width = 22.0 / 100.0 * 2.54;
249 const double kMaxVelocity = 0.6;
250 if (goal_distance > kMaxVelocity * 0.02 + filtered_goal_distance) {
251 filtered_goal_distance += kMaxVelocity * 0.02;
252 } else if (goal_distance <
253 -kMaxVelocity * 0.02 + filtered_goal_distance) {
254 filtered_goal_distance -= kMaxVelocity * 0.02;
255 } else {
256 filtered_goal_distance = goal_distance;
257 }
258 left_goal = filtered_goal_distance - robot_width * goal_theta / 2.0;
259 right_goal = filtered_goal_distance + robot_width * goal_theta / 2.0;
260 is_high_gear_ = false;
261
262 LOG(DEBUG, "Left goal %f Right goal %f\n", left_goal, right_goal);
263 }
264 if (!drivetrain.goal.MakeWithBuilder()
265 .steering(wheel)
266 .throttle(throttle)
267 .highgear(is_high_gear_)
268 .quickturn(data.IsPressed(kQuickTurn))
269 .control_loop_driving(is_control_loop_driving)
270 .left_goal(left_goal)
271 .right_goal(right_goal)
272 .Send()) {
273 LOG(WARNING, "sending stick values failed\n");
274 }
275 if (data.PosEdge(kShiftHigh)) {
276 is_high_gear_ = false;
277 }
278 if (data.PosEdge(kShiftLow)) {
279 is_high_gear_ = true;
280 }
281 }
282
283 void SetGoal(ClawGoal goal) {
284 goal_angle_ = goal.angle;
285 separation_angle_ = goal.separation;
Brian7e294392014-03-31 12:39:13 -0700286 moving_for_shot_ = false;
Brian Silvermana379f002014-03-22 19:34:53 -0700287 velocity_compensation_ = 0.0;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800288 intake_power_ = 0.0;
289 }
290
291 void SetGoal(ShotGoal goal) {
292 goal_angle_ = goal.claw.angle;
Brian7e294392014-03-31 12:39:13 -0700293 shot_separation_angle_ = goal.claw.separation;
294 separation_angle_ = kGrabSeparation;
295 moving_for_shot_ = true;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800296 shot_power_ = goal.shot_power;
297 velocity_compensation_ = goal.velocity_compensation;
298 intake_power_ = goal.intake_power;
Austin Schuh58d23682014-02-23 01:39:50 -0800299 }
300
301 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
302 HandleDrivetrain(data);
Austin Schuhc95c2b72014-03-02 11:56:49 -0800303 if (!data.GetControlBit(ControlBit::kEnabled)) {
304 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800305 LOG(DEBUG, "Canceling\n");
Austin Schuhc95c2b72014-03-02 11:56:49 -0800306 }
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800307 if (data.IsPressed(kRollersIn) || data.IsPressed(kRollersOut)) {
308 intake_power_ = 0.0;
Brian Silverman545f2ad2014-03-14 12:31:42 -0700309 separation_angle_ = kGrabSeparation;
Brian7e294392014-03-31 12:39:13 -0700310 moving_for_shot_ = false;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800311 }
Austin Schuh58d23682014-02-23 01:39:50 -0800312
Brian Silverman18f6e642014-03-13 18:52:47 -0700313 static const double kAdjustClawGoalDeadband = 0.08;
314 double claw_goal_adjust = data.GetAxis(kAdjustClawGoal);
315 if (::std::abs(claw_goal_adjust) < kAdjustClawGoalDeadband) {
316 claw_goal_adjust = 0;
317 } else {
318 claw_goal_adjust = (claw_goal_adjust -
319 ((claw_goal_adjust < 0) ? -kAdjustClawGoalDeadband
320 : kAdjustClawGoalDeadband)) *
321 0.035;
322 }
323 double claw_separation_adjust = data.GetAxis(kAdjustClawSeparation);
324 if (::std::abs(claw_separation_adjust) < kAdjustClawGoalDeadband) {
325 claw_separation_adjust = 0;
326 } else {
327 claw_separation_adjust =
328 (claw_separation_adjust -
329 ((claw_separation_adjust < 0) ? -kAdjustClawGoalDeadband
330 : kAdjustClawGoalDeadband)) *
331 -0.035;
332 }
333
Brian Silverman4d1795d2014-03-13 15:53:40 -0700334 if (data.GetAxis(kFlipRobot) > 0.5) {
Brian Silverman18f6e642014-03-13 18:52:47 -0700335 claw_goal_adjust += claw_separation_adjust;
336 claw_goal_adjust *= -1;
337
Austin Schuh80ff2e12014-03-08 12:06:19 -0800338 if (data.IsPressed(kIntakeOpenPosition)) {
339 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800340 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800341 SetGoal(kFlippedIntakeOpenGoal);
342 } else if (data.IsPressed(kIntakePosition)) {
343 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800344 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800345 SetGoal(kFlippedIntakeGoal);
346 } else if (data.IsPressed(kTuck)) {
347 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800348 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800349 SetGoal(kFlippedTuckGoal);
350 } else if (data.PosEdge(kLongShot)) {
351 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800352 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800353 SetGoal(kFlippedLongShotGoal);
354 } else if (data.PosEdge(kMediumShot)) {
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(kFlippedMediumShotGoal);
358 } else if (data.PosEdge(kShortShot)) {
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(kFlippedShortShotGoal);
Austin Schuhade6d082014-03-09 00:53:06 -0800362 } else if (data.PosEdge(kTrussShot)) {
363 action_queue_.CancelAllActions();
364 LOG(DEBUG, "Canceling\n");
Brian Silverman63ec7502014-03-30 18:09:10 -0700365#if ENABLE_HUMAN
366 SetGoal(kHumanShotGoal);
367#else
Austin Schuhade6d082014-03-09 00:53:06 -0800368 SetGoal(kTrussShotGoal);
Brian Silverman63ec7502014-03-30 18:09:10 -0700369#endif
Austin Schuh80ff2e12014-03-08 12:06:19 -0800370 }
371 } else {
372 if (data.IsPressed(kIntakeOpenPosition)) {
373 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800374 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800375 SetGoal(kIntakeOpenGoal);
376 } else if (data.IsPressed(kIntakePosition)) {
377 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800378 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800379 SetGoal(kIntakeGoal);
380 } else if (data.IsPressed(kTuck)) {
381 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800382 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800383 SetGoal(kTuckGoal);
384 } else if (data.PosEdge(kLongShot)) {
385 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800386 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800387 SetGoal(kLongShotGoal);
388 } else if (data.PosEdge(kMediumShot)) {
389 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800390 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800391 SetGoal(kMediumShotGoal);
392 } else if (data.PosEdge(kShortShot)) {
393 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800394 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800395 SetGoal(kShortShotGoal);
Austin Schuhade6d082014-03-09 00:53:06 -0800396 } else if (data.PosEdge(kTrussShot)) {
397 action_queue_.CancelAllActions();
398 LOG(DEBUG, "Canceling\n");
Brian Silverman63ec7502014-03-30 18:09:10 -0700399#if ENABLE_HUMAN
400 SetGoal(kHumanShotGoal);
401#else
Austin Schuhade6d082014-03-09 00:53:06 -0800402 SetGoal(kTrussShotGoal);
Brian Silverman63ec7502014-03-30 18:09:10 -0700403#endif
Austin Schuh80ff2e12014-03-08 12:06:19 -0800404 }
Austin Schuh58d23682014-02-23 01:39:50 -0800405 }
406
Austin Schuhade6d082014-03-09 00:53:06 -0800407 /*
Austin Schuh80ff2e12014-03-08 12:06:19 -0800408 if (data.PosEdge(kCatch)) {
409 auto catch_action = MakeCatchAction();
410 catch_action->GetGoal()->catch_angle = goal_angle_;
411 action_queue_.QueueAction(::std::move(catch_action));
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800412 }
Austin Schuhade6d082014-03-09 00:53:06 -0800413 */
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800414
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800415 if (data.PosEdge(kFire)) {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800416 action_queue_.QueueAction(actions::MakeShootAction());
Brian Silverman9f863a02014-03-29 17:42:36 -0700417 } else if (data.NegEdge(kFire)) {
418 action_queue_.CancelCurrentAction();
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800419 }
420
421 action_queue_.Tick();
Austin Schuhc95c2b72014-03-02 11:56:49 -0800422 if (data.IsPressed(kUnload) || data.IsPressed(kReload)) {
423 action_queue_.CancelAllActions();
Austin Schuhade6d082014-03-09 00:53:06 -0800424 LOG(DEBUG, "Canceling\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800425 intake_power_ = 0.0;
Brian Silvermana379f002014-03-22 19:34:53 -0700426 velocity_compensation_ = 0.0;
Austin Schuhc95c2b72014-03-02 11:56:49 -0800427 }
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800428
429 // Send out the claw and shooter goals if no actions are running.
430 if (!action_queue_.Running()) {
Brian Silverman18f6e642014-03-13 18:52:47 -0700431 goal_angle_ += claw_goal_adjust;
432 separation_angle_ += claw_separation_adjust;
433
Austin Schuh80ff2e12014-03-08 12:06:19 -0800434 // If the action just ended, turn the intake off and stop velocity
435 // compensating.
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800436 if (was_running_) {
437 intake_power_ = 0.0;
Brian Silvermana379f002014-03-22 19:34:53 -0700438 velocity_compensation_ = 0.0;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800439 }
440
441 control_loops::drivetrain.status.FetchLatest();
Brian Silvermana379f002014-03-22 19:34:53 -0700442 double goal_angle = goal_angle_;
443 if (control_loops::drivetrain.status.get()) {
444 goal_angle +=
445 SpeedToAngleOffset(control_loops::drivetrain.status->robot_speed);
446 } else {
447 LOG_INTERVAL(no_drivetrain_status_);
448 }
Brian7e294392014-03-31 12:39:13 -0700449
450 if (moving_for_shot_) {
451 auto &claw_status = control_loops::claw_queue_group.status;
452 claw_status.FetchLatest();
453 if (claw_status.get()) {
454 if (::std::abs(claw_status->bottom - goal_angle) < 0.4) {
455 moving_for_shot_ = false;
456 separation_angle_ = shot_separation_angle_;
457 }
458 }
459 }
460
Austin Schuhade6d082014-03-09 00:53:06 -0800461 double separation_angle = separation_angle_;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800462
Austin Schuhade6d082014-03-09 00:53:06 -0800463 if (data.IsPressed(kCatch)) {
464 const double kCatchSeparation = 1.0;
465 goal_angle -= kCatchSeparation / 2.0;
466 separation_angle = kCatchSeparation;
467 }
468
469 bool intaking =
470 data.IsPressed(kRollersIn) || data.IsPressed(kIntakePosition) ||
471 data.IsPressed(kIntakeOpenPosition) || data.IsPressed(kCatch);
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800472 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800473 .bottom_angle(goal_angle)
Austin Schuhade6d082014-03-09 00:53:06 -0800474 .separation_angle(separation_angle)
Austin Schuh80ff2e12014-03-08 12:06:19 -0800475 .intake(intaking ? 12.0
476 : (data.IsPressed(kRollersOut) ? -12.0
477 : intake_power_))
478 .centering(intaking ? 12.0 : 0.0)
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800479 .Send()) {
480 LOG(WARNING, "sending claw goal failed\n");
481 }
482
483 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
484 .shot_power(shot_power_)
485 .shot_requested(data.IsPressed(kFire))
486 .unload_requested(data.IsPressed(kUnload))
487 .load_requested(data.IsPressed(kReload))
488 .Send()) {
489 LOG(WARNING, "sending shooter goal failed\n");
490 }
Austin Schuh58d23682014-02-23 01:39:50 -0800491 }
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800492 was_running_ = action_queue_.Running();
493 }
494
495 double SpeedToAngleOffset(double speed) {
496 const frc971::constants::Values &values = frc971::constants::GetValues();
497 // scale speed to a [0.0-1.0] on something close to the max
498 // TODO(austin): Change the scale factor for different shots.
Brian Silvermana379f002014-03-22 19:34:53 -0700499 return (speed / values.drivetrain_max_speed) * velocity_compensation_;
Austin Schuh58d23682014-02-23 01:39:50 -0800500 }
501
Austin Schuh01c652b2014-02-21 23:13:42 -0800502 private:
Austin Schuh58d23682014-02-23 01:39:50 -0800503 bool is_high_gear_;
504 double shot_power_;
505 double goal_angle_;
Brian7e294392014-03-31 12:39:13 -0700506 double separation_angle_, shot_separation_angle_;
Brian Silvermana379f002014-03-22 19:34:53 -0700507 double velocity_compensation_;
Austin Schuh5d8c5e72014-03-07 20:24:34 -0800508 double intake_power_;
509 bool was_running_;
Brian7e294392014-03-31 12:39:13 -0700510 bool moving_for_shot_ = false;
Austin Schuhb7dfabc2014-03-01 18:57:42 -0800511
512 ActionQueue action_queue_;
Brian Silvermana379f002014-03-22 19:34:53 -0700513
514 ::aos::util::SimpleLogInterval no_drivetrain_status_ =
515 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.2), WARNING,
516 "no drivetrain status");
Brian Silverman756f9ff2014-01-17 23:40:23 -0800517};
518
519} // namespace joysticks
520} // namespace input
521} // namespace frc971
522
523int main() {
524 ::aos::Init();
525 ::frc971::input::joysticks::Reader reader;
526 reader.Run();
527 ::aos::Cleanup();
528}