IMUDataServer.C

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         //itsPort(new Serial(mgr))
00040 {
00041         //itsPort->configure("/dev/ttyUSB2", 57600, "8N2", false, false, 1);
00042         //addSubComponent(itsPort);
00043         res = XRV_OK;
00044         inited = false;
00045 }
00046 
00047 // ######################################################################
00048 IMUDataServer::~IMUDataServer()
00049 {
00050         delete packet;
00051         //cmt3.closePort();
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         /*cmt3.closePort();
00060         if(cmt3.isPortOpen())
00061         {
00062                 cout << "failed" << endl;
00063         }
00064         else
00065         {
00066                 cout << "success" << endl;
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         // Initialize packet for data
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         //registerSubscription("IMUDataServerMessageTopic");
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                         //cout << "No motion trackers found; can't continue" << endl;
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) //drop frames
00135         {
00136                 frames = 0;
00137                 //LFATAL("Temporary call to quit");
00138         }
00139         else
00140         {
00141                 return;
00142         }
00143 
00144         msg->angleMode = -1;
00145 
00146         // Output Temperature
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                         // Output: quaternion
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                         // Output: Euler
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                         // Output: Cosine Matrix
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                                 /* output position */
00227 /*                              CmtVector positionLLA = packet->getPositionLLA();
00228                                 if (res != XRV_OK)
00229                                 {
00230 
00231                                 }
00232 
00233                                 for (int i = 0; i < 2; i++)
00234                                 {
00235                                         double deg = positionLLA.m_data[0];
00236                                         double min = (deg - (int) deg) * 60;
00237                                         double sec = (min - (int) min) * 60;
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 // doHardwareScan
00288 //
00289 // Checks available COM ports and scans for MotionTrackers
00290 int IMUDataServer::doHardwareScan(xsens::Cmt3 &cmt3, CmtDeviceId deviceIds[])
00291 {
00292         XsensResultValue res;
00293         //List<CmtPortInfo> portInfo;// = {0,0,0,""};
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         //xsens::cmtScanPorts(portInfo);
00301         //portCount = portInfo.length();
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                 //std::cout << portInfo[i].m_baudrate << "|" << portInfo[i].m_deviceId << "|" << portInfo[i].m_portName << "|" << portInfo[i].m_portNr << std::endl;
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         //open the port which the device is connected to and connect at the device's baudrate.
00350         //for (int p = 0; p < (int) portCount; p++)
00351         //{
00352                 res = cmt3.openPort(port.m_portName, port.m_baudrate);
00353                 //                EXIT_ON_ERROR(res,"cmtOpenPort");
00354         //}
00355         std::cout << "done" << std::endl;
00356 
00357         //get the Mt sensor count.
00358         std::cout
00359                         << "Retrieving MotionTracker count (excluding attached Xbus Master(s))"
00360                         << std::endl;
00361         //mtCount = cmt3.getMtCount();
00362         mtCount = portCount;
00363         std::cout << "MotionTracker count: " << mtCount << std::endl;
00364 
00365         // retrieve the device IDs
00366         std::cout << "Retrieving MotionTrackers device ID(s)" << std::endl;
00367         /*for (int j = 0; j < mtCount; j++)
00368         {
00369                 res = cmt3.getDeviceId((unsigned char) (j + 1), deviceIds[j]);
00370                 //                EXIT_ON_ERROR(res,"getDeviceId");
00371                 std::cout << "Device ID at busId " << j + 1 << ","
00372                                 << (long) deviceIds[j] << std::endl;
00373         }*/
00374 
00375         deviceIds[0] = port.m_deviceId;
00376 
00377         return mtCount;
00378         //return 0;
00379 }
00380 
00381 //////////////////////////////////////////////////////////////////////////
00382 // getUserInputs
00383 //
00384 // Request user for output data
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         //nope
00404         /*if (mode < 1 || mode > 6) {
00405          std::cout << "\n\nPlease enter a valid output mode\n");
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                 //nope
00445                 /*if (settings < 1  || settings > 3) {
00446                  std::cout << "\n\nPlease enter a valid output format\n");
00447                  }*/
00448 
00449                 // Update outputSettings to match data specs of SetOutputSettings
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 // doMTSettings
00472 //
00473 // Set user settings in MTi/MTx
00474 // Assumes initialized global MTComm class
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         // set sensor to config sate
00482         res = cmt3.gotoConfig();
00483         //        EXIT_ON_ERROR(res,"gotoConfig");
00484 
00485         unsigned short sampleFreq;
00486         sampleFreq = cmt3.getSampleFrequency();
00487 
00488         // set the device output mode for the device(s)
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                         // not an MTi-G, remove all GPS related stuff
00497                         deviceMode.m_outputMode &= 0xFF0F;
00498                 }
00499                 res = cmt3.setDeviceMode(deviceMode, true, deviceIds[i]);
00500                 //                EXIT_ON_ERROR(res,"setDeviceMode");
00501         }
00502 
00503         // start receiving data
00504         res = cmt3.gotoMeasurement();
00505         //        EXIT_ON_ERROR(res,"gotoMeasurement");
00506 }
00507 #endif
Generated on Sun May 8 08:05:57 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3