blob: a02142d6e807078073d73b300faa12cc6ae7ea0a [file] [log] [blame]
Adam Snaider18f44172016-10-22 15:30:21 -07001#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/input/joystick_input.h"
8#include "aos/common/input/driver_station_data.h"
9#include "aos/common/logging/logging.h"
10#include "aos/common/util/log_interval.h"
11#include "aos/common/time.h"
12#include "aos/common/actions/actions.h"
13
14#include "frc971/control_loops/drivetrain/drivetrain.q.h"
15#include "y2016_bot3/control_loops/intake/intake.q.h"
16#include "y2016_bot3/control_loops/intake/intake.h"
17#include "y2016_bot3/queues/ball_detector.q.h"
18
19#include "frc971/queues/gyro.q.h"
20#include "frc971/autonomous/auto.q.h"
21#include "y2016_bot3/actors/autonomous_actor.h"
22#include "y2016_bot3/control_loops/drivetrain/drivetrain_base.h"
23
24using ::frc971::control_loops::drivetrain_queue;
25using ::y2016_bot3::control_loops::intake_queue;
26
27using ::aos::input::driver_station::ButtonLocation;
28using ::aos::input::driver_station::ControlBit;
29using ::aos::input::driver_station::JoystickAxis;
30using ::aos::input::driver_station::POVLocation;
31
32namespace y2016_bot3 {
33namespace input {
34namespace joysticks {
35
36const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
37const ButtonLocation kQuickTurn(1, 5);
38
39const ButtonLocation kTurn1(1, 7);
40const ButtonLocation kTurn2(1, 11);
41
42// Buttons on the lexan driver station to get things running on bring-up day.
43const ButtonLocation kIntakeDown(3, 11);
44const ButtonLocation kIntakeIn(3, 12);
45const ButtonLocation kFire(3, 3);
46const ButtonLocation kIntakeOut(3, 9);
47const ButtonLocation kChevalDeFrise(3, 8);
48
49class Reader : public ::aos::input::JoystickInput {
50 public:
51 Reader()
52 : intake_goal_(0.0),
53 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()) {}
54
55 void RunIteration(const ::aos::input::driver_station::Data &data) override {
56 bool last_auto_running = auto_running_;
57 auto_running_ = data.GetControlBit(ControlBit::kAutonomous) &&
58 data.GetControlBit(ControlBit::kEnabled);
59 if (auto_running_ != last_auto_running) {
60 if (auto_running_) {
61 StartAuto();
62 } else {
63 StopAuto();
64 }
65 }
66
67 if (!data.GetControlBit(ControlBit::kEnabled)) {
68 // If we are not enabled, reset the waiting for zero bit.
69 LOG(DEBUG, "Waiting for zero.\n");
70 waiting_for_zero_ = true;
71 }
72
73 if (!auto_running_) {
74 HandleDrivetrain(data);
75 HandleTeleop(data);
76 }
77
78 // Process any pending actions.
79 action_queue_.Tick();
80 was_running_ = action_queue_.Running();
81 }
82
83 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
84 bool is_control_loop_driving = false;
85 static double left_goal = 0.0;
86 static double right_goal = 0.0;
87
88 const double wheel = -data.GetAxis(kSteeringWheel);
89 const double throttle = -data.GetAxis(kDriveThrottle);
90 drivetrain_queue.status.FetchLatest();
91
92 if (data.PosEdge(kTurn1) || data.PosEdge(kTurn2)) {
93 if (drivetrain_queue.status.get()) {
94 left_goal = drivetrain_queue.status->estimated_left_position;
95 right_goal = drivetrain_queue.status->estimated_right_position;
96 }
97 }
98 if (data.IsPressed(kTurn1) || data.IsPressed(kTurn2)) {
99 is_control_loop_driving = true;
100 }
101 if (!drivetrain_queue.goal.MakeWithBuilder()
102 .steering(wheel)
103 .throttle(throttle)
104 .quickturn(data.IsPressed(kQuickTurn))
105 .control_loop_driving(is_control_loop_driving)
106 .left_goal(left_goal - wheel * 0.5 + throttle * 0.3)
107 .right_goal(right_goal + wheel * 0.5 + throttle * 0.3)
108 .left_velocity_goal(0)
109 .right_velocity_goal(0)
110 .Send()) {
111 LOG(WARNING, "sending stick values failed\n");
112 }
113 }
114
115 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
116 intake_goal_ = y2016_bot3::constants::kIntakeRange.upper - 0.04;
117
118 if (!data.GetControlBit(ControlBit::kEnabled)) {
119 action_queue_.CancelAllActions();
120 LOG(DEBUG, "Canceling\n");
121 }
122
123 intake_queue.status.FetchLatest();
124 if (!intake_queue.status.get()) {
125 LOG(ERROR, "Got no intake status packet.\n");
126 }
127
128 if (intake_queue.status.get() && intake_queue.status->zeroed) {
129 if (waiting_for_zero_) {
130 LOG(DEBUG, "Zeroed! Starting teleop mode.\n");
131 waiting_for_zero_ = false;
132 }
133 } else {
134 waiting_for_zero_ = true;
135 }
136
137 bool ball_detected = false;
138 ::y2016_bot3::sensors::ball_detector.FetchLatest();
139 if (::y2016_bot3::sensors::ball_detector.get()) {
140 ball_detected = ::y2016_bot3::sensors::ball_detector->voltage > 2.5;
141 }
142 if (data.PosEdge(kIntakeIn)) {
143 saw_ball_when_started_intaking_ = ball_detected;
144 }
145
146 if (data.IsPressed(kIntakeIn)) {
147 is_intaking_ = (!ball_detected || saw_ball_when_started_intaking_);
148 } else {
149 is_intaking_ = false;
150 }
151
152 is_outtaking_ = data.IsPressed(kIntakeOut);
153
154 if (is_intaking_ || is_outtaking_) {
155 recently_intaking_accumulator_ = 20;
156 }
157
158 if (data.IsPressed(kIntakeDown)) {
159 if (recently_intaking_accumulator_) {
160 intake_goal_ = 0.1;
161 } else {
162 intake_goal_ = -0.05;
163 }
164 }
165
166 if (recently_intaking_accumulator_ > 0) {
167 --recently_intaking_accumulator_;
168 }
169
170 if (data.IsPressed(kChevalDeFrise)) {
171 traverse_unlatched_ = false;
172 traverse_down_ = true;
173 } else {
174 traverse_unlatched_ = true;
175 traverse_down_ = false;
176 }
177
178 if (!waiting_for_zero_) {
179 auto new_intake_goal = intake_queue.goal.MakeMessage();
180 new_intake_goal->angle_intake = intake_goal_;
181
182 new_intake_goal->max_angular_velocity_intake = 7.0;
183 new_intake_goal->max_angular_acceleration_intake = 40.0;
184
185 // Granny mode
186 /*
187 new_intake_goal->max_angular_velocity_intake = 0.2;
188 new_intake_goal->max_angular_acceleration_intake = 1.0;
189 */
190 if (is_intaking_) {
191 new_intake_goal->voltage_top_rollers = 12.0;
192 new_intake_goal->voltage_bottom_rollers = 12.0;
193 } else if (is_outtaking_) {
194 new_intake_goal->voltage_top_rollers = -12.0;
195 new_intake_goal->voltage_bottom_rollers = -7.0;
196 } else {
197 new_intake_goal->voltage_top_rollers = 0.0;
198 new_intake_goal->voltage_bottom_rollers = 0.0;
199 }
200
201 new_intake_goal->traverse_unlatched = traverse_unlatched_;
202 new_intake_goal->traverse_down = traverse_down_;
203 new_intake_goal->force_intake = true;
204
205 if (!new_intake_goal.Send()) {
206 LOG(ERROR, "Sending intake goal failed.\n");
207 } else {
208 LOG(DEBUG, "sending goal: intake: %f\n", intake_goal_);
209 }
210 }
211 }
212
213 private:
214 void StartAuto() {
215 LOG(INFO, "Starting auto mode\n");
216
217 actors::AutonomousActionParams params;
218 actors::auto_mode.FetchLatest();
219 if (actors::auto_mode.get() != nullptr) {
220 params.mode = actors::auto_mode->mode;
221 } else {
222 LOG(WARNING, "no auto mode values\n");
223 params.mode = 0;
224 }
225 action_queue_.EnqueueAction(actors::MakeAutonomousAction(params));
226 }
227
228 void StopAuto() {
229 LOG(INFO, "Stopping auto mode\n");
230 action_queue_.CancelAllActions();
231 }
232
233 // Whatever these are set to are our default goals to send out after zeroing.
234 double intake_goal_;
235
236 bool was_running_ = false;
237 bool auto_running_ = false;
238
239 bool traverse_unlatched_ = false;
240 bool traverse_down_ = false;
241
242 // If we're waiting for the subsystems to zero.
243 bool waiting_for_zero_ = true;
244
245 // If true, the ball was present when the intaking button was pressed.
246 bool saw_ball_when_started_intaking_ = false;
247
248 bool is_intaking_ = false;
249 bool is_outtaking_ = false;
250
251 int recently_intaking_accumulator_ = 0;
252
253 ::aos::common::actions::ActionQueue action_queue_;
254
255 const ::frc971::control_loops::drivetrain::DrivetrainConfig dt_config_;
256
257 ::aos::util::SimpleLogInterval no_drivetrain_status_ =
258 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.2), WARNING,
259 "no drivetrain status");
260};
261
262} // namespace joysticks
263} // namespace input
264} // namespace y2016_bot3
265
266int main() {
267 ::aos::Init(-1);
268 ::y2016_bot3::input::joysticks::Reader reader;
269 reader.Run();
270 ::aos::Cleanup();
271}