blob: be49798f924c7d174f8348b9ebb603284c5f81d0 [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"
10
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12#include "frc971/queues/gyro_angle.q.h"
Brian Silverman756f9ff2014-01-17 23:40:23 -080013#include "frc971/autonomous/auto.q.h"
Brian Silvermanfac5c292014-02-17 15:26:57 -080014#include "frc971/control_loops/claw/claw.q.h"
15#include "frc971/control_loops/shooter/shooter.q.h"
Brian Silverman756f9ff2014-01-17 23:40:23 -080016
17using ::frc971::control_loops::drivetrain;
Brian Silverman756f9ff2014-01-17 23:40:23 -080018using ::frc971::sensors::gyro;
19
20using ::aos::input::driver_station::ButtonLocation;
21using ::aos::input::driver_station::JoystickAxis;
22using ::aos::input::driver_station::ControlBit;
23
24namespace frc971 {
25namespace input {
26namespace joysticks {
27
28const ButtonLocation kDriveControlLoopEnable1(1, 7),
29 kDriveControlLoopEnable2(1, 11);
30const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
31const ButtonLocation kShiftHigh(2, 1), kShiftLow(2, 3);
32const ButtonLocation kQuickTurn(1, 5);
Austin Schuh58d23682014-02-23 01:39:50 -080033
Austin Schuh06cbbf12014-02-22 02:07:31 -080034const ButtonLocation kFire(3, 11);
Austin Schuh58d23682014-02-23 01:39:50 -080035const ButtonLocation kUnload(3, 1);
36const ButtonLocation kReload(3, 9);
37
38const ButtonLocation kRollersOut(3, 12);
39const ButtonLocation kRollersIn(3, 10);
40
41const ButtonLocation kTuck(3, 8);
42const ButtonLocation kIntakePosition(3, 7);
43
44const ButtonLocation kLongShot(3, 5);
45const ButtonLocation kMediumShot(3, 3);
46const ButtonLocation kShortShot(3, 6);
47
48struct ClawGoal {
49 double angle;
50 double separation;
51};
52
53const ClawGoal kTuckGoal = {-2.273474, -0.749484};
54const ClawGoal kIntakeGoal = {-2.273474, 0.0};
55
56const ClawGoal kLongShotGoal = {-M_PI / 2.0 + 0.5, 0.05};
57const ClawGoal kMediumShotGoal = {-0.8, 0.05};
58const ClawGoal kShortShotGoal = {-0.2, 0.05};
Brian Silverman756f9ff2014-01-17 23:40:23 -080059
60class Reader : public ::aos::input::JoystickInput {
61 public:
Austin Schuh58d23682014-02-23 01:39:50 -080062 Reader()
63 : is_high_gear_(false),
64 shot_power_(0.1),
65 goal_angle_(0.0),
66 separation_angle_(0.0) {}
Brian Silverman756f9ff2014-01-17 23:40:23 -080067
68 virtual void RunIteration(const ::aos::input::driver_station::Data &data) {
Brian Silverman756f9ff2014-01-17 23:40:23 -080069
70 if (data.GetControlBit(ControlBit::kAutonomous)) {
71 if (data.PosEdge(ControlBit::kEnabled)){
72 LOG(INFO, "Starting auto mode\n");
73 ::frc971::autonomous::autonomous.MakeWithBuilder()
74 .run_auto(true).Send();
75 } else if (data.NegEdge(ControlBit::kEnabled)) {
76 LOG(INFO, "Stopping auto mode\n");
77 ::frc971::autonomous::autonomous.MakeWithBuilder()
78 .run_auto(false).Send();
79 }
Austin Schuh58d23682014-02-23 01:39:50 -080080 } else {
81 HandleTeleop(data);
Brian Silverman756f9ff2014-01-17 23:40:23 -080082 }
83 }
Austin Schuh58d23682014-02-23 01:39:50 -080084
85 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
86 bool is_control_loop_driving = false;
87 double left_goal = 0.0;
88 double right_goal = 0.0;
89 const double wheel = -data.GetAxis(kSteeringWheel);
90 const double throttle = -data.GetAxis(kDriveThrottle);
91 const double kThrottleGain = 1.0 / 2.5;
92 if (false && (data.IsPressed(kDriveControlLoopEnable1) ||
93 data.IsPressed(kDriveControlLoopEnable2))) {
94 // TODO(austin): Static sucks!
95 static double distance = 0.0;
96 static double angle = 0.0;
97 static double filtered_goal_distance = 0.0;
98 if (data.PosEdge(kDriveControlLoopEnable1) ||
99 data.PosEdge(kDriveControlLoopEnable2)) {
100 if (drivetrain.position.FetchLatest() && gyro.FetchLatest()) {
101 distance = (drivetrain.position->left_encoder +
102 drivetrain.position->right_encoder) /
103 2.0 -
104 throttle * kThrottleGain / 2.0;
105 angle = gyro->angle;
106 filtered_goal_distance = distance;
107 }
108 }
109 is_control_loop_driving = true;
110
111 // const double gyro_angle = Gyro.View().angle;
112 const double goal_theta = angle - wheel * 0.27;
113 const double goal_distance = distance + throttle * kThrottleGain;
114 const double robot_width = 22.0 / 100.0 * 2.54;
115 const double kMaxVelocity = 0.6;
116 if (goal_distance > kMaxVelocity * 0.02 + filtered_goal_distance) {
117 filtered_goal_distance += kMaxVelocity * 0.02;
118 } else if (goal_distance <
119 -kMaxVelocity * 0.02 + filtered_goal_distance) {
120 filtered_goal_distance -= kMaxVelocity * 0.02;
121 } else {
122 filtered_goal_distance = goal_distance;
123 }
124 left_goal = filtered_goal_distance - robot_width * goal_theta / 2.0;
125 right_goal = filtered_goal_distance + robot_width * goal_theta / 2.0;
126 is_high_gear_ = false;
127
128 LOG(DEBUG, "Left goal %f Right goal %f\n", left_goal, right_goal);
129 }
130 if (!drivetrain.goal.MakeWithBuilder()
131 .steering(wheel)
132 .throttle(throttle)
133 .highgear(is_high_gear_)
134 .quickturn(data.IsPressed(kQuickTurn))
135 .control_loop_driving(is_control_loop_driving)
136 .left_goal(left_goal)
137 .right_goal(right_goal)
138 .Send()) {
139 LOG(WARNING, "sending stick values failed\n");
140 }
141 if (data.PosEdge(kShiftHigh)) {
142 is_high_gear_ = false;
143 }
144 if (data.PosEdge(kShiftLow)) {
145 is_high_gear_ = true;
146 }
147 }
148
149 void SetGoal(ClawGoal goal) {
150 goal_angle_ = goal.angle;
151 separation_angle_ = goal.separation;
152 }
153
154 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
155 HandleDrivetrain(data);
156
157 if (data.IsPressed(kRollersIn) || data.IsPressed(kIntakePosition)) {
158 SetGoal(kIntakeGoal);
159 } else if (data.IsPressed(kTuck)) {
160 SetGoal(kTuckGoal);
161 }
162
163 // TODO(austin): Wait for the claw to go to position before shooting, and
164 // open the claw as part of the actual fire step.
165 if (data.IsPressed(kLongShot)) {
166 shot_power_ = 0.25;
167 SetGoal(kLongShotGoal);
168 } else if (data.IsPressed(kMediumShot)) {
169 shot_power_ = 0.15;
170 SetGoal(kMediumShotGoal);
171 } else if (data.IsPressed(kShortShot)) {
172 shot_power_ = 0.07;
173 SetGoal(kShortShotGoal);
174 }
175
176 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
177 .bottom_angle(goal_angle_)
178 .separation_angle(separation_angle_)
179 .intake(data.IsPressed(kRollersIn)
180 ? 12.0
181 : (data.IsPressed(kRollersOut) ? -12.0 : 0.0))
182 .centering(data.IsPressed(kRollersIn) ? 12.0 : 0.0)
183 .Send()) {
184 LOG(WARNING, "sending claw goal failed\n");
185 }
186
187 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
188 .shot_power(shot_power_)
189 .shot_requested(data.IsPressed(kFire))
190 .unload_requested(data.IsPressed(kUnload))
191 .load_requested(data.IsPressed(kReload))
192 .Send()) {
193 LOG(WARNING, "sending shooter goal failed\n");
194 }
195 }
196
Austin Schuh01c652b2014-02-21 23:13:42 -0800197 private:
Austin Schuh58d23682014-02-23 01:39:50 -0800198 bool is_high_gear_;
199 double shot_power_;
200 double goal_angle_;
201 double separation_angle_;
Brian Silverman756f9ff2014-01-17 23:40:23 -0800202};
203
204} // namespace joysticks
205} // namespace input
206} // namespace frc971
207
208int main() {
209 ::aos::Init();
210 ::frc971::input::joysticks::Reader reader;
211 reader.Run();
212 ::aos::Cleanup();
213}