00001 /* 00002 * SerialIMUDevice.cpp 00003 * 00004 * Created on: Jul 11, 2012 00005 * Author: mriedel 00006 */ 00007 00008 #include "SerialIMUDevice.hpp" 00009 00010 namespace TELEKYB_NAMESPACE { 00011 00012 SerialIMUDevice::SerialIMUDevice() 00013 : ThreadedSerialDevice(SerialIMUDeviceOptions::Instance().tDeviceName->getValue(), "\r"), 00014 options(SerialIMUDeviceOptions::Instance()), 00015 rawImuDataListener(NULL) 00016 { 00017 00018 // Configure Connection 00019 //std::cout << "BaudRate: " << options.tBaudRate->getValue().value() << std::endl; 00020 setTermiosAttrCFlag(options.tTermiosCFlags->getValue()); 00021 setTermiosAttrSpeed(options.tBaudRate->getValue().value(),options.tBaudRate->getValue().value()); 00022 std::cout << "device: " << SerialIMUDeviceOptions::Instance().tDeviceName->getValue() << std::endl; 00023 printTermiosAttr(); 00024 // register yourself as serial device listener. 00025 registerSerialDeviceListener(this); 00026 } 00027 00028 SerialIMUDevice::~SerialIMUDevice() { 00029 // TODO Auto-generated destructor stub 00030 } 00031 00032 //void printBits(char c) { 00033 // for (int i = 0; i < 8; i++) { 00034 // printf("%d", c >> (7-i) & 1); 00035 // } 00036 //} 00037 00038 void SerialIMUDevice::handleReadSerialData(const std::vector<char>& data) { 00039 // first output 00040 // std::cout << "Received something" << std::endl; 00041 // for (unsigned int i = 0; i < data.size(); ++i) { 00042 // printf("%02X",(int)data[i] & 0xff); 00043 // } 00044 // printf("\n"); 00045 00046 // Check Size 00047 if (data.size() != SERIAL_MSG_SIZE) { 00048 ROS_ERROR("Received message of wrong size!"); 00049 return; 00050 } 00051 00052 // Calculate CRC (and copy data into array) 00053 unsigned int crc = 0; 00054 for (unsigned int i = 0; i < SERIAL_MSG_SIZE - 2; i++ ) { 00055 crc += data[i]; 00056 // copy minus '=' 00057 msgData[i] = data[i] - '='; 00058 } 00059 crc %= 64; 00060 00061 // Check CRC 00062 if (crc != (data[SERIAL_MSG_SIZE - 2] - '=')) { 00063 ROS_ERROR("Received message with wrong CRC!"); 00064 return; 00065 } 00066 00067 //const unsigned char* startByte = (const unsigned char*)&data[0]; 00068 00069 // Reconstruct Data 00070 RawImuData rawData; 00071 rawData.gyroRoll = (msgData[0] << 4) | (msgData[1] >> 2); 00072 rawData.gyroPitch = ((msgData[1] & 0x03) << 8) | (msgData[2] << 2) | (msgData[3] >> 4); 00073 rawData.gyroYaw = ((msgData[3] & 0x0f) << 6) | msgData[4]; 00074 rawData.accX = (msgData[0+5] << 4) | (msgData[1+5] >> 2); 00075 rawData.accY = ((msgData[1+5] & 0x03) << 8) | (msgData[2+5] << 2) | (msgData[3+5] >> 4); 00076 rawData.accZ = ((msgData[3+5] & 0x0f) << 6) | msgData[4+5]; 00077 00078 if (batteryTimer.getElapsed().toDSec() > 2.0){ 00079 double batteryStatus = (msgData[10] + 106)/10.0; 00080 if (batteryStatus < 14.5){ 00081 if (batteryStatus < 13.7){ 00082 ROS_ERROR("Battery level is critical: %f", batteryStatus); 00083 } else { 00084 ROS_WARN("Battery level is low: %f", batteryStatus); 00085 } 00086 } 00087 batteryTimer.reset(); 00088 } 00089 00090 00091 if (rawImuDataListener) { 00092 rawImuDataListener->processRawIMUData(rawData); 00093 } 00094 } 00095 00096 00097 void SerialIMUDevice::setRawImuDataListener(RawImuDataListener* listener) 00098 { 00099 rawImuDataListener = listener; 00100 } 00101 00102 }