00001 /*!@file Devices/GPS_USGlobalSat_.C class for interfacing with the 00002 USGlobalSat EM-408 GPS */ 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/GPS_USGlobalSat_EM_408.C $ 00035 // $Id: GPS_USGlobalSat_EM_408.C 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #include "Devices/GPS_USGlobalSat_EM_408.H" 00039 #include "Util/BinaryConversion.H" 00040 #include "Util/Timer.H" 00041 #include <GL/glut.h> 00042 00043 // A static pointer to the IMU 00044 static GPS_USGlobalSat_EM_408* theIMU = NULL; 00045 00046 void *GPS_USGlobalSat_EM_408_run(void *c); 00047 00048 // ###################################################################### 00049 void *GPS_USGlobalSat_EM_408_run(void *c) 00050 { 00051 GPS_USGlobalSat_EM_408 *d = (GPS_USGlobalSat_EM_408 *) c; 00052 d ->run(); 00053 return NULL; 00054 } 00055 00056 // ###################################################################### 00057 GPS_USGlobalSat_EM_408::GPS_USGlobalSat_EM_408 00058 (OptionManager& mgr, 00059 const std::string& descrName, 00060 const std::string& tagName, 00061 const std::string& dev) : 00062 ModelComponent(mgr, descrName, tagName), 00063 itsSerial(new Serial(mgr)) 00064 { 00065 addSubComponent(itsSerial); 00066 pthread_mutex_init(&itsResLock, NULL); 00067 itsRunDataUpdateThread = true; 00068 itsNewData = false; 00069 } 00070 00071 // ###################################################################### 00072 void GPS_USGlobalSat_EM_408::configureSerial(std::string dev) 00073 { 00074 itsSerialDev = dev; 00075 itsSerial->configure(itsSerialDev.c_str(), 115200); 00076 } 00077 00078 // ###################################################################### 00079 void GPS_USGlobalSat_EM_408::start1() 00080 { 00081 // thread to update the IMU data 00082 pthread_create(&itsDataUpdateThread, NULL, 00083 &GPS_USGlobalSat_EM_408_run, (void *) this); 00084 00085 if(theIMU != NULL) 00086 { 00087 LINFO("Trying to create a duplicate Gumbot!!!"); 00088 exit(-1); 00089 } 00090 theIMU = this; 00091 00092 // thread to make OpenGL rendering 00093 pthread_create(&itsDataDisplayThread, NULL, 00094 display_thread_function, NULL); 00095 } 00096 00097 // ###################################################################### 00098 void GPS_USGlobalSat_EM_408::stop1() 00099 { 00100 itsRunDataUpdateThread = false; 00101 usleep(300000); // make sure thread has exited 00102 } 00103 00104 // ###################################################################### 00105 GPS_USGlobalSat_EM_408::~GPS_USGlobalSat_EM_408() 00106 { 00107 pthread_mutex_destroy(&itsResLock); 00108 } 00109 00110 // ###################################################################### 00111 bool GPS_USGlobalSat_EM_408::newData() 00112 { 00113 bool ret; 00114 pthread_mutex_lock(&itsResLock); 00115 ret = itsNewData; 00116 pthread_mutex_unlock(&itsResLock); 00117 return ret; 00118 } 00119 00120 // ###################################################################### 00121 void GPS_USGlobalSat_EM_408::getAccelerationAndAngularRate() 00122 { 00123 // 0xC2 for acceleration and angular rate 00124 unsigned char cmd = char(0xC2); 00125 itsSerial->write(&cmd, 1); 00126 00127 unsigned char buffer[256]; 00128 itsSerial->read(&buffer,31); 00129 00130 std::vector<unsigned char> response(buffer, buffer+31); 00131 00132 //if(dwBytesRead != 31){ return SERIAL_READ_ERROR; } 00133 if(response[0] == 0xC2) LDEBUG("Angular ACC"); 00134 else LINFO("NOT Angular ACC"); 00135 00136 pthread_mutex_lock(&itsResLock); 00137 00138 // acceleration 00139 itsAccelAndAngRateRecord.accelX = 00140 binaryconversion::FloatFromBytes(&response[1], true); //bytes 1.. 4 00141 itsAccelAndAngRateRecord.accelY = 00142 binaryconversion::FloatFromBytes(&response[5], true); //bytes 5.. 8 00143 itsAccelAndAngRateRecord.accelZ = 00144 binaryconversion::FloatFromBytes(&response[9], true); //bytes 9..12 00145 00146 00147 // Angular Rate 00148 itsAccelAndAngRateRecord.angRateX = 00149 binaryconversion::FloatFromBytes(&response[13], true); //bytes 13.. 16 00150 itsAccelAndAngRateRecord.angRateY = 00151 binaryconversion::FloatFromBytes(&response[17], true); //bytes 17.. 20 00152 itsAccelAndAngRateRecord.angRateZ = 00153 binaryconversion::FloatFromBytes(&response[21], true); //bytes 21.. 24 00154 00155 // Timer 00156 // record->timer = response[25, 26, 27, 28]; 00157 00158 //wChecksum = MAKEWORD(response[30], response[29]); 00159 //calculate the checkusm, 29 = 31-2 don't include the checksum bytes 00160 //wCalculatedCheckSum = Checksum(&response[0], 29); 00161 //if(wChecksum != wCalculatedCheckSum) CHECKSUM_ERROR; 00162 00163 itsNewData = true; 00164 pthread_mutex_unlock(&itsResLock); 00165 } 00166 00167 // ###################################################################### 00168 void GPS_USGlobalSat_EM_408:: 00169 getAccelerationAndAngularRate(AccelAndAngRateRecord &record) 00170 { 00171 pthread_mutex_lock(&itsResLock); 00172 00173 // acceleration 00174 record.accelX = itsAccelAndAngRateRecord.accelX; 00175 record.accelY = itsAccelAndAngRateRecord.accelY; 00176 record.accelZ = itsAccelAndAngRateRecord.accelZ; 00177 00178 // Angular Rate 00179 record.angRateX = itsAccelAndAngRateRecord.angRateX; 00180 record.angRateY = itsAccelAndAngRateRecord.angRateY; 00181 record.angRateZ = itsAccelAndAngRateRecord.angRateZ; 00182 00183 itsNewData = false; 00184 pthread_mutex_unlock(&itsResLock); 00185 } 00186 00187 // ###################################################################### 00188 void GPS_USGlobalSat_EM_408::getMagnetometer() 00189 { 00190 // 0xC7 for magnetometer direction and magnitude 00191 unsigned char cmd = char(0xC7); 00192 itsSerial->write(&cmd, 1); 00193 00194 unsigned char buffer[256]; 00195 itsSerial->read(&buffer,19); 00196 00197 std::vector<unsigned char> response(buffer, buffer+31); 00198 00199 if(response[0] == 0xC7) LDEBUG("Magnetometer"); 00200 else LINFO("NOT Magnetometer"); 00201 00202 pthread_mutex_lock(&itsResLock); 00203 00204 // magnetometer 00205 itsMagnetometerRecord.magX = 00206 binaryconversion::FloatFromBytes(&response[1], true); //bytes 1.. 4 00207 itsMagnetometerRecord.magY = 00208 binaryconversion::FloatFromBytes(&response[5], true); //bytes 5.. 8 00209 itsMagnetometerRecord.magZ = 00210 binaryconversion::FloatFromBytes(&response[9], true); //bytes 9..12 00211 00212 itsNewData = true; 00213 pthread_mutex_unlock(&itsResLock); 00214 } 00215 00216 // ###################################################################### 00217 void GPS_USGlobalSat_EM_408::getMagnetometer(MagnetometerRecord &record) 00218 { 00219 pthread_mutex_lock(&itsResLock); 00220 00221 record.magX = itsMagnetometerRecord.magX; 00222 record.magY = itsMagnetometerRecord.magY; 00223 record.magZ = itsMagnetometerRecord.magZ; 00224 00225 itsNewData = false; 00226 pthread_mutex_unlock(&itsResLock); 00227 } 00228 00229 // ###################################################################### 00230 void GPS_USGlobalSat_EM_408::getRollPitchYaw() 00231 { 00232 // 0xCE for roll, pitch, yaw 00233 unsigned char cmd = char(0xCE); 00234 itsSerial->write(&cmd, 1); 00235 00236 unsigned char buffer[256]; 00237 itsSerial->read(&buffer,19); 00238 00239 std::vector<unsigned char> response(buffer, buffer+31); 00240 00241 if(response[0] == 0xCE) LDEBUG("Roll, pitch, yaw"); 00242 else LINFO("NOT roll, pitch, yaw"); 00243 00244 pthread_mutex_lock(&itsResLock); 00245 00246 // acceleration 00247 itsRollPitchYawRecord.roll = 00248 binaryconversion::FloatFromBytes(&response[1], true); //bytes 1.. 4 00249 itsRollPitchYawRecord.pitch = 00250 binaryconversion::FloatFromBytes(&response[5], true); //bytes 5.. 8 00251 itsRollPitchYawRecord.yaw = 00252 binaryconversion::FloatFromBytes(&response[9], true); //bytes 9..12 00253 00254 itsNewData = true; 00255 pthread_mutex_unlock(&itsResLock); 00256 } 00257 00258 // ###################################################################### 00259 void GPS_USGlobalSat_EM_408::getRollPitchYaw(RollPitchYawRecord &record) 00260 { 00261 pthread_mutex_lock(&itsResLock); 00262 00263 record.roll = itsRollPitchYawRecord.roll; 00264 record.pitch = itsRollPitchYawRecord.pitch; 00265 record.yaw = itsRollPitchYawRecord.yaw; 00266 00267 itsNewData = false; 00268 pthread_mutex_unlock(&itsResLock); 00269 } 00270 00271 // ###################################################################### 00272 void GPS_USGlobalSat_EM_408::run() 00273 { 00274 Timer t(1000000); 00275 t.reset(); 00276 00277 while(itsRunDataUpdateThread) 00278 { 00279 // do { 00280 // } while ((checksum & 0x0000FFFF)); // exit iff checksum correct 00281 00282 // get Acceleration and Angular Rate 00283 //getAccelerationAndAngularRate(); 00284 //getMagnetometer(); 00285 getRollPitchYaw(); 00286 00287 usleep(1000); 00288 LDEBUG("time %11.5f", t.get()/1000.0F); 00289 t.reset(); 00290 } 00291 00292 pthread_exit(0); 00293 } 00294 00295 // ###################################################################### 00296 /* So things look consistent in everyone's emacs... */ 00297 /* Local Variables: */ 00298 /* indent-tabs-mode: nil */ 00299 /* End: */