Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <xsensdeviceapi.h>
00019 #include "serialkey.h"
00020
00021 #include <iostream>
00022 #include <list>
00023 #include <iomanip>
00024 #include <stdexcept>
00025
00026 #include <xsens/xstime.h>
00027
00028 #include "conio.h"
00029
00030 #include <ros/ros.h>
00031 #include <sensor_msgs/Imu.h>
00032
00033 class CallbackHandler : public XsCallback
00034 {
00035 public:
00036 CallbackHandler(size_t maxBufferSize = 5) : m_maxNumberOfPacketsInBuffer(maxBufferSize), m_numberOfPacketsInBuffer(0)
00037 #ifdef _MSC_VER
00038 {InitializeCriticalSection(&m_CriticalSection);}
00039 virtual ~CallbackHandler() throw() {DeleteCriticalSection(&m_CriticalSection);}
00040 #else
00041 {
00042
00043 pthread_mutexattr_t mAttr;
00044
00045
00046 pthread_mutexattr_settype(&mAttr, PTHREAD_MUTEX_RECURSIVE_NP);
00047
00048
00049 pthread_mutex_init(&m_CriticalSection, &mAttr);
00050
00051
00052 pthread_mutexattr_destroy(&mAttr);
00053
00054 }
00055 virtual ~CallbackHandler() throw() {pthread_mutex_destroy(&m_CriticalSection);}
00056 #endif
00057
00058 bool packetAvailable() const {Locker lock(*this); return m_numberOfPacketsInBuffer > 0;}
00059 XsDataPacket getNextPacket()
00060 {
00061 assert(packetAvailable());
00062 Locker lock(*this);
00063 XsDataPacket oldestPacket(m_packetBuffer.front());
00064 m_packetBuffer.pop_front();
00065 --m_numberOfPacketsInBuffer;
00066 return oldestPacket;
00067 }
00068
00069 protected:
00070 virtual void onDataAvailable(XsDevice*, const XsDataPacket* packet)
00071 {
00072 Locker lock(*this);
00073 assert(packet != 0);
00074 while (m_numberOfPacketsInBuffer >= m_maxNumberOfPacketsInBuffer)
00075 {
00076 (void)getNextPacket();
00077 }
00078 m_packetBuffer.push_back(*packet);
00079 ++m_numberOfPacketsInBuffer;
00080 assert(m_numberOfPacketsInBuffer <= m_maxNumberOfPacketsInBuffer);
00081 }
00082 private:
00083 #ifdef _MSC_VER
00084 mutable CRITICAL_SECTION m_CriticalSection;
00085 #else
00086 mutable pthread_mutex_t m_CriticalSection;
00087 #endif
00088 struct Locker
00089 {
00090 #ifdef _MSC_VER
00091 Locker(CallbackHandler const & self) : m_self(self) {EnterCriticalSection(&m_self.m_CriticalSection);}
00092 ~Locker() throw() {LeaveCriticalSection(&m_self.m_CriticalSection);}
00093 #else
00094 Locker(CallbackHandler const & self) : m_self(self) {pthread_mutex_lock(&m_self.m_CriticalSection);}
00095 ~Locker() throw() {pthread_mutex_unlock(&m_self.m_CriticalSection);}
00096 #endif
00097 CallbackHandler const & m_self;
00098 };
00099 size_t m_maxNumberOfPacketsInBuffer;
00100 size_t m_numberOfPacketsInBuffer;
00101 std::list<XsDataPacket> m_packetBuffer;
00102 };
00103
00104
00105 int main(int argc, char** argv)
00106 {
00107 ros::init(argc, argv, "receive_xsens");
00108 ros::NodeHandle nh;
00109
00110 ros::Publisher publisher = nh.advertise<sensor_msgs::Imu> ("/imu/data", 1);
00111
00112 if (!setSerialKey())
00113 {
00114 std::cout << "Invalid serial key." << std::endl;
00115 std::cout << "Press [ENTER] to continue." << std::endl; std::cin.get();
00116 return 1;
00117 }
00118
00119
00120 XsControl* control = XsControl::construct();
00121 assert(control != 0);
00122
00123 try
00124 {
00125
00126 XsPortInfoArray portInfoArray = XsScanner::scanPorts();
00127
00128
00129 XsPortInfoArray::const_iterator mtPort = portInfoArray.begin();
00130 while (mtPort != portInfoArray.end() && !mtPort->deviceId().isMtMk4()) {++mtPort;}
00131 if (mtPort == portInfoArray.end())
00132 {
00133 throw std::runtime_error("No MTi / MTx / MTmk4 device found. Aborting.");
00134 }
00135 std::cout << "Found a device with id: " << mtPort->deviceId().toString().toStdString() << " @ port: " << mtPort->portName().toStdString() << ", baudrate: " << mtPort->baudrate() << std::endl;
00136
00137
00138 if (!control->openPort(mtPort->portName().toStdString(), mtPort->baudrate()))
00139 {
00140 throw std::runtime_error("Could not open port. Aborting.");
00141 }
00142
00143 try
00144 {
00145
00146 XsDevice* device = control->device(mtPort->deviceId());
00147 assert(device != 0);
00148
00149
00150 std::cout << "Device: " << device->productCode().toStdString() << " opened." << std::endl;
00151
00152
00153 CallbackHandler callback;
00154 device->addCallbackHandler(&callback);
00155
00156
00157 if (!device->gotoMeasurement())
00158 {
00159 throw std::runtime_error("Could not put device into measurement mode. Aborting.");
00160 }
00161
00162
00163
00164 while (ros::ok())
00165 {
00166 if (callback.packetAvailable())
00167 {
00168
00169 sensor_msgs::Imu imuData;
00170 imuData.header.frame_id = "/imu";
00171 imuData.header.stamp = ros::Time::now();
00172
00173
00174 XsDataPacket packet = callback.getNextPacket();
00175
00176
00177 if (packet.containsOrientation()) {
00178
00179
00180
00181
00182
00183
00184
00185
00186 XsQuaternion quaternion = packet.orientationQuaternion();
00187
00188 imuData.orientation.x = quaternion.m_x;
00189 imuData.orientation.y = quaternion.m_y;
00190 imuData.orientation.z = quaternion.m_z;
00191 imuData.orientation.w = quaternion.m_w;
00192 }
00193
00194
00195 if (packet.containsCalibratedGyroscopeData()) {
00196 XsVector gyroscope = packet.calibratedGyroscopeData();
00197
00198 imuData.angular_velocity.x = gyroscope.at(0);
00199 imuData.angular_velocity.y = gyroscope.at(1);
00200 imuData.angular_velocity.z = gyroscope.at(2);
00201 }
00202
00203
00204 if (packet.containsCalibratedAcceleration()) {
00205 XsVector acceleration = packet.calibratedAcceleration();
00206
00207 imuData.linear_acceleration.x = acceleration.at(0);
00208 imuData.linear_acceleration.y = acceleration.at(1);
00209 imuData.linear_acceleration.z = acceleration.at(2);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 publisher.publish(imuData);
00219 }
00220
00221 ros::spinOnce();
00222 XsTime::msleep(1.0);
00223 }
00224
00225
00226 }
00227 catch (std::runtime_error const & error)
00228 {
00229 std::cout << error.what() << std::endl;
00230 }
00231 catch (...)
00232 {
00233 std::cout << "An unknown fatal error has occured. Aborting." << std::endl;
00234 }
00235
00236
00237 control->closePort(mtPort->portName().toStdString());
00238 }
00239 catch (std::runtime_error const & error)
00240 {
00241 std::cout << error.what() << std::endl;
00242 }
00243 catch (...)
00244 {
00245 std::cout << "An unknown fatal error has occured. Aborting." << std::endl;
00246 }
00247
00248
00249 control->destruct();
00250
00251 std::cout << "Successful exit." << std::endl;
00252
00253 return 0;
00254 }