Atomic6DOF.cc

00001 /*
00002  * Atomic6DOF.cc
00003  *
00004  *  Created on: Feb 18, 2010
00005  *      Author: uscr
00006  */
00007 
00008 #include "Atomic6DOF.h"
00009 
00010 #include <cstdio>
00011 #include <cstring>
00012 #include <cstdlib>
00013 #include <cmath>
00014 #include <termio.h>
00015 #include <sys/fcntl.h>
00016 #include <sys/file.h>
00017 #include <unistd.h>
00018 
00019 #define MAX_SERIAL_BUF_LENGTH           1024
00020 int serialCon;
00021 struct currentIMUData curIMUData;
00022 unsigned char serialBuf[MAX_SERIAL_BUF_LENGTH];
00023 int serialBufLength = 0;
00024 
00025 bool initializeAtomic6DOF() {
00026 
00027         memset(serialBuf, 0, MAX_SERIAL_BUF_LENGTH);
00028 
00029         if ((serialCon = open (SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY)) < 0)
00030                 return false;
00031 
00032         struct termios attr;
00033 
00034         if (tcgetattr(serialCon, &attr) < 0)
00035                 return false;
00036 
00037         /* 8 bits + baud rate + local control */
00038         attr.c_cflag = SERIAL_BAUD|CLOCAL|CREAD;
00039         attr.c_cflag &= ~CRTSCTS;
00040 
00041     attr.c_iflag = IXOFF;
00042     attr.c_iflag |= ~( IGNBRK | BRKINT | ISTRIP | IGNCR | ICRNL | IXON | INLCR | PARMRK);
00043         attr.c_oflag = 0;
00044         attr.c_lflag = 0;
00045         /* set output and input baud rates */
00046         cfsetospeed(&attr, SERIAL_BAUD);
00047         cfsetispeed(&attr, SERIAL_BAUD);
00048         if (tcsetattr(serialCon, TCSANOW, &attr) < 0)
00049                 return false;
00050 
00051         if (write(serialCon, "*#", 2) != 2)
00052                 return false;
00053 
00054         return true;
00055 
00056 }
00057 
00058 void shutdownAtomic6DOF() {
00059         close(serialCon);
00060 
00061 }
00062 
00063 bool isIMUDataReady() {
00064 
00065         unsigned char buffer[801];
00066         int numRead = read(serialCon, buffer, 800);
00067 
00068         //if we didn't read anything then don't continue
00069         if (numRead < 1)
00070                 return false;
00071 
00072         //copy what we read into our long-term buffer
00073         memcpy(serialBuf + serialBufLength, buffer, numRead);
00074         serialBufLength += numRead;
00075 
00076         //if we have more than two packets in our buffer, then
00077         // we should disregard our first ones and look at the last
00078         if (serialBufLength > 32) {
00079                 int lastAPos = serialBufLength - 1;
00080 
00081                 //find the position of the last "Z"
00082                 while (lastAPos >= 0 && serialBuf[lastAPos] != 'Z') {lastAPos--;}
00083                 //find the start of the last complete packet
00084                 while (lastAPos >= 0 && serialBuf[lastAPos] != 'A') {lastAPos--;}
00085 
00086                 unsigned char tempBuf[32];
00087                 serialBufLength -= lastAPos;
00088                 if (serialBufLength <= 32) {
00089                         memcpy (tempBuf, serialBuf + lastAPos, serialBufLength);
00090                         memcpy (serialBuf, tempBuf, serialBufLength);
00091                         memset (serialBuf + serialBufLength, 0, MAX_SERIAL_BUF_LENGTH - serialBufLength);
00092                 }
00093         }
00094 
00095         //if we still don't have enough to form a complete packet
00096         // or if our packet is bad, then don't continue
00097         if (serialBufLength < 16 || serialBuf[0] != 'A' || serialBuf[15] != 'Z')
00098                 return false;
00099 
00100 //      printf("%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X\n",
00101 //                      serialBuf[0], serialBuf[1], serialBuf[2], serialBuf[3], serialBuf[4], serialBuf[5],
00102 //                      serialBuf[6], serialBuf[7], serialBuf[8], serialBuf[9], serialBuf[10], serialBuf[11],
00103 //                      serialBuf[12], serialBuf[13], serialBuf[14], serialBuf[15]);
00104         //throw the data into the currentIMUData structure
00105         curIMUData.count = (double) (( ((serialBuf[1]&0x7F) << 8) | (serialBuf[2]&0xFF) ) & 0x7FFF);
00106         curIMUData.accel_x = (double) (( ((serialBuf[3]&0x3) << 8) | (serialBuf[4]&0xFF) ) & 0x3FF);
00107         curIMUData.accel_y = (double) (( ((serialBuf[5]&0x3) << 8) | (serialBuf[6]&0xFF) ) & 0x3FF);
00108         curIMUData.accel_z = (double) (( ((serialBuf[7]&0x3) << 8) | (serialBuf[8]&0xFF) ) & 0x3FF);
00109         curIMUData.gyro_pitch = (double) (( ((serialBuf[9]&0x3) << 8) | (serialBuf[10]&0xFF) ) & 0x3FF);
00110         curIMUData.gyro_roll = (double) (( ((serialBuf[11]&0x3) << 8) | (serialBuf[12]&0xFF) ) & 0x3FF);
00111         curIMUData.gyro_yaw = (double) (( ((serialBuf[13]&0x3) << 8) | (serialBuf[14]&0xFF) ) & 0x3FF);
00112 
00113         //adjust the data (i.e., accel raw -> angle  and  gyro raw -> angular velocity)
00114         curIMUData.adj_accel_x = curIMUData.accel_x*X_ACCEL_COEFF - X_ACCEL_OFFSET;
00115         curIMUData.adj_accel_y = curIMUData.accel_y*Y_ACCEL_COEFF - Y_ACCEL_OFFSET;
00116         curIMUData.adj_accel_z = curIMUData.accel_z*Z_ACCEL_COEFF - Z_ACCEL_OFFSET;
00117         curIMUData.adj_gyro_pitch = curIMUData.gyro_pitch*GYRO_COEFF - GYRO_OFFSET;
00118         curIMUData.adj_gyro_roll = curIMUData.gyro_roll*GYRO_COEFF - GYRO_OFFSET;
00119         curIMUData.adj_gyro_yaw = curIMUData.gyro_yaw*GYRO_COEFF - GYRO_OFFSET;
00120         curIMUData.adj_accel_pitch = asin(curIMUData.adj_accel_y)*RAD_TO_DEG;
00121         if (isnan(curIMUData.adj_accel_pitch))
00122                 curIMUData.adj_accel_pitch = (curIMUData.adj_accel_y < 0 ? -1 : 1) * 90.0;
00123         curIMUData.adj_accel_roll = asin(curIMUData.adj_accel_x)*RAD_TO_DEG;
00124         if (isnan(curIMUData.adj_accel_roll))
00125                 curIMUData.adj_accel_roll = (curIMUData.adj_accel_x < 0 ? -1 : 1) * 90.0;
00126 
00127 
00128         //shift the data over in the long-term buffer so we get new data next time
00129         serialBufLength -= 16;
00130         if (serialBufLength > 0) {
00131                 for (int i = 0; i < serialBufLength; i++)
00132                         serialBuf[i] = serialBuf[i + 16];
00133         }
00134 
00135         //we need this because of the occasional bad packet :*(
00136         memset(serialBuf + serialBufLength, 0, MAX_SERIAL_BUF_LENGTH - serialBufLength);
00137 
00138         return true;
00139 }
Generated on Sun May 8 08:41:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3