main.cpp
Go to the documentation of this file.
00001 /* 
00002  * @copyright
00003  * Copyright (c) Xsens Technologies B.V., 2006-2012. All rights reserved.
00004 
00005           This source code is provided under the MT SDK Software License Agreement
00006 and is intended for use only by Xsens Technologies BV and
00007            those that have explicit written permission to use it from
00008            Xsens Technologies BV.
00009 
00010           THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
00011            KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
00012            IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
00013            PARTICULAR PURPOSE.
00014  */
00015 
00026 #include "serialkey.h"
00027 
00028 #include <iostream>
00029 #include <list>
00030 #include <iomanip>
00031 #include <stdexcept>
00032 
00033 
00034 #include <xsens/xstime.h>
00035 
00036 #include "conio.h" // for non ANSI _kbhit() and _getch()
00037 
00038 #include <ros/ros.h>
00039 #include <ros/console.h>
00040 #include <sensor_msgs/Imu.h>
00041 #include <sensor_msgs/NavSatFix.h>
00042 #include <sensor_msgs/Temperature.h>
00043 #include <sensor_msgs/MagneticField.h>
00044 #include <sensor_msgs/FluidPressure.h>
00045 #include <geometry_msgs/Twist.h>
00046 
00047 #include "mtiG.h"
00048 
00049 
00054 class CallbackHandler : public XsCallback
00055 {
00056 public:
00057         CallbackHandler(size_t maxBufferSize = 5) : m_maxNumberOfPacketsInBuffer(maxBufferSize), m_numberOfPacketsInBuffer(0)
00058 #ifdef _MSC_VER
00059         {InitializeCriticalSection(&m_CriticalSection);}
00060         virtual ~CallbackHandler() throw() {DeleteCriticalSection(&m_CriticalSection);}
00061 #else
00062         {
00063           //create mutex attribute variable
00064           pthread_mutexattr_t mAttr;
00065 
00066           // setup recursive mutex for mutex attribute
00067           pthread_mutexattr_settype(&mAttr, PTHREAD_MUTEX_RECURSIVE_NP);
00068 
00069           // Use the mutex attribute to create the mutex
00070           pthread_mutex_init(&m_CriticalSection, &mAttr);
00071 
00072           // Mutex attribute can be destroy after initializing the mutex variable
00073           pthread_mutexattr_destroy(&mAttr);
00074 
00075         }
00076         virtual ~CallbackHandler() throw() {pthread_mutex_destroy(&m_CriticalSection);}
00077 #endif
00078 
00079         bool packetAvailable() const {Locker lock(*this); return m_numberOfPacketsInBuffer > 0;}
00080         XsDataPacket getNextPacket()
00081         {
00082                 assert(packetAvailable());
00083                 Locker lock(*this);
00084                 XsDataPacket oldestPacket(m_packetBuffer.front());
00085                 m_packetBuffer.pop_front();
00086                 --m_numberOfPacketsInBuffer;
00087                 return oldestPacket;
00088         }
00089 
00090 protected:
00091         virtual void onDataAvailable(XsDevice*, const XsDataPacket* packet)
00092         {
00093                 Locker lock(*this);
00094                 assert(packet != 0);
00095                 while (m_numberOfPacketsInBuffer >= m_maxNumberOfPacketsInBuffer)
00096                 {
00097                         (void)getNextPacket();
00098                 }
00099                 m_packetBuffer.push_back(*packet);
00100                 ++m_numberOfPacketsInBuffer;
00101                 assert(m_numberOfPacketsInBuffer <= m_maxNumberOfPacketsInBuffer);
00102         }
00103 private:
00104 #ifdef _MSC_VER
00105         mutable CRITICAL_SECTION m_CriticalSection;
00106 #else
00107         mutable pthread_mutex_t m_CriticalSection;
00108 #endif
00109         struct Locker
00110         {
00111 #ifdef _MSC_VER
00112                 Locker(CallbackHandler const & self) : m_self(self) {EnterCriticalSection(&m_self.m_CriticalSection);}
00113                 ~Locker() throw() {LeaveCriticalSection(&m_self.m_CriticalSection);}
00114 #else
00115                 Locker(CallbackHandler const & self) : m_self(self) {pthread_mutex_lock(&m_self.m_CriticalSection);}
00116                 ~Locker() throw() {pthread_mutex_unlock(&m_self.m_CriticalSection);}
00117 #endif
00118                 CallbackHandler const & m_self;
00119         };
00120         size_t m_maxNumberOfPacketsInBuffer;
00121         size_t m_numberOfPacketsInBuffer;
00122         std::list<XsDataPacket> m_packetBuffer;
00123 };
00124 
00125 
00126 
00130 int main(int argc, char** argv)
00131 {
00132         ros::init(argc, argv, "receive_xsens");
00133                 
00134         //DEBUG
00135         if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
00136            ros::console::notifyLoggerLevelsChanged();   
00137         }
00138 
00139         if (!setSerialKey())
00140         {
00141                 std::cout << "Invalid serial key." << std::endl;
00142                 std::cout << "Press [ENTER] to continue." << std::endl; std::cin.get();
00143                 return 1;
00144         }
00145 
00146         // Create XsControl object
00147         XsControl* control = XsControl::construct();
00148         assert(control != 0);
00149 
00150         try
00151         {
00152                 // Scan for connected devices
00153                 XsPortInfoArray portInfoArray = XsScanner::scanPorts();
00154 
00155                 // Find an MTi / MTx / MTmk4 device
00156                 XsPortInfoArray::const_iterator mtPort = portInfoArray.begin();
00157                 while (mtPort != portInfoArray.end() && !mtPort->deviceId().isMtx() && !mtPort->deviceId().isMtMk4()) {++mtPort;}
00158                 if (mtPort == portInfoArray.end())
00159                 {
00160                         throw std::runtime_error("No MTi / MTx / MTmk4 device found. Aborting.");
00161                 }
00162                 std::cout << "Found a device with id: " << mtPort->deviceId().toString().toStdString() << " @ port: " << mtPort->portName().toStdString() << ", baudrate: " << mtPort->baudrate() << std::endl;
00163 
00164                 // Open the port with the detected device
00165                 if (!control->openPort(mtPort->portName().toStdString(), mtPort->baudrate()))
00166                 {
00167                         throw std::runtime_error("Could not open port. Aborting.");
00168                 }
00169 
00170                 try
00171                 {
00172                         // Get the device object
00173                         XsDevice* device = control->device(mtPort->deviceId());
00174                         assert(device != 0);
00175                 
00176                         // Print information about detected MTi / MTx / MTmk4 device
00177                         std::cout << "Device: " << device->productCode().toStdString() << " opened." << std::endl;
00178                         ROS_INFO("Output Mode: %.4x",  device->outputMode() );
00179 
00180                         // Creates an mtiG object using the device object and command-line parameters                   
00181                         mtiG myXsens(device, argc, argv);
00182 
00183                         // Create and attach callback handler to device
00184                         CallbackHandler callback;
00185                         device->addCallbackHandler(&callback);
00186 
00187                         // Put the device in measurement mode
00188                         if (!device->gotoMeasurement())
00189                         {
00190                                 throw std::runtime_error("Could not put device into measurement mode. Aborting.");
00191                         }
00192 
00193                         //std::cout << "\nMain loop (press Ctrl+C to quit)" << std::endl;
00194                         //std::cout << std::string(79, '-') << std::endl;
00195                         while (ros::ok())
00196                         {
00197                                 if (callback.packetAvailable())
00198                                 {
00199                                         
00200                                         ROS_INFO_STREAM_THROTTLE(THROTTLE_VALUE, "PACKET INFORMATION: "); 
00201                                         
00202                                         // Retrieve a packet
00203                                         XsDataPacket packet = callback.getNextPacket();
00204 
00205                                         // Obtains and keeps all relevant data from the packet
00206                                         myXsens.fillData(&packet);
00207 
00208                                         // Publish ROS message
00209                                         myXsens.publish();                                      
00210 
00211                                         std::cout << std::flush;
00212                                 }
00213 
00214                                 ros::spinOnce();
00215                                 XsTime::msleep(1.0);
00216                         }
00217                         //std::cout << "\r" << std::string(79, '-') << "\n";
00218                         //std::cout << std::endl;
00219                 }
00220                 catch (std::runtime_error const & error)
00221                 {
00222                         std::cout << error.what() << std::endl;
00223                 }
00224                 catch (...)
00225                 {
00226                         std::cout << "An unknown fatal error has occured. Aborting." << std::endl;
00227                 }
00228 
00229                 // Close port
00230                 control->closePort(mtPort->portName().toStdString());
00231         }
00232         catch (std::runtime_error const & error)
00233         {
00234                 std::cout << error.what() << std::endl;
00235         }
00236         catch (...)
00237         {
00238                 std::cout << "An unknown fatal error has occured. Aborting." << std::endl;
00239         }
00240 
00241         // Free XsControl object
00242         control->destruct();
00243 
00244         std::cout << "Successful exit." << std::endl;
00245 
00246         return 0;
00247 }


mtig_driver
Author(s): Lucas Casanova Nogueira
autogenerated on Thu Jun 6 2019 18:25:27