Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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"
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
00064 pthread_mutexattr_t mAttr;
00065
00066
00067 pthread_mutexattr_settype(&mAttr, PTHREAD_MUTEX_RECURSIVE_NP);
00068
00069
00070 pthread_mutex_init(&m_CriticalSection, &mAttr);
00071
00072
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
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
00147 XsControl* control = XsControl::construct();
00148 assert(control != 0);
00149
00150 try
00151 {
00152
00153 XsPortInfoArray portInfoArray = XsScanner::scanPorts();
00154
00155
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
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
00173 XsDevice* device = control->device(mtPort->deviceId());
00174 assert(device != 0);
00175
00176
00177 std::cout << "Device: " << device->productCode().toStdString() << " opened." << std::endl;
00178 ROS_INFO("Output Mode: %.4x", device->outputMode() );
00179
00180
00181 mtiG myXsens(device, argc, argv);
00182
00183
00184 CallbackHandler callback;
00185 device->addCallbackHandler(&callback);
00186
00187
00188 if (!device->gotoMeasurement())
00189 {
00190 throw std::runtime_error("Could not put device into measurement mode. Aborting.");
00191 }
00192
00193
00194
00195 while (ros::ok())
00196 {
00197 if (callback.packetAvailable())
00198 {
00199
00200 ROS_INFO_STREAM_THROTTLE(THROTTLE_VALUE, "PACKET INFORMATION: ");
00201
00202
00203 XsDataPacket packet = callback.getNextPacket();
00204
00205
00206 myXsens.fillData(&packet);
00207
00208
00209 myXsens.publish();
00210
00211 std::cout << std::flush;
00212 }
00213
00214 ros::spinOnce();
00215 XsTime::msleep(1.0);
00216 }
00217
00218
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
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
00242 control->destruct();
00243
00244 std::cout << "Successful exit." << std::endl;
00245
00246 return 0;
00247 }