blob: 17e5c47fb1688a6cefe99da9421f4bc874d71daa [file] [log] [blame]
Campbell Crowley71b5f132017-02-18 13:16:08 -08001#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <math.h>
5
Austin Schuh3028b1d2017-03-11 22:12:13 -08006#include "aos/common/actions/actions.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -08007#include "aos/common/input/driver_station_data.h"
8#include "aos/common/logging/logging.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -08009#include "aos/common/time.h"
Austin Schuh3028b1d2017-03-11 22:12:13 -080010#include "aos/common/util/log_interval.h"
11#include "aos/input/joystick_input.h"
12#include "aos/linux_code/init.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -080013#include "frc971/autonomous/auto.q.h"
Austin Schuh3028b1d2017-03-11 22:12:13 -080014#include "frc971/autonomous/base_autonomous_actor.h"
15#include "frc971/control_loops/drivetrain/drivetrain.q.h"
16#include "y2017/constants.h"
17#include "y2017/control_loops/superstructure/superstructure.q.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -080018
19using ::frc971::control_loops::drivetrain_queue;
20using ::y2017::control_loops::superstructure_queue;
21
22using ::aos::input::driver_station::ButtonLocation;
23using ::aos::input::driver_station::ControlBit;
24using ::aos::input::driver_station::JoystickAxis;
25using ::aos::input::driver_station::POVLocation;
26
27namespace y2017 {
28namespace input {
29namespace joysticks {
30
31const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
32const ButtonLocation kQuickTurn(1, 5);
33
34const ButtonLocation kTurn1(1, 7);
35const ButtonLocation kTurn2(1, 11);
36
37const ButtonLocation kIntakeDown(3, 9);
Austin Schuhd0629b12017-03-22 22:37:16 -070038const POVLocation kIntakeUp(3, 90);
Campbell Crowley71b5f132017-02-18 13:16:08 -080039const ButtonLocation kIntakeIn(3, 12);
40const ButtonLocation kIntakeOut(3, 8);
Campbell Crowley71b5f132017-02-18 13:16:08 -080041const ButtonLocation kFire(3, 3);
42const ButtonLocation kCloseShot(3, 7);
43const ButtonLocation kMiddleShot(3, 6);
44const POVLocation kFarShot(3, 270);
45
46const ButtonLocation kVisionAlign(3, 5);
47
48const ButtonLocation kReverseIndexer(3, 4);
49const ButtonLocation kExtra1(3, 11);
50const ButtonLocation kExtra2(3, 10);
Austin Schuhd0629b12017-03-22 22:37:16 -070051const ButtonLocation kHang(3, 2);
Campbell Crowley71b5f132017-02-18 13:16:08 -080052
53class Reader : public ::aos::input::JoystickInput {
54 public:
55 Reader() {}
56
Austin Schuhd0629b12017-03-22 22:37:16 -070057 enum class ShotDistance { CLOSE_SHOT, MIDDLE_SHOT, FAR_SHOT };
58
59 ShotDistance last_shot_distance_ = ShotDistance::FAR_SHOT;
60
Campbell Crowley71b5f132017-02-18 13:16:08 -080061 void RunIteration(const ::aos::input::driver_station::Data &data) override {
62 bool last_auto_running = auto_running_;
63 auto_running_ = data.GetControlBit(ControlBit::kAutonomous) &&
64 data.GetControlBit(ControlBit::kEnabled);
65 if (auto_running_ != last_auto_running) {
66 if (auto_running_) {
67 StartAuto();
68 } else {
69 StopAuto();
70 }
71 }
72
73 vision_valid_ = false;
74
75 if (!auto_running_) {
76 HandleDrivetrain(data);
77 HandleTeleop(data);
78 }
79
80 // Process any pending actions.
81 action_queue_.Tick();
82 was_running_ = action_queue_.Running();
83 }
Austin Schuhd0629b12017-03-22 22:37:16 -070084 int intake_accumulator_ = 0;
Campbell Crowley71b5f132017-02-18 13:16:08 -080085
86 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
87 bool is_control_loop_driving = false;
88
89 const double wheel = -data.GetAxis(kSteeringWheel);
90 const double throttle = -data.GetAxis(kDriveThrottle);
91 drivetrain_queue.status.FetchLatest();
Austin Schuhd0629b12017-03-22 22:37:16 -070092 if (drivetrain_queue.status.get()) {
93 robot_velocity_ = drivetrain_queue.status->robot_speed;
94 }
Campbell Crowley71b5f132017-02-18 13:16:08 -080095
96 if (data.PosEdge(kTurn1) || data.PosEdge(kTurn2)) {
97 if (drivetrain_queue.status.get()) {
98 left_goal_ = drivetrain_queue.status->estimated_left_position;
99 right_goal_ = drivetrain_queue.status->estimated_right_position;
100 }
101 }
102 if (data.IsPressed(kTurn1) || data.IsPressed(kTurn2)) {
103 is_control_loop_driving = true;
104 }
105 if (!drivetrain_queue.goal.MakeWithBuilder()
106 .steering(wheel)
107 .throttle(throttle)
108 .quickturn(data.IsPressed(kQuickTurn))
109 .control_loop_driving(is_control_loop_driving)
110 .left_goal(left_goal_ - wheel * 0.5 + throttle * 0.3)
111 .right_goal(right_goal_ + wheel * 0.5 + throttle * 0.3)
112 .left_velocity_goal(0)
113 .right_velocity_goal(0)
114 .Send()) {
115 LOG(WARNING, "sending stick values failed\n");
116 }
117 }
118
119 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
120 // Default the intake to in.
Austin Schuhd0629b12017-03-22 22:37:16 -0700121 intake_goal_ = 0.07;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800122 bool lights_on = false;
Austin Schuhd0629b12017-03-22 22:37:16 -0700123 bool vision_track = false;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800124
125 if (!data.GetControlBit(ControlBit::kEnabled)) {
126 action_queue_.CancelAllActions();
127 LOG(DEBUG, "Canceling\n");
128 }
129
130 superstructure_queue.status.FetchLatest();
131 if (!superstructure_queue.status.get()) {
132 LOG(ERROR, "Got no superstructure status packet.\n");
133 return;
134 }
135
136 if (data.IsPressed(kIntakeDown)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700137 intake_goal_ = 0.235;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800138 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700139 if (data.IsPressed(kIntakeUp)) {
140 intake_goal_ = 0.0;
141 turret_goal_ = 0.0;
142 }
143
Campbell Crowley71b5f132017-02-18 13:16:08 -0800144
145 if (data.IsPressed(kVisionAlign)) {
146 // Align shot using vision
147 // TODO(campbell): Add vision aligning.
Adam Snaidere0554ef2017-03-11 23:02:45 -0800148 lights_on = true;
Austin Schuhd0629b12017-03-22 22:37:16 -0700149 vision_track = true;
150 }
151 if (data.PosEdge(kMiddleShot)) {
152 turret_goal_ = -M_PI;
153 }
154 if (data.PosEdge(kFarShot)) {
155 turret_goal_ = 0.0;
156 }
157
158 if (data.IsPressed(kCloseShot)) {
159 last_shot_distance_ = ShotDistance::CLOSE_SHOT;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800160 } else if (data.IsPressed(kMiddleShot)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700161 last_shot_distance_ = ShotDistance::MIDDLE_SHOT;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800162 } else if (data.IsPressed(kFarShot)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700163 last_shot_distance_ = ShotDistance::FAR_SHOT;
164 }
165
166 if (data.IsPressed(kVisionAlign) || data.IsPressed(kCloseShot) ||
167 data.IsPressed(kMiddleShot) || data.IsPressed(kFarShot) ||
168 data.IsPressed(kFire)) {
169 switch (last_shot_distance_) {
170 case ShotDistance::CLOSE_SHOT:
171 hood_goal_ = 0.285;
172 shooter_velocity_ = 335.0;
173 break;
174 case ShotDistance::MIDDLE_SHOT:
175 hood_goal_ = 0.63;
176 shooter_velocity_ = 384.0;
177 break;
178 case ShotDistance::FAR_SHOT:
179 hood_goal_ = 0.63;
180 shooter_velocity_ = 378.0;
181 break;
182 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800183 } else {
Austin Schuhd0629b12017-03-22 22:37:16 -0700184 //hood_goal_ = 0.15;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800185 shooter_velocity_ = 0.0;
186 }
187
188 if (data.IsPressed(kExtra1)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700189 //turret_goal_ = -M_PI * 3.0 / 4.0;
190 turret_goal_ += 0.150;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800191 }
192 if (data.IsPressed(kExtra2)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700193 //turret_goal_ = M_PI * 3.0 / 4.0;
194 turret_goal_ -= 0.150;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800195 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700196 turret_goal_ = ::std::max(::std::min(turret_goal_, M_PI), -M_PI);
Campbell Crowley71b5f132017-02-18 13:16:08 -0800197
198 fire_ = data.IsPressed(kFire) && shooter_velocity_ != 0.0;
Austin Schuhd0629b12017-03-22 22:37:16 -0700199 if (data.IsPressed(kVisionAlign)) {
200 fire_ = fire_ && superstructure_queue.status->turret.vision_tracking;
201 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800202
203 auto new_superstructure_goal = superstructure_queue.goal.MakeMessage();
Austin Schuhd0629b12017-03-22 22:37:16 -0700204 if (data.IsPressed(kHang)) {
205 intake_goal_ = 0.23;
206 }
207
Campbell Crowley71b5f132017-02-18 13:16:08 -0800208 new_superstructure_goal->intake.distance = intake_goal_;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800209 new_superstructure_goal->intake.disable_intake = false;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800210 new_superstructure_goal->turret.angle = turret_goal_;
Austin Schuhd0629b12017-03-22 22:37:16 -0700211 new_superstructure_goal->turret.track = vision_track;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800212 new_superstructure_goal->hood.angle = hood_goal_;
213 new_superstructure_goal->shooter.angular_velocity = shooter_velocity_;
214
215 new_superstructure_goal->intake.profile_params.max_velocity = 0.50;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800216 new_superstructure_goal->hood.profile_params.max_velocity = 5.0;
217
218 new_superstructure_goal->intake.profile_params.max_acceleration = 5.0;
Austin Schuhd0629b12017-03-22 22:37:16 -0700219 if (vision_track) {
220 new_superstructure_goal->turret.profile_params.max_acceleration = 35.0;
221 new_superstructure_goal->turret.profile_params.max_velocity = 10.0;
222 } else {
223 new_superstructure_goal->turret.profile_params.max_acceleration = 15.0;
224 new_superstructure_goal->turret.profile_params.max_velocity = 6.0;
225 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800226 new_superstructure_goal->hood.profile_params.max_acceleration = 25.0;
227
Austin Schuh3028b1d2017-03-11 22:12:13 -0800228 new_superstructure_goal->intake.voltage_rollers = 0.0;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800229 new_superstructure_goal->lights_on = lights_on;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800230
Campbell Crowley71b5f132017-02-18 13:16:08 -0800231 if (data.IsPressed(kHang)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700232 new_superstructure_goal->intake.voltage_rollers = -10.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800233 new_superstructure_goal->intake.disable_intake = true;
Austin Schuhd0629b12017-03-22 22:37:16 -0700234 } else if (data.IsPressed(kIntakeIn) || data.IsPressed(kFire)) {
235 if (robot_velocity_ > 2.0) {
236 new_superstructure_goal->intake.voltage_rollers = 12.0;
237 } else {
238 new_superstructure_goal->intake.voltage_rollers = 10.0;
239 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800240 } else if (data.IsPressed(kIntakeOut)) {
241 new_superstructure_goal->intake.voltage_rollers = -8.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800242 }
243 if (intake_goal_ < 0.1) {
244 new_superstructure_goal->intake.voltage_rollers =
245 ::std::min(8.0, new_superstructure_goal->intake.voltage_rollers);
Campbell Crowley71b5f132017-02-18 13:16:08 -0800246 }
247
Austin Schuhd0629b12017-03-22 22:37:16 -0700248 if (superstructure_queue.status->intake.position >
249 superstructure_queue.status->intake.unprofiled_goal_position + 0.01) {
250 intake_accumulator_ = 10;
251 }
252 if (intake_accumulator_ > 0) {
253 --intake_accumulator_;
254 new_superstructure_goal->intake.voltage_rollers = 10.0;
255 }
256
Campbell Crowley71b5f132017-02-18 13:16:08 -0800257 if (data.IsPressed(kReverseIndexer)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700258 new_superstructure_goal->indexer.voltage_rollers = -12.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800259 new_superstructure_goal->indexer.angular_velocity = 4.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800260 new_superstructure_goal->indexer.angular_velocity = 1.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800261 } else if (fire_) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700262 new_superstructure_goal->indexer.voltage_rollers = 12.0;
263 switch (last_shot_distance_) {
264 case ShotDistance::CLOSE_SHOT:
265 new_superstructure_goal->indexer.angular_velocity = -0.90 * M_PI;
266 break;
267 case ShotDistance::MIDDLE_SHOT:
268 case ShotDistance::FAR_SHOT:
269 new_superstructure_goal->indexer.angular_velocity = -2.25 * M_PI;
270 break;
271 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800272 } else {
273 new_superstructure_goal->indexer.voltage_rollers = 0.0;
274 new_superstructure_goal->indexer.angular_velocity = 0.0;
275 }
276
277 LOG_STRUCT(DEBUG, "sending goal", *new_superstructure_goal);
278 if (!new_superstructure_goal.Send()) {
279 LOG(ERROR, "Sending superstructure goal failed.\n");
280 }
281 }
282
283 private:
Austin Schuh3028b1d2017-03-11 22:12:13 -0800284 void StartAuto() {
285 LOG(INFO, "Starting auto mode\n");
286
287 ::frc971::autonomous::AutonomousActionParams params;
288 ::frc971::autonomous::auto_mode.FetchLatest();
289 if (::frc971::autonomous::auto_mode.get() != nullptr) {
290 params.mode = ::frc971::autonomous::auto_mode->mode;
291 } else {
292 LOG(WARNING, "no auto mode values\n");
293 params.mode = 0;
294 }
295 action_queue_.EnqueueAction(
296 ::frc971::autonomous::MakeAutonomousAction(params));
297 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800298
299 void StopAuto() {
300 LOG(INFO, "Stopping auto mode\n");
301 action_queue_.CancelAllActions();
302 }
303
304 // Current goals to send to the robot.
305 double intake_goal_ = 0.0;
306 double turret_goal_ = 0.0;
307 double hood_goal_ = 0.3;
308 double shooter_velocity_ = 0.0;
309
310 // Goals to send to the drivetrain in closed loop mode.
Austin Schuh3028b1d2017-03-11 22:12:13 -0800311 double left_goal_ = 0.0;
312 double right_goal_ = 0.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800313
314 bool was_running_ = false;
315 bool auto_running_ = false;
316
317 bool vision_valid_ = false;
318
319 bool fire_ = false;
Austin Schuhd0629b12017-03-22 22:37:16 -0700320 double robot_velocity_ = 0.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800321
322 ::aos::common::actions::ActionQueue action_queue_;
323};
324
325} // namespace joysticks
326} // namespace input
327} // namespace y2017
328
329int main() {
330 ::aos::Init(-1);
331 ::y2017::input::joysticks::Reader reader;
332 reader.Run();
333 ::aos::Cleanup();
334}