blob: 246150f5d7f019e9d43a8a1f39c71704118f71a6 [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
Austin Schuh55c8d302017-04-05 19:25:37 -070037const ButtonLocation kGearSlotBack(2, 11);
38
Campbell Crowley71b5f132017-02-18 13:16:08 -080039const ButtonLocation kIntakeDown(3, 9);
Austin Schuhd0629b12017-03-22 22:37:16 -070040const POVLocation kIntakeUp(3, 90);
Campbell Crowley71b5f132017-02-18 13:16:08 -080041const ButtonLocation kIntakeIn(3, 12);
42const ButtonLocation kIntakeOut(3, 8);
Campbell Crowley71b5f132017-02-18 13:16:08 -080043const ButtonLocation kFire(3, 3);
44const ButtonLocation kCloseShot(3, 7);
45const ButtonLocation kMiddleShot(3, 6);
46const POVLocation kFarShot(3, 270);
47
48const ButtonLocation kVisionAlign(3, 5);
49
50const ButtonLocation kReverseIndexer(3, 4);
51const ButtonLocation kExtra1(3, 11);
52const ButtonLocation kExtra2(3, 10);
Austin Schuhd0629b12017-03-22 22:37:16 -070053const ButtonLocation kHang(3, 2);
Campbell Crowley71b5f132017-02-18 13:16:08 -080054
55class Reader : public ::aos::input::JoystickInput {
56 public:
57 Reader() {}
58
Austin Schuhd0629b12017-03-22 22:37:16 -070059 enum class ShotDistance { CLOSE_SHOT, MIDDLE_SHOT, FAR_SHOT };
60
61 ShotDistance last_shot_distance_ = ShotDistance::FAR_SHOT;
62
Campbell Crowley71b5f132017-02-18 13:16:08 -080063 void RunIteration(const ::aos::input::driver_station::Data &data) override {
64 bool last_auto_running = auto_running_;
65 auto_running_ = data.GetControlBit(ControlBit::kAutonomous) &&
66 data.GetControlBit(ControlBit::kEnabled);
67 if (auto_running_ != last_auto_running) {
68 if (auto_running_) {
69 StartAuto();
70 } else {
71 StopAuto();
72 }
73 }
74
75 vision_valid_ = false;
76
77 if (!auto_running_) {
78 HandleDrivetrain(data);
79 HandleTeleop(data);
80 }
81
82 // Process any pending actions.
83 action_queue_.Tick();
84 was_running_ = action_queue_.Running();
85 }
Austin Schuhd0629b12017-03-22 22:37:16 -070086 int intake_accumulator_ = 0;
Campbell Crowley71b5f132017-02-18 13:16:08 -080087
88 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
89 bool is_control_loop_driving = false;
90
91 const double wheel = -data.GetAxis(kSteeringWheel);
92 const double throttle = -data.GetAxis(kDriveThrottle);
93 drivetrain_queue.status.FetchLatest();
Austin Schuhd0629b12017-03-22 22:37:16 -070094 if (drivetrain_queue.status.get()) {
95 robot_velocity_ = drivetrain_queue.status->robot_speed;
96 }
Campbell Crowley71b5f132017-02-18 13:16:08 -080097
Austin Schuh55c8d302017-04-05 19:25:37 -070098 if (data.PosEdge(kTurn1) || data.PosEdge(kTurn2) ||
99 data.PosEdge(kGearSlotBack)) {
Campbell Crowley71b5f132017-02-18 13:16:08 -0800100 if (drivetrain_queue.status.get()) {
101 left_goal_ = drivetrain_queue.status->estimated_left_position;
102 right_goal_ = drivetrain_queue.status->estimated_right_position;
103 }
104 }
Austin Schuh55c8d302017-04-05 19:25:37 -0700105 double current_left_goal = left_goal_ - wheel * 0.5 + throttle * 0.3;
106 double current_right_goal = right_goal_ + wheel * 0.5 + throttle * 0.3;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800107 if (data.IsPressed(kTurn1) || data.IsPressed(kTurn2)) {
108 is_control_loop_driving = true;
109 }
Austin Schuh55c8d302017-04-05 19:25:37 -0700110 if (data.IsPressed(kGearSlotBack)) {
111 is_control_loop_driving = true;
112 current_left_goal = left_goal_ - 0.03;
113 current_right_goal = right_goal_ - 0.03;
114 }
115 auto new_drivetrain_goal = drivetrain_queue.goal.MakeMessage();
116 new_drivetrain_goal->steering = wheel;
117 new_drivetrain_goal->throttle = throttle;
118 new_drivetrain_goal->quickturn = data.IsPressed(kQuickTurn);
119 new_drivetrain_goal->control_loop_driving = is_control_loop_driving;
120 new_drivetrain_goal->left_goal = current_left_goal;
121 new_drivetrain_goal->right_goal = current_right_goal;
122 new_drivetrain_goal->left_velocity_goal = 0;
123 new_drivetrain_goal->right_velocity_goal = 0;
124
125 new_drivetrain_goal->linear.max_velocity = 3.0;
126 new_drivetrain_goal->linear.max_acceleration = 20.0;
127
128 if (!new_drivetrain_goal.Send()) {
Campbell Crowley71b5f132017-02-18 13:16:08 -0800129 LOG(WARNING, "sending stick values failed\n");
130 }
131 }
132
133 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
134 // Default the intake to in.
Austin Schuhd0629b12017-03-22 22:37:16 -0700135 intake_goal_ = 0.07;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800136 bool lights_on = false;
Austin Schuhd0629b12017-03-22 22:37:16 -0700137 bool vision_track = false;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800138
139 if (!data.GetControlBit(ControlBit::kEnabled)) {
140 action_queue_.CancelAllActions();
141 LOG(DEBUG, "Canceling\n");
142 }
143
144 superstructure_queue.status.FetchLatest();
145 if (!superstructure_queue.status.get()) {
146 LOG(ERROR, "Got no superstructure status packet.\n");
147 return;
148 }
149
150 if (data.IsPressed(kIntakeDown)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700151 intake_goal_ = 0.235;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800152 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700153 if (data.IsPressed(kIntakeUp)) {
154 intake_goal_ = 0.0;
155 turret_goal_ = 0.0;
156 }
157
Campbell Crowley71b5f132017-02-18 13:16:08 -0800158
159 if (data.IsPressed(kVisionAlign)) {
160 // Align shot using vision
161 // TODO(campbell): Add vision aligning.
Adam Snaidere0554ef2017-03-11 23:02:45 -0800162 lights_on = true;
Austin Schuhd0629b12017-03-22 22:37:16 -0700163 vision_track = true;
164 }
165 if (data.PosEdge(kMiddleShot)) {
166 turret_goal_ = -M_PI;
167 }
168 if (data.PosEdge(kFarShot)) {
169 turret_goal_ = 0.0;
170 }
171
172 if (data.IsPressed(kCloseShot)) {
173 last_shot_distance_ = ShotDistance::CLOSE_SHOT;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800174 } else if (data.IsPressed(kMiddleShot)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700175 last_shot_distance_ = ShotDistance::MIDDLE_SHOT;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800176 } else if (data.IsPressed(kFarShot)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700177 last_shot_distance_ = ShotDistance::FAR_SHOT;
178 }
179
180 if (data.IsPressed(kVisionAlign) || data.IsPressed(kCloseShot) ||
181 data.IsPressed(kMiddleShot) || data.IsPressed(kFarShot) ||
182 data.IsPressed(kFire)) {
183 switch (last_shot_distance_) {
184 case ShotDistance::CLOSE_SHOT:
185 hood_goal_ = 0.285;
186 shooter_velocity_ = 335.0;
187 break;
188 case ShotDistance::MIDDLE_SHOT:
189 hood_goal_ = 0.63;
190 shooter_velocity_ = 384.0;
191 break;
192 case ShotDistance::FAR_SHOT:
193 hood_goal_ = 0.63;
194 shooter_velocity_ = 378.0;
195 break;
196 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800197 } else {
Austin Schuhd0629b12017-03-22 22:37:16 -0700198 //hood_goal_ = 0.15;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800199 shooter_velocity_ = 0.0;
200 }
201
202 if (data.IsPressed(kExtra1)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700203 //turret_goal_ = -M_PI * 3.0 / 4.0;
204 turret_goal_ += 0.150;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800205 }
206 if (data.IsPressed(kExtra2)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700207 //turret_goal_ = M_PI * 3.0 / 4.0;
208 turret_goal_ -= 0.150;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800209 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700210 turret_goal_ = ::std::max(::std::min(turret_goal_, M_PI), -M_PI);
Campbell Crowley71b5f132017-02-18 13:16:08 -0800211
212 fire_ = data.IsPressed(kFire) && shooter_velocity_ != 0.0;
Austin Schuhd0629b12017-03-22 22:37:16 -0700213 if (data.IsPressed(kVisionAlign)) {
214 fire_ = fire_ && superstructure_queue.status->turret.vision_tracking;
215 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800216
217 auto new_superstructure_goal = superstructure_queue.goal.MakeMessage();
Austin Schuhd0629b12017-03-22 22:37:16 -0700218 if (data.IsPressed(kHang)) {
219 intake_goal_ = 0.23;
220 }
221
Campbell Crowley71b5f132017-02-18 13:16:08 -0800222 new_superstructure_goal->intake.distance = intake_goal_;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800223 new_superstructure_goal->intake.disable_intake = false;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800224 new_superstructure_goal->turret.angle = turret_goal_;
Austin Schuhd0629b12017-03-22 22:37:16 -0700225 new_superstructure_goal->turret.track = vision_track;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800226 new_superstructure_goal->hood.angle = hood_goal_;
227 new_superstructure_goal->shooter.angular_velocity = shooter_velocity_;
228
229 new_superstructure_goal->intake.profile_params.max_velocity = 0.50;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800230 new_superstructure_goal->hood.profile_params.max_velocity = 5.0;
231
232 new_superstructure_goal->intake.profile_params.max_acceleration = 5.0;
Austin Schuhd0629b12017-03-22 22:37:16 -0700233 if (vision_track) {
234 new_superstructure_goal->turret.profile_params.max_acceleration = 35.0;
235 new_superstructure_goal->turret.profile_params.max_velocity = 10.0;
236 } else {
237 new_superstructure_goal->turret.profile_params.max_acceleration = 15.0;
238 new_superstructure_goal->turret.profile_params.max_velocity = 6.0;
239 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800240 new_superstructure_goal->hood.profile_params.max_acceleration = 25.0;
241
Austin Schuh3028b1d2017-03-11 22:12:13 -0800242 new_superstructure_goal->intake.voltage_rollers = 0.0;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800243 new_superstructure_goal->lights_on = lights_on;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800244
Austin Schuh8e4a7ee2017-04-05 19:26:06 -0700245 if (superstructure_queue.status->intake.position >
246 superstructure_queue.status->intake.unprofiled_goal_position + 0.01) {
247 intake_accumulator_ = 10;
248 }
249 if (intake_accumulator_ > 0) {
250 --intake_accumulator_;
251 if (!superstructure_queue.status->intake.estopped) {
252 new_superstructure_goal->intake.voltage_rollers = 10.0;
253 }
254 }
255
Campbell Crowley71b5f132017-02-18 13:16:08 -0800256 if (data.IsPressed(kHang)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700257 new_superstructure_goal->intake.voltage_rollers = -10.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800258 new_superstructure_goal->intake.disable_intake = true;
Austin Schuhd0629b12017-03-22 22:37:16 -0700259 } else if (data.IsPressed(kIntakeIn) || data.IsPressed(kFire)) {
260 if (robot_velocity_ > 2.0) {
261 new_superstructure_goal->intake.voltage_rollers = 12.0;
262 } else {
263 new_superstructure_goal->intake.voltage_rollers = 10.0;
264 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800265 } else if (data.IsPressed(kIntakeOut)) {
266 new_superstructure_goal->intake.voltage_rollers = -8.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800267 }
268 if (intake_goal_ < 0.1) {
269 new_superstructure_goal->intake.voltage_rollers =
270 ::std::min(8.0, new_superstructure_goal->intake.voltage_rollers);
Campbell Crowley71b5f132017-02-18 13:16:08 -0800271 }
272
273 if (data.IsPressed(kReverseIndexer)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700274 new_superstructure_goal->indexer.voltage_rollers = -12.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800275 new_superstructure_goal->indexer.angular_velocity = 4.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800276 new_superstructure_goal->indexer.angular_velocity = 1.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800277 } else if (fire_) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700278 new_superstructure_goal->indexer.voltage_rollers = 12.0;
279 switch (last_shot_distance_) {
280 case ShotDistance::CLOSE_SHOT:
281 new_superstructure_goal->indexer.angular_velocity = -0.90 * M_PI;
282 break;
283 case ShotDistance::MIDDLE_SHOT:
284 case ShotDistance::FAR_SHOT:
285 new_superstructure_goal->indexer.angular_velocity = -2.25 * M_PI;
286 break;
287 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800288 } else {
289 new_superstructure_goal->indexer.voltage_rollers = 0.0;
290 new_superstructure_goal->indexer.angular_velocity = 0.0;
291 }
292
293 LOG_STRUCT(DEBUG, "sending goal", *new_superstructure_goal);
294 if (!new_superstructure_goal.Send()) {
295 LOG(ERROR, "Sending superstructure goal failed.\n");
296 }
297 }
298
299 private:
Austin Schuh3028b1d2017-03-11 22:12:13 -0800300 void StartAuto() {
301 LOG(INFO, "Starting auto mode\n");
302
303 ::frc971::autonomous::AutonomousActionParams params;
304 ::frc971::autonomous::auto_mode.FetchLatest();
305 if (::frc971::autonomous::auto_mode.get() != nullptr) {
306 params.mode = ::frc971::autonomous::auto_mode->mode;
307 } else {
308 LOG(WARNING, "no auto mode values\n");
309 params.mode = 0;
310 }
311 action_queue_.EnqueueAction(
312 ::frc971::autonomous::MakeAutonomousAction(params));
313 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800314
315 void StopAuto() {
316 LOG(INFO, "Stopping auto mode\n");
317 action_queue_.CancelAllActions();
318 }
319
320 // Current goals to send to the robot.
321 double intake_goal_ = 0.0;
322 double turret_goal_ = 0.0;
323 double hood_goal_ = 0.3;
324 double shooter_velocity_ = 0.0;
325
326 // Goals to send to the drivetrain in closed loop mode.
Austin Schuh3028b1d2017-03-11 22:12:13 -0800327 double left_goal_ = 0.0;
328 double right_goal_ = 0.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800329
330 bool was_running_ = false;
331 bool auto_running_ = false;
332
333 bool vision_valid_ = false;
334
335 bool fire_ = false;
Austin Schuhd0629b12017-03-22 22:37:16 -0700336 double robot_velocity_ = 0.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800337
338 ::aos::common::actions::ActionQueue action_queue_;
339};
340
341} // namespace joysticks
342} // namespace input
343} // namespace y2017
344
345int main() {
346 ::aos::Init(-1);
347 ::y2017::input::joysticks::Reader reader;
348 reader.Run();
349 ::aos::Cleanup();
350}