00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include "Devices/IMU_MicroStrain_3DM_GX2.H"
00060 #include "Util/BinaryConversion.H"
00061 #include "Util/Timer.H"
00062 #include <GL/gl.h>
00063 #undef APIENTRY // otherwise it gets redefined between gl.h and glut.h???
00064 #include <GL/glut.h>
00065
00066
00067 static IMU_MicroStrain_3DM_GX2* theIMU = NULL;
00068
00069 void *IMU_MicroStrain_3DM_GX2_run(void *c);
00070
00071
00072 void *IMU_MicroStrain_3DM_GX2_run(void *c)
00073 {
00074 IMU_MicroStrain_3DM_GX2 *d = (IMU_MicroStrain_3DM_GX2 *) c;
00075 d ->run();
00076 return NULL;
00077 }
00078
00079
00080 void renderScene(void)
00081 {
00082
00083 RollPitchYawRecord rpyRecord;
00084 theIMU->getRollPitchYaw(rpyRecord);
00085 LDEBUG("Euler Angle r:%15.6f p:%15.6f y:%15.6f",
00086 rpyRecord.roll, rpyRecord.pitch, rpyRecord.yaw);
00087
00088
00089
00090
00091
00092
00093
00094 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00095
00096
00097 glLoadIdentity();
00098
00099
00100
00101
00102
00103 float sz = 0.25;
00104 glRotatef( rpyRecord.pitch/M_PI * 180.0, 1.0f,0.0f,0.0f);
00105 glRotatef( rpyRecord.yaw /M_PI * 180.0, 0.0f,1.0f,0.0f);
00106 glRotatef( rpyRecord.roll /M_PI * 180.0, 0.0f,0.0f,1.0f);
00107
00108 glBegin(GL_QUADS);
00109 glColor3f(0.0f, 0.0f, 1.0f);
00110 glVertex3f(-sz, -sz, -sz);
00111 glVertex3f(-sz, sz, -sz);
00112 glVertex3f( sz, sz, -sz);
00113 glVertex3f( sz, -sz, -sz);
00114
00115 glColor3f(1.0f, 1.0f, 0.0f);
00116 glVertex3f(-sz, -sz, sz);
00117 glVertex3f(-sz, sz, sz);
00118 glVertex3f( sz, sz, sz);
00119 glVertex3f( sz, -sz, sz);
00120
00121 glColor3f(1.0f, 0.0f, 0.0f);
00122 glVertex3f(-sz, -sz, -sz);
00123 glVertex3f(-sz, -sz, sz);
00124 glVertex3f(-sz, sz, sz);
00125 glVertex3f(-sz, sz, -sz);
00126
00127 glColor3f(0.0f, 1.0f,1.0f);
00128 glVertex3f( sz, -sz, -sz);
00129 glVertex3f( sz, -sz, sz);
00130 glVertex3f( sz, sz, sz);
00131 glVertex3f( sz, sz, -sz);
00132
00133 glColor3f(0.0f, 1.0f, 0.0f);
00134 glVertex3f(-sz, -sz, -sz);
00135 glVertex3f(-sz, -sz, sz);
00136 glVertex3f( sz, -sz, sz);
00137 glVertex3f( sz, -sz, -sz);
00138
00139 glColor3f(1.0f,0.0f,1.0f);
00140 glVertex3f(-sz, sz, -sz);
00141 glVertex3f(-sz, sz, sz);
00142 glVertex3f( sz, sz, sz);
00143 glVertex3f( sz, sz, -sz);
00144
00145 glEnd();
00146
00147
00148
00149
00150 glutSwapBuffers();
00151 }
00152
00153
00154 void *display_thread_function(void *ptr)
00155 {
00156
00157 int argc = 1;
00158 char** argv = new char*[1];
00159 argv[0] = new char[4];
00160 glutInit(&argc, argv);
00161
00162
00163 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
00164
00165 glutInitWindowPosition(100,100);
00166 glutInitWindowSize(320,320);
00167 glutCreateWindow("IMU Visualization");
00168 glutDisplayFunc(renderScene);
00169
00170
00171 glutIdleFunc(renderScene);
00172
00173
00174
00175
00176 glEnable(GL_DEPTH_TEST);
00177 glutMainLoop();
00178 return NULL;
00179 }
00180
00181
00182 IMU_MicroStrain_3DM_GX2::IMU_MicroStrain_3DM_GX2
00183 (OptionManager& mgr,
00184 const std::string& descrName,
00185 const std::string& tagName,
00186 const std::string& dev) :
00187 ModelComponent(mgr, descrName, tagName),
00188 itsSerial(new Serial(mgr))
00189 {
00190 addSubComponent(itsSerial);
00191 pthread_mutex_init(&itsResLock, NULL);
00192 pthread_mutex_init(&itsDataRequestedLock, NULL);
00193 itsRunDataUpdateThread = true;
00194 itsNewData = false;
00195
00196
00197 itsDataRequested = MAGNETOMETER;
00198
00199 }
00200
00201
00202 void IMU_MicroStrain_3DM_GX2::configureSerial(std::string dev)
00203 {
00204 itsSerialDev = dev;
00205 itsSerial->configure(itsSerialDev.c_str(), 115200);
00206 }
00207
00208
00209 void IMU_MicroStrain_3DM_GX2::start1()
00210 {
00211
00212 pthread_create(&itsDataUpdateThread, NULL,
00213 &IMU_MicroStrain_3DM_GX2_run, (void *) this);
00214
00215 if(theIMU != NULL)
00216 {
00217 LINFO("Trying to create a duplicate IMU!!!");
00218 exit(-1);
00219 }
00220 theIMU = this;
00221
00222
00223 pthread_create(&itsDataDisplayThread, NULL,
00224 display_thread_function, NULL);
00225
00226 itsRollPitchYawRecord.roll = 0.0;
00227 itsRollPitchYawRecord.pitch = 0.0;
00228 itsRollPitchYawRecord.yaw = 0.0;
00229 }
00230
00231
00232 void IMU_MicroStrain_3DM_GX2::stop1()
00233 {
00234 itsRunDataUpdateThread = false;
00235 usleep(300000);
00236 }
00237
00238
00239 IMU_MicroStrain_3DM_GX2::~IMU_MicroStrain_3DM_GX2()
00240 {
00241 pthread_mutex_destroy(&itsResLock);
00242 pthread_mutex_destroy(&itsDataRequestedLock);
00243 }
00244
00245
00246 bool IMU_MicroStrain_3DM_GX2::setDataRequested(DataRequested dataRequested)
00247 {
00248
00249 switch(dataRequested)
00250 {
00251 case ACCEL_AND_ANG_RATE: break;
00252 case DELTA_ANG_AND_VEL: break;
00253 case MAGNETOMETER: break;
00254 case ORIENTATION_MATRIX: break;
00255 case ROLL_PITCH_YAW: break;
00256 case TEMPERATURE: break;
00257
00258 default: LERROR("Unknown data requested: %d", dataRequested);
00259 return false;
00260 }
00261
00262 pthread_mutex_lock(&itsDataRequestedLock);
00263 itsDataRequested = dataRequested;
00264 pthread_mutex_unlock(&itsDataRequestedLock);
00265
00266 return true;
00267 }
00268
00269
00270 DataRequested IMU_MicroStrain_3DM_GX2::getDataRequested()
00271 {
00272 pthread_mutex_lock(&itsDataRequestedLock);
00273 DataRequested dataRequested = itsDataRequested;
00274 pthread_mutex_unlock(&itsDataRequestedLock);
00275
00276 return dataRequested;
00277 }
00278
00279
00280 bool IMU_MicroStrain_3DM_GX2::newData()
00281 {
00282 bool ret;
00283 pthread_mutex_lock(&itsResLock);
00284 ret = itsNewData;
00285 pthread_mutex_unlock(&itsResLock);
00286 return ret;
00287 }
00288
00289
00290 void IMU_MicroStrain_3DM_GX2::getAccelerationAndAngularRate()
00291 {
00292
00293 unsigned char cmd = char(0xC2);
00294 itsSerial->write(&cmd, 1);
00295
00296 unsigned char buffer[256];
00297 itsSerial->read(&buffer,31);
00298
00299 std::vector<unsigned char> response(buffer, buffer+31);
00300
00301
00302 if(response[0] == 0xC2) LDEBUG("Angular ACC");
00303 else LINFO("NOT Angular ACC");
00304
00305 pthread_mutex_lock(&itsResLock);
00306
00307
00308 itsAccelAndAngRateRecord.accelX =
00309 binaryconversion::FloatFromBytes(&response[1], true);
00310 itsAccelAndAngRateRecord.accelY =
00311 binaryconversion::FloatFromBytes(&response[5], true);
00312 itsAccelAndAngRateRecord.accelZ =
00313 binaryconversion::FloatFromBytes(&response[9], true);
00314
00315
00316
00317 itsAccelAndAngRateRecord.angRateX =
00318 binaryconversion::FloatFromBytes(&response[13], true);
00319 itsAccelAndAngRateRecord.angRateY =
00320 binaryconversion::FloatFromBytes(&response[17], true);
00321 itsAccelAndAngRateRecord.angRateZ =
00322 binaryconversion::FloatFromBytes(&response[21], true);
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 itsNewData = true;
00333 pthread_mutex_unlock(&itsResLock);
00334 }
00335
00336
00337 void IMU_MicroStrain_3DM_GX2::
00338 getAccelerationAndAngularRate(AccelAndAngRateRecord &record)
00339 {
00340 pthread_mutex_lock(&itsResLock);
00341
00342
00343 record.accelX = itsAccelAndAngRateRecord.accelX;
00344 record.accelY = itsAccelAndAngRateRecord.accelY;
00345 record.accelZ = itsAccelAndAngRateRecord.accelZ;
00346
00347
00348 record.angRateX = itsAccelAndAngRateRecord.angRateX;
00349 record.angRateY = itsAccelAndAngRateRecord.angRateY;
00350 record.angRateZ = itsAccelAndAngRateRecord.angRateZ;
00351
00352 itsNewData = false;
00353 pthread_mutex_unlock(&itsResLock);
00354 }
00355
00356
00357 void IMU_MicroStrain_3DM_GX2::getMagnetometer()
00358 {
00359
00360 unsigned char cmd = char(0xC7);
00361 itsSerial->write(&cmd, 1);
00362
00363 unsigned char buffer[256];
00364 itsSerial->read(&buffer,19);
00365
00366 std::vector<unsigned char> response(buffer, buffer+31);
00367
00368 if(response[0] == 0xC7) LDEBUG("Magnetometer");
00369 else LINFO("NOT Magnetometer");
00370
00371 pthread_mutex_lock(&itsResLock);
00372
00373
00374 itsMagnetometerRecord.magX =
00375 binaryconversion::FloatFromBytes(&response[1], true);
00376 itsMagnetometerRecord.magY =
00377 binaryconversion::FloatFromBytes(&response[5], true);
00378 itsMagnetometerRecord.magZ =
00379 binaryconversion::FloatFromBytes(&response[9], true);
00380
00381 itsNewData = true;
00382 pthread_mutex_unlock(&itsResLock);
00383 }
00384
00385
00386 void IMU_MicroStrain_3DM_GX2::getMagnetometer(MagnetometerRecord &record)
00387 {
00388 pthread_mutex_lock(&itsResLock);
00389
00390 record.magX = itsMagnetometerRecord.magX;
00391 record.magY = itsMagnetometerRecord.magY;
00392 record.magZ = itsMagnetometerRecord.magZ;
00393
00394 itsNewData = false;
00395 pthread_mutex_unlock(&itsResLock);
00396 }
00397
00398
00399 void IMU_MicroStrain_3DM_GX2::getRollPitchYaw()
00400 {
00401
00402 unsigned char cmd = char(0xCE);
00403 itsSerial->write(&cmd, 1);
00404
00405 unsigned char buffer[256];
00406 itsSerial->read(&buffer,19);
00407
00408 std::vector<unsigned char> response(buffer, buffer+31);
00409
00410 if(response[0] == 0xCE) LDEBUG("Roll, pitch, yaw");
00411 else LINFO("NOT roll, pitch, yaw");
00412
00413 pthread_mutex_lock(&itsResLock);
00414
00415
00416 itsRollPitchYawRecord.roll =
00417 binaryconversion::FloatFromBytes(&response[1], true);
00418 itsRollPitchYawRecord.pitch =
00419 binaryconversion::FloatFromBytes(&response[5], true);
00420 itsRollPitchYawRecord.yaw =
00421 binaryconversion::FloatFromBytes(&response[9], true);
00422
00423 itsNewData = true;
00424 pthread_mutex_unlock(&itsResLock);
00425 }
00426
00427
00428 void IMU_MicroStrain_3DM_GX2::getRollPitchYaw(RollPitchYawRecord &record)
00429 {
00430 pthread_mutex_lock(&itsResLock);
00431
00432 record.roll = itsRollPitchYawRecord.roll;
00433 record.pitch = itsRollPitchYawRecord.pitch;
00434 record.yaw = itsRollPitchYawRecord.yaw;
00435
00436 itsNewData = false;
00437 pthread_mutex_unlock(&itsResLock);
00438 }
00439
00440
00441 void IMU_MicroStrain_3DM_GX2::run()
00442 {
00443 Timer t(1000000);
00444 t.reset();
00445
00446 while(itsRunDataUpdateThread)
00447 {
00448
00449
00450
00451
00452
00453
00454
00455 pthread_mutex_lock(&itsDataRequestedLock);
00456 DataRequested dr = itsDataRequested;
00457 pthread_mutex_unlock(&itsDataRequestedLock);
00458
00459
00460 switch(dr)
00461 {
00462 case ACCEL_AND_ANG_RATE:
00463 getAccelerationAndAngularRate();
00464 break;
00465
00466 case DELTA_ANG_AND_VEL:
00467
00468 break;
00469
00470 case MAGNETOMETER:
00471 getMagnetometer();
00472 break;
00473
00474 case ORIENTATION_MATRIX:
00475
00476 break;
00477
00478 case ROLL_PITCH_YAW:
00479 getRollPitchYaw();
00480 break;
00481
00482 case TEMPERATURE:
00483
00484 break;
00485
00486 default: LERROR("Unknown data requested: %d",
00487 itsDataRequested);
00488 }
00489
00490 usleep(1000);
00491 LDEBUG("time %11.5f", t.get()/1000.0F);
00492 t.reset();
00493 }
00494
00495 pthread_exit(0);
00496 }
00497
00498
00499
00500
00501
00502