peripherals  1.4.2
RoadNarrows Robotics Hardware Peripherals Package
yost.cxx
1 #include "rnr/imu/yost.h"
2 
3 #include <libusb-1.0/libusb.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <sys/time.h>
7 #include <sys/ioctl.h>
8 #include <time.h>
9 #include <math.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <termios.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <errno.h>
16 #include <unistd.h>
17 
18 using namespace std;
19 
20 //Option left open for constuctor function
21 Yost::Yost() {
22  USB_lock = NULL;
23  FD = -1;
24 }
25 
26 Yost::~Yost() {
27  if(FD >= 0) {
28  close(FD);
29  }
30  FD = -1;
31 }
32 
33 
34 //Returns -1 if no YOST sensor on USB
35 int Yost::checkYost() {
36  libusb_init(&tmpcntxt);
37  libusb_set_debug(tmpcntxt, 1);
38  //Looking for a USB devive with same vendor and product ID as YOST
39  USB_lock = libusb_open_device_with_vid_pid(tmpcntxt, YOST_ID_VENDOR,
40  YOST_ID_PRODUCTA);
41  if(USB_lock == NULL) {
42  USB_lock = libusb_open_device_with_vid_pid(tmpcntxt, YOST_ID_VENDOR,
43  YOST_ID_PRODUCTB);
44  if(USB_lock == NULL) {
45  return -1;
46  }
47  }
48  //Freeing up YOST for use if found
49  libusb_close(USB_lock);
50  USB_lock = NULL;
51  libusb_exit(tmpcntxt);
52  return YOST_WE_OK;
53 }
54 
55 //Returns -1 if unable to get attributes, -2 on failure to set attributes
56 int Yost::setAttributes(int fileDesc) {
57  struct termios tios;
58  int error;
59  error = tcgetattr(fileDesc, &tios);
60  if(error < 0) {
61  return -1;
62  }
63  cfsetispeed(&tios, B115200);
64  cfsetospeed(&tios, B115200);
65  tios.c_cflag |= (CLOCAL|CREAD);
66  tios.c_cflag &= ~PARENB;
67  tios.c_cflag &= ~CSIZE;
68  tios.c_cflag |= CS8;
69  tios.c_cflag &= ~CRTSCTS;
70  tios.c_iflag &= ~(IXON|IXOFF|IXANY);
71  //Submitting terminal attributes for communication
72  error = tcsetattr(fileDesc, TCSANOW, &tios);
73  if(error < 0) {
74  return -2;
75  }
76  return YOST_WE_OK;
77 }
78 
79 
80 //Returns: -1 on complete write failure, -2 if no bytes written,
81 //-3 if number of bytes written is not correct, -4 on read failure
82 int Yost::writeNRead(uint8_t *from, const char *to) {
83  size_t length = strlen(to);
84  int err;
85  err = write(FD, to, length);
86  if(err < 0) {
87  return -1;
88  }
89  if(err == 0) {
90  return -2;
91  }
92  if(err != length) {
93  return -3;
94  }
95  usleep(3000);
96  //Mandatory sleep length for a write from the YOST
97  err = read(FD,from,3000);
98  if(err <= 0) {
99  return -4;
100  }
101  return YOST_WE_OK;
102 }
103 
104 //Resets factory defaults on Yost
105 int Yost::setYostToDefault() {
106  const char *out = ":224\n";
107  size_t length = strlen(out);
108  int err;
109  err =write(FD, out, length);
110  if(err < 0) {
111  return -1;
112  }
113  return YOST_WE_OK;
114 }
115 
116 
117 //Returns -1 if unable to open designated device,
118 //-2 if unable to set attributes, -3 on transfer failure,
119 //-4 if device is not YOST
120 int Yost::checkIfYost(const char *dev) {
121  int err;
122  uint8_t buff[40];
123  FD = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY);
124  if(FD < 0) {
125  return -1;
126  }
127  err = setAttributes(FD);
128  if(err < 0) {
129  close(FD);
130  return -2;
131  }
132  usleep(500);
133  //Sending out a version check
134  err = writeNRead(buff, ":230\n");
135  if(err < 0){
136  close(FD);
137  return -3;
138  }
139  //Seeing if first byte recieved is correct
140  //(could be more specific, however the likelihood of another product
141  //returning the same byte given our version prompt is pretty low)
142  if(buff[0] != 0x54) {
143  close(FD);
144  return -4;
145  }
146  close(FD);
147  return YOST_WE_OK;
148 }
149 
150 //Returns: -1 if no YOST on USB, -2 if yost is not at ttyACM0 or ttyACM1
151 int Yost::OpenYost() {
152  int er;
153  er = checkYost();
154  if( er < 0) {
155  return -1;
156  }
157  //Assuming a potential of multiple ttyACM* devices
158  er = checkIfYost("/dev/ttyACM0");
159  if(er == 0) {
160  FD = open("/dev/ttyACM0", O_RDWR | O_NONBLOCK | O_NOCTTY);
161  if(FD < 0) {
162  return -1;
163  }
164  setYostToDefault();
165  resetKalman();
166  usleep(1000);
167  ResetAngles();
168  return YOST_WE_OK;
169  }
170  er = checkIfYost("/dev/ttyACM1");
171  if(er == 0) {
172  FD = open("/dev/ttyACM1", O_RDWR | O_NONBLOCK | O_NOCTTY);
173  if(FD < 0) {
174  return -1;
175  }
176  setYostToDefault();
177  resetKalman();
178  usleep(1000);
179  ResetAngles();
180  return YOST_WE_OK;
181  }
182  return -2;
183 }
184 
185 
186 //Quick close function to free the device
187 void Yost::CloseYost() {
188  if(FD >= 0) {
189  close(FD);
190  }
191  FD = -1;
192 }
193 
194 //Returns -1 on failure to set 0 point
195 int Yost::ResetAngles() {
196  const char *out = ":96\n";
197  size_t length = strlen(out);
198  int err;
199  err =write(FD, out, length);
200  if(err < 0) {
201  return -1;
202  }
203  return YOST_WE_OK;
204 }
205 
206 //Returns -1 on failure to disengage the magnetometer
207 int Yost::MagOff() {
208  const char *out = ":109,0\n";
209  size_t length = strlen(out);
210  int err;
211  err =write(FD, out, length);
212  if(err < 0) {
213  return -1;
214  }
215  return YOST_WE_OK;
216 }
217 
218 //Returns -1 on failure to disengage the magnetometer
219 int Yost::MagOn() {
220  const char *out = ":109,1\n";
221  size_t length = strlen(out);
222  int err;
223  err =write(FD, out, length);
224  if(err < 0) {
225  return -1;
226  }
227  return YOST_WE_OK;
228 }
229 
230 //returns -1 on transfer error
231 int Yost::ReadEuler(float &ex, float &why, float &zee) {
232  uint8_t buffr[YOST_MAX_BUFF_LEN];
233  int err;
234  err = writeNRead(buffr, ":1\n");
235  if(err < 6) {
236  return -1;
237  }
238  //Converting buffer to three float values (X, Y, Z)
239  const char * inString = strtok((char *)buffr, ",");
240  if(inString != NULL) {
241  ex = atof(inString);
242  }
243  else {
244  return -2;
245  }
246  inString = strtok(NULL, ",");
247  if(inString != NULL) {
248  why = atof(inString);
249  }
250  else {
251  return -2;
252  }
253  inString = strtok(NULL, ",");
254  if(inString != NULL) {
255  zee = atof(inString);
256  }
257  else {
258  return -2;
259  }
260  return YOST_WE_OK;
261 }
262 
263 
264 //returns -1 on transfer error
265 int Yost::ReadQuat(float &dubya, float &ex, float &why, float &zee) {
266  uint8_t buffr[YOST_MAX_BUFF_LEN];
267  int err;
268  err = writeNRead(buffr, ":0\n");
269  if(err < 0) {
270  return -1;
271  }
272  //Converting buffer to three float values (X, Y, Z)
273  const char * inString = strtok((char *)buffr, ",");
274  if(inString != NULL) {
275  ex = atof(inString);
276  }
277  else {
278  return -2;
279  }
280  inString = strtok(NULL, ",");
281  if(inString != NULL) {
282  why = atof(inString);
283  }
284  else {
285  return -2;
286  }
287  inString = strtok(NULL, ",");
288  if(inString != NULL) {
289  zee = atof(inString);
290  }
291  else {
292  return -2;
293  }
294  inString = strtok(NULL, ",");
295  if(inString != NULL) {
296  dubya = atof(inString);
297  }
298  else {
299  return -2;
300  }
301  return YOST_WE_OK;
302 }
303 
304 
305 
306 //returns -1 on transfer error
307 int Yost::ReadVectors(float &downx, float &downy, float &downz,
308  float &forx, float &fory, float &forz) {
309  uint8_t buffr[YOST_MAX_BUFF_LEN];
310  int err;
311  err = writeNRead(buffr, ":11\n");
312  if(err < 0) {
313  return -1;
314  }
315  //Converting buffer to three float values (X, Y, Z)
316  const char * inString = strtok((char *)buffr, ",");
317  if(inString != NULL) {
318  forx = atof(inString);
319  }
320  else {
321  return -2;
322  }
323  inString = strtok(NULL, ",");
324  if(inString != NULL) {
325  fory = atof(inString);
326  }
327  else {
328  return -2;
329  }
330  inString = strtok(NULL, ",");
331  if(inString != NULL) {
332  forz = atof(inString);
333  }
334  else {
335  return -2;
336  }
337  inString = strtok(NULL, ",");
338  if(inString != NULL) {
339  downx = atof(inString);
340  }
341  else {
342  return -2;
343  }
344  inString = strtok(NULL, ",");
345  if(inString != NULL) {
346  downy = atof(inString);
347  }
348  else {
349  return -2;
350  }
351  inString = strtok(NULL, ",");
352  if(inString != NULL) {
353  downz = atof(inString);
354  }
355  else {
356  return -2;
357  }
358  return YOST_WE_OK;
359 }
360 
361 //returns -1 on transfer error
362 int Yost::ReadDecoupleAngles(float &yaw, float &pitch, float &roll) {
363  float forx, fory, forz, downx, downy, downz;
364  double tmpx=0, tmpy=0, tmpz=0;
365  uint8_t buffr[YOST_MAX_BUFF_LEN];
366  int err;
367  err = writeNRead(buffr, ":11\n");
368  if(err < 0) {
369  return -1;
370  }
371  const char * inString = strtok((char *)buffr, ",");
372  if(inString != NULL) {
373  forx = atof(inString);
374  }
375  else {
376  return -2;
377  }
378  inString = strtok(NULL, ",");
379  if(inString != NULL) {
380  fory = atof(inString);
381  }
382  else {
383  return -2;
384  }
385  inString = strtok(NULL, ",");
386  if(inString != NULL) {
387  forz = atof(inString);
388  }
389  else {
390  return -2;
391  }
392  inString = strtok(NULL, ",");
393  if(inString != NULL) {
394  downx = atof(inString);
395  }
396  else {
397  return -2;
398  }
399  inString = strtok(NULL, ",");
400  if(inString != NULL) {
401  downy = atof(inString);
402  }
403  else {
404  return -2;
405  }
406  inString = strtok(NULL, ",");
407  if(inString != NULL) {
408  downz = atof(inString);
409  }
410  else {
411  return -2;
412  }
413  tmpx = (double)forx;
414  tmpy = (double)forz;
415  normalize(&tmpx,&tmpy,&tmpz);
416  yaw = atan2(tmpx,tmpy);
417  tmpx = (double)downx;
418  tmpy = (-1.00)*(double)downy;
419  normalize(&tmpx,&tmpy,&tmpz);
420  pitch = atan2(tmpx,tmpy);
421  tmpx = (double)downz;
422  tmpy = (-1.00)*(double)downy;
423  normalize(&tmpx,&tmpy,&tmpz);
424  roll = atan2(tmpx,tmpy);
425  return YOST_WE_OK;
426 }
427 
428 
429 //Returns -1 on transfer error
430 int Yost::ReadAccel(float &ex, float &why, float &zee) {
431  uint8_t buffr[YOST_MAX_BUFF_LEN];
432  int err;
433  err = writeNRead(buffr, ":66\n");
434  if(err < 0) {
435  return -1;
436  }
437  //Converting buffer to three float values (X, Y, Z)
438  const char * inString = strtok((char *)buffr, ",");
439  if(inString != NULL) {
440  ex = atof(inString);
441  }
442  inString = strtok(NULL, ",");
443  if(inString != NULL) {
444  why = atof(inString);
445  }
446  inString = strtok(NULL, ",");
447  if(inString != NULL) {
448  zee = atof(inString);
449  }
450  return YOST_WE_OK;
451 }
452 
453 
454 //Returns -1 on transfer error
455 int Yost::ReadConfidence(float &cee) {
456  uint8_t buffr[YOST_MAX_BUFF_LEN];
457  int err;
458  err = writeNRead(buffr, ":38\n");
459  if(err < 0) {
460  return -1;
461  }
462  //Converting buffer to float value
463  const char * inString = strtok((char *)buffr, ",");
464  if(inString != NULL) {
465  cee = atof(inString);
466  }
467  return YOST_WE_OK;
468 }
469 
470 
471 //Returns -1 on transfer error
472 int Yost::ReadTemp(int &tee) {
473  uint8_t buffr[YOST_MAX_BUFF_LEN];
474  int err;
475  err = writeNRead(buffr, ":37\n");
476  if(err < 0) {
477  return -1;
478  }
479  //Converting buffer to float value
480  const char * inString = strtok((char *)buffr, ",");
481  if(inString != NULL) {
482  tee = atoi(inString);
483  }
484  return YOST_WE_OK;
485 }
486 
487 
488 int Yost::gyroSpeed(int speed) {
489  const char *out;
490  if(speed == 0){
491  out = ":125,0\n";
492  }
493  if(speed == 1){
494  out = ":125,1\n";
495  }
496  if(speed == 2){
497  out = ":125,2\n";
498  }
499  size_t length = strlen(out);
500  int err;
501  err =write(FD, out, length);
502  if(err < 0) {
503  return -1;
504  }
505  return YOST_WE_OK;
506 }
507 
508 
509 int Yost::calibGyro() {
510  const char *out = ":165\n";
511  size_t length = strlen(out);
512  int err;
513  err =write(FD, out, length);
514  usleep(5000);
515  if(err < 0) {
516  return -1;
517  }
518  return YOST_WE_OK;
519 }
520 
521 int Yost::resetKalman() {
522  const char *out = ":120\n";
523  size_t length = strlen(out);
524  int err;
525  err =write(FD, out, length);
526  usleep(5000);
527  if(err < 0) {
528  return -1;
529  }
530  return YOST_WE_OK;
531 }
532 
533 void Yost::normalize(double *nx, double *ny, double *nz) {
534  float mag;
535  mag = sqrt(((*nx)*(*nx))+((*ny)*(*ny))+((*nz)*(*nz)));
536  if(mag != 0) {
537  *nx = (*nx)/mag;
538  *ny = (*ny)/mag;
539  *nz = (*nz)/mag;
540  }
541 }