blob: 47b61e8f1dc3f478fb2d3e071be4573ec209ad59 [file] [log] [blame]
Brian Silverman59685152013-03-29 21:37:43 -07001#include <libusb-1.0/libusb.h>
2#include <memory>
3
4#include "aos/common/inttypes.h"
5#include "aos/atom_code/init.h"
6#include "aos/common/logging/logging.h"
7
8#include "frc971/control_loops/drivetrain/drivetrain.q.h"
9#include "frc971/control_loops/wrist/wrist_motor.q.h"
10#include "frc971/control_loops/angle_adjust/angle_adjust_motor.q.h"
11#include "frc971/control_loops/index/index_motor.q.h"
12#include "frc971/control_loops/shooter/shooter_motor.q.h"
13#include "frc971/input/gyro_board_data.h"
14#include "gyro_board/src/libusb-driver/libusb_wrap.h"
15
16#ifndef M_PI
17#define M_PI 3.14159265358979323846
18#endif
19
20using ::frc971::control_loops::drivetrain;
21using ::frc971::control_loops::wrist;
22using ::frc971::control_loops::angle_adjust;
23using ::frc971::control_loops::shooter;
24using ::frc971::control_loops::index_loop;
25
26namespace frc971 {
27namespace {
28
29inline double drivetrain_translate(int32_t in) {
30 return static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) *
31 (19.0 / 50.0) /*output reduction*/ * (64.0 / 24.0) /*encoder gears*/ *
32 (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI);
33}
34
35inline double wrist_translate(int32_t in) {
Austin Schuhe9f09792013-03-30 10:05:45 +000036 return static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) *
Brian Silverman59685152013-03-29 21:37:43 -070037 (14.0 / 50.0 * 20.0 / 84.0) /*gears*/ * (2 * M_PI);
38}
39
40inline double angle_adjust_translate(int32_t in) {
41 static const double kCableDiameter = 0.060;
Austin Schuhe9f09792013-03-30 10:05:45 +000042 return -static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*4x*/) *
Brian Silverman59685152013-03-29 21:37:43 -070043 ((0.75 + kCableDiameter) / (16.61125 + kCableDiameter)) /*pulleys*/ *
44 (2 * M_PI);
45}
46
47inline double shooter_translate(int32_t in) {
Austin Schuhe9f09792013-03-30 10:05:45 +000048 return static_cast<double>(in) / (32.0 /*cpr*/ * 4.0 /*quad*/) *
Brian Silverman59685152013-03-29 21:37:43 -070049 (15.0 / 34.0) /*gears*/ * (2 * M_PI);
50}
51
52inline double index_translate(int32_t in) {
53 return -static_cast<double>(in) / (128.0 /*cpr*/ * 2.0 /*2x*/) *
54 (1.0) /*gears*/ * (2 * M_PI);
55}
56
57} // namespace
58
59class GyroBoardReader {
60 public:
Austin Schuhe9f09792013-03-30 10:05:45 +000061 GyroBoardReader()
62 : top_rise_count_(0),
63 last_top_rise_count_(0),
64 top_fall_count_(0),
65 last_top_fall_count_(0),
66 bottom_rise_count_(0),
67 last_bottom_rise_count_(0),
68 bottom_fall_delay_count_(0),
69 last_bottom_fall_delay_count_(0),
70 bottom_fall_count_(0),
71 last_bottom_fall_count_(0),
72 wrist_rise_count_(0),
73 last_wrist_rise_count_(0),
74 shooter_angle_rise_count_(0),
75 last_shooter_angle_rise_count_(0) {
76 }
77
Brian Silverman59685152013-03-29 21:37:43 -070078 void Run() {
79 LibUSB libusb;
80
81 ::std::unique_ptr<LibUSBDeviceHandle> dev_handle(
82 libusb.FindDeviceWithVIDPID(kVid, kPid));
83 if (!dev_handle) {
84 LOG(FATAL, "couldn't find device\n");
85 }
86
87 uint8_t data[64];
88 GyroBoardData *real_data;
89 static_assert(sizeof(*real_data) <= sizeof(data), "it doesn't fit");
90
91 uint8_t *data_pointer = data;
92 memcpy(&real_data, &data_pointer, sizeof(data_pointer));
93 while (true) {
94 int read_bytes;
95 int r = dev_handle->interrupt_transfer(
96 kEndpoint, data, sizeof(data), &read_bytes, kReadTimeout);
97
98 if (r != 0) {
99 if (r == LIBUSB_ERROR_TIMEOUT) {
100 LOG(ERROR, "read timed out\n");
101 continue;
102 }
103 LOG(FATAL, "libusb gave error %d\n", r);
104 }
105
106 if (read_bytes != sizeof(data)) {
107 LOG(ERROR, "read %d bytes instead of %zu\n",
108 read_bytes, sizeof(data));
109 continue;
110 }
111
112 ProcessData(real_data);
113 }
114 }
115
116 private:
117 static const unsigned char kEndpoint = 0x81;
118 // in ms
119 // 0 is unlimited
120 static const unsigned int kReadTimeout = 1000;
121
122 // vendor ID
123 static const int32_t kVid = 0x1424;
124 // product ID
125 static const int32_t kPid = 0xd243;
126
Austin Schuhe9f09792013-03-30 10:05:45 +0000127 void UpdateWrappingCounter(
128 uint8_t current, uint8_t *last, int32_t *counter) {
129 if (*last > current) {
130 *counter += 0x100;
131 }
132 *counter = (*counter & 0xffffff00) | current;
133 *last = current;
134 }
135
Brian Silverman59685152013-03-29 21:37:43 -0700136 void ProcessData(GyroBoardData *data) {
137 data->NetworkToHost();
138
Austin Schuhe9f09792013-03-30 10:05:45 +0000139 UpdateWrappingCounter(data->top_rise_count,
140 &last_top_rise_count_, &top_rise_count_);
141 UpdateWrappingCounter(data->top_fall_count,
142 &last_top_fall_count_, &top_fall_count_);
143 UpdateWrappingCounter(data->bottom_rise_count,
144 &last_bottom_rise_count_, &bottom_rise_count_);
145 UpdateWrappingCounter(data->bottom_fall_delay_count,
146 &last_bottom_fall_delay_count_, &bottom_fall_delay_count_);
147 UpdateWrappingCounter(data->bottom_fall_count,
148 &last_bottom_fall_count_, &bottom_fall_count_);
149 UpdateWrappingCounter(data->wrist_rise_count,
150 &last_wrist_rise_count_, &wrist_rise_count_);
151 UpdateWrappingCounter(data->shooter_angle_rise_count,
152 &last_shooter_angle_rise_count_, &shooter_angle_rise_count_);
153
Brian Silverman59685152013-03-29 21:37:43 -0700154 drivetrain.position.MakeWithBuilder()
Austin Schuhe9f09792013-03-30 10:05:45 +0000155 .right_encoder(-drivetrain_translate(data->right_drive))
156 .left_encoder(drivetrain_translate(data->left_drive))
Brian Silverman59685152013-03-29 21:37:43 -0700157 .Send();
158
159 wrist.position.MakeWithBuilder()
160 .pos(wrist_translate(data->wrist))
161 .hall_effect(!data->wrist_hall_effect)
162 .calibration(wrist_translate(data->capture_wrist_rise))
163 .Send();
164
165 angle_adjust.position.MakeWithBuilder()
166 .angle(angle_adjust_translate(data->shooter_angle))
167 .bottom_hall_effect(!data->angle_adjust_bottom_hall_effect)
168 .middle_hall_effect(false)
169 .bottom_calibration(angle_adjust_translate(
170 data->capture_shooter_angle_rise))
171 .middle_calibration(angle_adjust_translate(
172 0))
173 .Send();
174
175 shooter.position.MakeWithBuilder()
176 .position(shooter_translate(data->shooter))
177 .Send();
178
179 index_loop.position.MakeWithBuilder()
180 .index_position(index_translate(data->indexer))
181 .top_disc_detect(!data->top_disc)
Austin Schuhe9f09792013-03-30 10:05:45 +0000182 .top_disc_posedge_count(top_rise_count_)
Brian Silverman59685152013-03-29 21:37:43 -0700183 .top_disc_posedge_position(index_translate(data->capture_top_rise))
Austin Schuhe9f09792013-03-30 10:05:45 +0000184 .top_disc_negedge_count(top_fall_count_)
Brian Silverman59685152013-03-29 21:37:43 -0700185 .top_disc_negedge_position(index_translate(data->capture_top_fall))
186 .bottom_disc_detect(!data->bottom_disc)
Austin Schuhe9f09792013-03-30 10:05:45 +0000187 .bottom_disc_posedge_count(bottom_rise_count_)
188 .bottom_disc_negedge_count(bottom_fall_count_)
Brian Silverman59685152013-03-29 21:37:43 -0700189 .bottom_disc_negedge_wait_position(index_translate(
190 data->capture_bottom_fall_delay))
Austin Schuhe9f09792013-03-30 10:05:45 +0000191 .bottom_disc_negedge_wait_count(bottom_fall_delay_count_)
Brian Silverman59685152013-03-29 21:37:43 -0700192 .Send();
193 }
Austin Schuhe9f09792013-03-30 10:05:45 +0000194
195 int32_t top_rise_count_;
196 uint8_t last_top_rise_count_;
197 int32_t top_fall_count_;
198 uint8_t last_top_fall_count_;
199 int32_t bottom_rise_count_;
200 uint8_t last_bottom_rise_count_;
201 int32_t bottom_fall_delay_count_;
202 uint8_t last_bottom_fall_delay_count_;
203 int32_t bottom_fall_count_;
204 uint8_t last_bottom_fall_count_;
205 int32_t wrist_rise_count_;
206 uint8_t last_wrist_rise_count_;
207 int32_t shooter_angle_rise_count_;
208 uint8_t last_shooter_angle_rise_count_;
Brian Silverman59685152013-03-29 21:37:43 -0700209};
210
211} // namespace frc971
212
213int main() {
214 ::aos::Init();
215 ::frc971::GyroBoardReader reader;
216 reader.Run();
217 ::aos::Cleanup();
218 return 0;
219}