00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <sys/ioctl.h>
00005 #include <fcntl.h>
00006 #include <signal.h>
00007
00008 #include "cmtdef.h"
00009 #include "xsens_time.h"
00010 #include "xsens_list.h"
00011 #include "cmtscan.h"
00012 #include "cmt3.h"
00013
00014 #include "IMUDataServer.H"
00015
00016 #include "Component/ModelParam.H"
00017 #include "Component/ModelOptionDef.H"
00018
00019 #include <iostream>
00020
00021 #ifndef IMUDATASERVER_C
00022 #define IMUDATASERVER_C
00023
00024 using namespace xsens;
00025
00026 const ModelOptionCateg MOC_SeaBeeIIIIMUDataServer = {
00027 MOC_SORTPRI_3, "Options" };
00028
00029 const ModelOptionDef OPT_EnableConfig =
00030 { MODOPT_ARG(int), "EnableConfig", &MOC_SeaBeeIIIIMUDataServer, OPTEXP_CORE,
00031 "Enable configuration of the IMU",
00032 "enable-config", '\0', "<float>", "0" };
00033
00034
00035 IMUDataServer::IMUDataServer(int id, OptionManager& mgr,
00036 const std::string& descrName, const std::string& tagName) :
00037 RobotBrainComponent(mgr, descrName, tagName),
00038 mEnableConfig(&OPT_EnableConfig, this, 0)
00039
00040 {
00041
00042
00043 res = XRV_OK;
00044 inited = false;
00045 }
00046
00047
00048 IMUDataServer::~IMUDataServer()
00049 {
00050 delete packet;
00051
00052 }
00053
00054 void IMUDataServer::stop2()
00055 {
00056 cout << "closing port: ";
00057 LFATAL("Testing to see if this fixes the port issues");
00058 return;
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 }
00069
00070 bool IMUDataServer::initMe()
00071 {
00072 unsigned long mtCount = doHardwareScan(cmt3, deviceIds);
00073
00074 if (mtCount == 0)
00075 {
00076 std::cout << "no MTs, quitting." << std::endl;
00077 cmt3.closePort();
00078 inited = true;
00079 return false;
00080 }
00081
00082 if(mEnableConfig.getVal() == 1)
00083 {
00084 getUserInputs(mode, settings);
00085 }
00086 else
00087 {
00088 mode = CMT_OUTPUTMODE_CALIB | CMT_OUTPUTMODE_ORIENT;
00089 settings = CMT_OUTPUTSETTINGS_ORIENTMODE_EULER;
00090 }
00091
00092 doMtSettings(cmt3, mode, settings, deviceIds);
00093
00094
00095 packet = new Packet((unsigned short) mtCount, cmt3.isXm());
00096 msg = new RobotSimEvents::IMUDataServerMessage();
00097
00098 inited = true;
00099 return true;
00100 }
00101
00102
00103 void IMUDataServer::registerTopics()
00104 {
00105 registerPublisher("IMUDataServerMessageTopic");
00106
00107 }
00108
00109
00110 void IMUDataServer::evolve()
00111 {
00112 static int frames = 0;
00113
00114 if (!inited)
00115 {
00116 cout << "initing..." << endl;
00117 if(!initMe())
00118 {
00119 LFATAL("No motion trackers found; can't continue");
00120
00121 return;
00122 }
00123 }
00124
00125 if (res != XRV_OK)
00126 {
00127 return;
00128 }
00129
00130 frames ++;
00131
00132 cmt3.waitForDataMessage(packet);
00133
00134 if(frames > 6)
00135 {
00136 frames = 0;
00137
00138 }
00139 else
00140 {
00141 return;
00142 }
00143
00144 msg->angleMode = -1;
00145
00146
00147 if ((mode & CMT_OUTPUTMODE_TEMP) != 0)
00148 {
00149 tdata = packet->getTemp(0);
00150
00151 msg->temp = tdata;
00152 }
00153
00154 if ((mode & CMT_OUTPUTMODE_CALIB) != 0)
00155 {
00156 caldata = packet->getCalData(0);
00157
00158 msg->accel.x = caldata.m_acc.m_data[0];
00159 msg->accel.y = caldata.m_acc.m_data[1];
00160 msg->accel.z = caldata.m_acc.m_data[2];
00161
00162 msg->gyro.x = caldata.m_gyr.m_data[0];
00163 msg->gyro.y = caldata.m_gyr.m_data[1];
00164 msg->gyro.z = caldata.m_gyr.m_data[2];
00165
00166 msg->mag.x = caldata.m_mag.m_data[0];
00167 msg->mag.y = caldata.m_mag.m_data[1];
00168 msg->mag.z = caldata.m_mag.m_data[2];
00169
00170 }
00171
00172 if ((mode & CMT_OUTPUTMODE_ORIENT) != 0)
00173 {
00174
00175 switch (settings & CMT_OUTPUTSETTINGS_ORIENTMODE_MASK)
00176 {
00177 case CMT_OUTPUTSETTINGS_ORIENTMODE_QUATERNION:
00178
00179 msg->angleMode = Mode::quat;
00180 qat_data = packet->getOriQuat(0);
00181
00182 msg->orientation.resize(4);
00183 msg->orientation[0] = qat_data.m_data[0];
00184 msg->orientation[1] = qat_data.m_data[1];
00185 msg->orientation[2] = qat_data.m_data[2];
00186 msg->orientation[3] = qat_data.m_data[3];
00187
00188 break;
00189
00190 case CMT_OUTPUTSETTINGS_ORIENTMODE_EULER:
00191
00192 msg->angleMode = Mode::euler;
00193 euler_data = packet->getOriEuler(0);
00194
00195 msg->orientation.resize(3);
00196 msg->orientation[0] = euler_data.m_roll;
00197 msg->orientation[1] = euler_data.m_pitch;
00198 msg->orientation[2] = euler_data.m_yaw;
00199
00200 break;
00201
00202 case CMT_OUTPUTSETTINGS_ORIENTMODE_MATRIX:
00203
00204 msg->angleMode = Mode::cos_mat;
00205 matrix_data = packet->getOriMatrix(0);
00206
00207 msg->orientation.resize(9);
00208 msg->orientation[0] = matrix_data.m_data[0][0];
00209 msg->orientation[1] = matrix_data.m_data[0][1];
00210 msg->orientation[2] = matrix_data.m_data[0][2];
00211 msg->orientation[3] = matrix_data.m_data[1][0];
00212 msg->orientation[4] = matrix_data.m_data[1][1];
00213 msg->orientation[5] = matrix_data.m_data[1][2];
00214 msg->orientation[6] = matrix_data.m_data[2][0];
00215 msg->orientation[7] = matrix_data.m_data[2][1];
00216 msg->orientation[8] = matrix_data.m_data[2][2];
00217
00218 break;
00219 }
00220
00221 if ((mode & CMT_OUTPUTMODE_POSITION) != 0)
00222 {
00223
00224 if (packet->containsPositionLLA())
00225 {
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 }
00242 else
00243 {
00244
00245 }
00246 }
00247 }
00248
00249 publish("IMUDataServerMessageTopic", msg);
00250 }
00251
00252
00253 void IMUDataServer::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg,
00254 const Ice::Current&)
00255 {
00256 if (eMsg->ice_isA("::RobotSimEvents::IMUDataServerMessage") && false)
00257 {
00258 RobotSimEvents::IMUDataServerMessagePtr msg = RobotSimEvents::IMUDataServerMessagePtr::dynamicCast(eMsg);
00259 cout << "temperature" << endl;
00260 cout << msg->temp << endl;
00261 cout << "acceleration" << endl;
00262 cout << msg->accel.x << "," << msg->accel.y << "," << msg->accel.z << endl;
00263 cout << "gyroscope" << endl;
00264 cout << msg->gyro.x << "," << msg->gyro.y << "," << msg->gyro.z << endl;
00265 cout << "magnetometer" << endl;
00266 cout << msg->mag.x << "," << msg->mag.y << "," << msg->mag.z << endl;
00267 switch(msg->angleMode)
00268 {
00269 case 0:
00270 cout << "quaternian" << endl;
00271 cout << msg->orientation[0] << "," << msg->orientation[1] << "," << msg->orientation[2] << "," << msg->orientation[3] << endl;
00272 break;
00273 case 1:
00274 cout << "euler" << endl;
00275 cout << msg->orientation[0] << "," << msg->orientation[1] << "," << msg->orientation[2] << endl;
00276 break;
00277 case 2:
00278 cout << "cosine matrix" << endl;
00279 cout << msg->orientation[0] << "," << msg->orientation[1] << "," << msg->orientation[2] << endl;
00280 cout << msg->orientation[3] << "," << msg->orientation[4] << "," << msg->orientation[5] << endl;
00281 cout << msg->orientation[6] << "," << msg->orientation[7] << "," << msg->orientation[8] << endl;
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290 int IMUDataServer::doHardwareScan(xsens::Cmt3 &cmt3, CmtDeviceId deviceIds[])
00291 {
00292 XsensResultValue res;
00293
00294 CmtPortInfo port = {0,0,0,"/dev/ttyUSB0"};
00295
00296 unsigned long portCount = 0;
00297 int mtCount;
00298
00299 std::cout << "Scanning for connected Xsens devices..." << std::endl;
00300
00301
00302 portCount = (xsens::cmtScanForIMU(port));
00303 std::cout << "done" << std::endl;
00304
00305 if (portCount == 0)
00306 {
00307 std::cout << "No MotionTrackers found" << std::endl;
00308 return 0;
00309 }
00310
00311 for (int i = 0; i < (int) portCount; i++)
00312 {
00313
00314 std::cout << "Using COM port at " << port.m_portName;
00315
00316 switch (port.m_baudrate)
00317 {
00318 case B9600:
00319 std::cout << "9k6";
00320 break;
00321 case B19200:
00322 std::cout << "19k2";
00323 break;
00324 case B38400:
00325 std::cout << "38k4";
00326 break;
00327 case B57600:
00328 std::cout << "57k6";
00329 break;
00330 case B115200:
00331 std::cout << "115k2";
00332 break;
00333 case B230400:
00334 std::cout << "230k4";
00335 break;
00336 case B460800:
00337 std::cout << "460k8";
00338 break;
00339 case B921600:
00340 std::cout << "921k6";
00341 break;
00342 default:
00343 std::cout << port.m_baudrate;
00344 }
00345 std::cout << "baud" << std::endl;
00346 }
00347
00348 std::cout << "Opening ports...";
00349
00350
00351
00352 res = cmt3.openPort(port.m_portName, port.m_baudrate);
00353
00354
00355 std::cout << "done" << std::endl;
00356
00357
00358 std::cout
00359 << "Retrieving MotionTracker count (excluding attached Xbus Master(s))"
00360 << std::endl;
00361
00362 mtCount = portCount;
00363 std::cout << "MotionTracker count: " << mtCount << std::endl;
00364
00365
00366 std::cout << "Retrieving MotionTrackers device ID(s)" << std::endl;
00367
00368
00369
00370
00371
00372
00373
00374
00375 deviceIds[0] = port.m_deviceId;
00376
00377 return mtCount;
00378
00379 }
00380
00381
00382
00383
00384
00385 void IMUDataServer::getUserInputs(CmtOutputMode &mode,
00386 CmtOutputSettings &settings)
00387 {
00388 mode = 0;
00389
00390 std::cout << "Select desired output:" << std::endl;
00391 std::cout << "1 - Calibrated data" << std::endl;
00392 std::cout << "2 - Orientation data and GPS Position (MTi-G only)"
00393 << std::endl;
00394 std::cout << "3 - Both Calibrated and Orientation data" << std::endl;
00395 std::cout << "4 - Temperature and Calibrated data" << std::endl;
00396 std::cout << "5 - Temperature and Orientation data" << std::endl;
00397 std::cout << "6 - Temperature, Calibrated and Orientation data"
00398 << std::endl;
00399 std::cout << "Enter your choice: ";
00400
00401 std::cin >> mode;
00402
00403
00404
00405
00406
00407
00408 switch (mode)
00409 {
00410 case 1:
00411 mode = CMT_OUTPUTMODE_CALIB;
00412 break;
00413 case 2:
00414 mode = CMT_OUTPUTMODE_ORIENT | CMT_OUTPUTMODE_POSITION;
00415 break;
00416 case 3:
00417 mode = CMT_OUTPUTMODE_CALIB | CMT_OUTPUTMODE_ORIENT;
00418 break;
00419 case 4:
00420 mode = CMT_OUTPUTMODE_TEMP | CMT_OUTPUTMODE_CALIB;
00421 break;
00422 case 5:
00423 mode = CMT_OUTPUTMODE_TEMP | CMT_OUTPUTMODE_ORIENT;
00424 break;
00425 case 6:
00426 mode = CMT_OUTPUTMODE_TEMP | CMT_OUTPUTMODE_CALIB
00427 | CMT_OUTPUTMODE_ORIENT;
00428 break;
00429 }
00430
00431 if ((mode & CMT_OUTPUTMODE_ORIENT) != 0)
00432 {
00433 settings = 0;
00434
00435 std::cout << std::endl;
00436 std::cout << "Select desired output format" << std::endl;
00437 std::cout << "1 - Quaternions" << std::endl;
00438 std::cout << "2 - Euler angles" << std::endl;
00439 std::cout << "3 - Matrix" << std::endl;
00440 std::cout << "Enter your choice: ";
00441
00442 std::cin >> settings;
00443
00444
00445
00446
00447
00448
00449
00450 switch (settings)
00451 {
00452 case 1:
00453 settings = CMT_OUTPUTSETTINGS_ORIENTMODE_QUATERNION;
00454 break;
00455 case 2:
00456 settings = CMT_OUTPUTSETTINGS_ORIENTMODE_EULER;
00457 break;
00458 case 3:
00459 settings = CMT_OUTPUTSETTINGS_ORIENTMODE_MATRIX;
00460 break;
00461 }
00462 }
00463 else
00464 {
00465 settings = 0;
00466 }
00467 settings |= CMT_OUTPUTSETTINGS_TIMESTAMP_SAMPLECNT;
00468 }
00469
00470
00471
00472
00473
00474
00475 void IMUDataServer::doMtSettings(xsens::Cmt3 &cmt3, CmtOutputMode &mode,
00476 CmtOutputSettings &settings, CmtDeviceId deviceIds[])
00477 {
00478 XsensResultValue res;
00479 unsigned long mtCount = cmt3.getMtCount();
00480
00481
00482 res = cmt3.gotoConfig();
00483
00484
00485 unsigned short sampleFreq;
00486 sampleFreq = cmt3.getSampleFrequency();
00487
00488
00489 std::cout << "Configuring your mode selection" << std::endl;
00490
00491 for (unsigned int i = 0; i < mtCount; i++)
00492 {
00493 CmtDeviceMode deviceMode(mode, settings, sampleFreq);
00494 if ((deviceIds[i] & 0xFFF00000) != 0x00500000)
00495 {
00496
00497 deviceMode.m_outputMode &= 0xFF0F;
00498 }
00499 res = cmt3.setDeviceMode(deviceMode, true, deviceIds[i]);
00500
00501 }
00502
00503
00504 res = cmt3.gotoMeasurement();
00505
00506 }
00507 #endif