blob: 5922958cee1aae5a4c0a82d9d6fa459abe08cd22 [file] [log] [blame]
Austin Schuh9b360e92013-03-27 04:47:04 +00001#include "get.h"
2
3#include <google/gflags.h>
4#include <glog/logging.h>
5#include <iostream>
6#include <signal.h>
7#include <stdio.h>
8#include <queue>
9#include <unistd.h>
10#include <map>
11
12#include "signal_handler.h"
13
14DEFINE_int32(vid, 0x1424, "Vendor ID of the device.");
15DEFINE_int32(pid, 0xd243, "Product ID of the device.");
16DEFINE_bool(send, true,
17 "True if the code should send packets. (default: true)");
18
19// USB descriptors in use:
20// 0x81 Interrupt IN endpoint with the received CAN packets.
21// These packets are 64 bytes maximum, and have the same format as
22// SocketCAN.
23// 0x04 Interrupt OUT endpoint with the CAN packets to send.
24// These packets are 64 bytes maximum, and have the same format as
25// SocketCAN.
26// 0x82 Bulk IN endpoint with printf output.
27// 0x05 Bulk OUT endpoint for stdin.
28
29bool can_frame_priority_comparator::operator() (
30 const struct can_frame& x,
31 const struct can_frame& y) const {
32 // Error frames win first.
33 if (x.can_id & CAN_EFF_FLAG) {
34 return false;
35 }
36 if (y.can_id & CAN_EFF_FLAG) {
37 return true;
38 }
39 // Extended frames send the first 11 bits out just like a standard frame.
40 int x_standard_bits = (x.can_id & CAN_SFF_MASK);
41 int y_standard_bits = (y.can_id & CAN_SFF_MASK);
42 if (x_standard_bits == y_standard_bits) {
43 // RTR wins next.
44 bool x_rtr = (x.can_id & CAN_RTR_FLAG);
45 bool y_rtr = (y.can_id & CAN_RTR_FLAG);
46 if (x_rtr == y_rtr) {
47 // Now check if it is an EFF packet.
48 bool x_eff = (x.can_id & CAN_EFF_FLAG);
49 bool y_eff = (y.can_id & CAN_EFF_FLAG);
50 if (x_eff == y_eff) {
51 // Now compare the bits in the extended frame.
52 return (x.can_id & CAN_EFF_MASK) < (y.can_id & CAN_EFF_MASK);
53 } else if (x_eff < y_eff) {
54 return false;
55 } else {
56 return true;
57 }
58 } else if (x_rtr < y_rtr) {
59 return true;
60 } else {
61 return false;
62 }
63 } else {
64 return x_standard_bits < y_standard_bits;
65 }
66}
67
68class GyroDriver::PacketReceiver : public Thread {
69 public:
70 // refusing to send any more frames.
71 static const int kMaxRXFrames = 128;
72
73 explicit PacketReceiver(LibUSBDeviceHandle *dev_handle)
74 : Thread(), dev_handle_(dev_handle), rx_queue_(new can_priority_queue) {}
75
76 // Serve.
77 void operator()();
78
79 bool GetCanFrame(struct can_frame *msg);
80
81 private:
82 typedef std::priority_queue<struct can_frame,
83 std::vector<struct can_frame>,
84 can_frame_priority_comparator> can_priority_queue;
85
86 LibUSBDeviceHandle *dev_handle_;
87 boost::mutex rx_mutex_;
88 std::unique_ptr<can_priority_queue> rx_queue_;
89 //boost::condition_variable rx_cond_;
90};
91
92GyroDriver::GyroDriver(LibUSBDeviceHandle *dev_handle)
93 : dev_handle_(dev_handle), dbg_(new DbgReader(this)),
94 debug_thread_(new boost::thread(boost::ref(*dbg_))),
95 rx_(new GyroDriver::PacketReceiver(dev_handle)),
96 rx_thread_(new boost::thread(boost::ref(*rx_))) { }
97
98
99std::string GyroDriver::GetDebugData() {
100 char data[64];
101 int r;
102 int transferred;
103 r = dev_handle_->bulk_transfer(0x82,
104 (unsigned char *)data, sizeof(data),
105 &transferred, 0);
106 return std::string(data, transferred);
107}
108
109void GyroDriver::Terminate() {
110 rx_->Terminate();
111}
112
113GyroDriver::~GyroDriver() {
114 rx_->Terminate();
115 rx_thread_->join();
116 dbg_->Terminate();
117 debug_thread_->join();
118}
119
120//bool GyroDriver::GetCanFrame(struct can_frame *msg) {
121// return rx_->GetCanFrame(msg);
122//}
123
124struct DataStruct{
125 int64_t gyro_angle;
126
127 int32_t right_drive;
128 int32_t left_drive;
129 int32_t shooter_angle;
130 int32_t shooter;
131 int32_t indexer;
132 int32_t wrist;
133
134 int32_t capture_top_rise;
135 int32_t capture_top_fall;
136 int32_t capture_bottom_fall_delay;
137 int32_t capture_wrist_rise;
138 int32_t capture_shooter_angle_rise;
139
140 int8_t top_rise_count;
141
142 int8_t top_fall_count;
143
144 int8_t bottom_rise_count;
145
146 int8_t bottom_fall_delay_count;
147 int8_t bottom_fall_count;
148
149 int8_t wrist_rise_count;
150
151 int8_t shooter_angle_rise_count;
152} __attribute__((__packed__));
153
154void GyroDriver::PacketReceiver::operator()() {
155 int r;
156 int actual;
157 uint8_t data[64];
158 DataStruct *real_data;
159 real_data = (DataStruct *)data;
160
161 while (should_run()) {
162 r = dev_handle_->interrupt_transfer(
163 0x81, data, sizeof(data), &actual, 1000);
164 printf("size: %d\n",sizeof(DataStruct));
165 CHECK_GT(actual, 0);
166
167 if (r != 0) {
168 LOG(ERROR) << "Read Error. Read " << actual;
169 }
170
171 printf("angle: %d\n", real_data->gyro_angle);
172 printf("drivel: %d\n", real_data->left_drive);
173 printf("driver: %d\n", real_data->right_drive);
174 printf("shooter: %d\n", real_data->shooter);
175 printf("shooter_angle: %d\n", real_data->shooter_angle);
176 printf("indexer: %d\n", real_data->indexer);
177 printf("wrist: %d\n", real_data->wrist);
178 printf("capture:\n");
179 printf(" wrist_rise{%d}: %d\n", real_data->wrist_rise_count,
180 real_data->capture_wrist_rise);
181 printf(" shooter_angle_rise{%d}: %d\n", real_data->shooter_angle_rise_count,
182 real_data->capture_shooter_angle_rise);
183 printf(" bottom_rise_delay{%d}; \n", real_data->bottom_rise_count);
184 printf(" bottom_fall_delay{%d,%d}: %d\n", real_data->bottom_fall_count,
185 real_data->bottom_fall_delay_count,
186 real_data->capture_bottom_fall_delay);
187 printf(" top_rise{%d}: %d\n", real_data->top_rise_count,
188 real_data->capture_top_rise);
189 printf(" top_fall{%d}: %d\n", real_data->top_fall_count,
190 real_data->capture_top_fall);
191
192
193
194
195 //if (actual > 1) {
196 // rx_cond_.notify_all();
197 //}
198 }
199 //rx_cond_.notify_all();
200 LOG(INFO) << "Receive thread down.";
201}
202
203DbgReader::DbgReader(GyroDriver *gyro)
204 : Thread(), gyro_(gyro) {}
205
206void DbgReader::operator()() {
207 unsigned char data[64];
208 LOG(INFO) << "Running debug dump thread.";
209 while (should_run()) {
210 printf("%s", gyro_->GetDebugData().c_str());
211 }
212 LOG(INFO) << "Exiting debug dump thread.";
213}
214
215
216int main(int argc, char ** argv) {
217 int r;
218 google::InitGoogleLogging(argv[0]);
219 google::ParseCommandLineFlags(&argc, &argv, true);
220 google::InstallFailureSignalHandler();
221
222 LibUSB libusb;
223
224 {
225 std::unique_ptr<LibUSBDeviceHandle> dev_handle(
226 CHECK_NOTNULL(libusb.FindDeviceWithVIDPID(FLAGS_vid, FLAGS_pid)));
227
228 GyroDriver gyro(dev_handle.release());
229
230 while(true){
231 sleep(50);
232 }
233 }
234 return 0;
235}