MRPT  1.9.9
CIMUXSens_MT4.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled headers
11 
15 
16 #include <iostream>
17 #include <thread>
18 
19 #if MRPT_HAS_xSENS_MT4
20 /* Copyright (c) Xsens Technologies B.V., 2006-2012. All rights reserved.
21 
22  This source code is provided under the MT SDK Software License Agreement
23 and is intended for use only by Xsens Technologies BV and
24  those that have explicit written permission to use it from
25  Xsens Technologies BV.
26 
27  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
28  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
29  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
30  PARTICULAR PURPOSE.
31  */
32 #include <xsens/xsresultvalue.h>
33 #include <xsens/xsbytearray.h>
34 #include <xsens/xsmessagearray.h>
35 #include <xsens/xsdeviceid.h>
36 #include <xsens/xsportinfo.h>
37 #include <xsens/xsoutputmode.h>
38 #include <xsens/xsoutputsettings.h>
40 #include <xsens/protocolhandler.h>
41 #include <xsens/usbinterface.h>
42 #include <xsens/serialinterface.h>
43 #include <xsens/streaminterface.h>
44 #include <xsens/xsportinfoarray.h>
45 #include <xsens/xsdatapacket.h>
46 #include <xsens/xsstatusflag.h>
47 #include <xsens/xstime.h>
48 #include <xsens/legacydatapacket.h>
49 #include <xsens/int_xsdatapacket.h>
51 
52 class DeviceClass
53 {
54  public:
55  DeviceClass() : m_streamInterface(nullptr) {}
56  ~DeviceClass()
57  {
58  if (m_streamInterface)
59  {
60  delete m_streamInterface;
61  m_streamInterface = nullptr;
62  }
63  }
64 
65  /*! \brief Open an IO device
66  \param portInfo The info to use for opening the port
67  \return True when successful
68  */
69  bool openPort(const XsPortInfo& portInfo)
70  {
71  if (portInfo.isUsb())
72  m_streamInterface = new UsbInterface();
73  else
74  m_streamInterface = new SerialInterface();
75 
76  if (m_streamInterface->open(portInfo) != XRV_OK) return false;
77  return true;
78  }
79 
80  /*! \brief Close an IO device
81  */
82  void close()
83  {
84  if (m_streamInterface) m_streamInterface->close();
85  }
86 
87  /*! \brief Read available data from the open IO device
88  \details This function will attempt to read all available data from the
89  open device (COM port
90  or USB port).
91  The function will read from the device, but it won't wait for data to
92  become available.
93  \param raw A XsByteArray to where the read data will be stored.
94  \return Whether data has been read from the IO device
95  */
96  XsResultValue readDataToBuffer(XsByteArray& raw)
97  {
98  // always read data and append it to the cache before doing analysis
99  const int maxSz = 8192;
100  XsResultValue res = m_streamInterface->readData(maxSz, raw);
101  if (raw.size()) return XRV_OK;
102 
103  return res;
104  }
105 
106  /*! \brief Read all messages from the buffered read data after adding new
107  data supplied in \a rawIn
108  \details This function will read all present messages in the read
109  buffer. In order for this function
110  to work, you need to call readDataToBuffer() first.
111  \param rawIn The buffered data in which to search for messages
112  \param messages The messages found in the data
113  \return The messages that were read.
114  */
115  XsResultValue processBufferedData(
116  XsByteArray& rawIn, XsMessageArray& messages)
117  {
118  ProtocolHandler protocol;
119 
120  if (rawIn.size()) m_dataBuffer.append(rawIn);
121 
122  int popped = 0;
123  messages.clear();
124 
125  for (;;)
126  {
127  XsByteArray raw(
128  m_dataBuffer.data() + popped, m_dataBuffer.size() - popped);
129  XsMessage message;
130  MessageLocation location = protocol.findMessage(message, raw);
131 
132  if (location.isValid())
133  {
134  // message is valid, remove data from cache
135  popped += location.m_size + location.m_startPos;
136  messages.push_back(message);
137  }
138  else
139  {
140  if (popped) m_dataBuffer.pop_front(popped);
141 
142  if (messages.empty()) return XRV_TIMEOUTNODATA;
143 
144  return XRV_OK;
145  }
146  }
147  }
148 
149  /*! \brief Wait for the requested XsXbusMessageId
150  \param xmid The message id to wait for
151  \param rcv The received message
152  \return Whether the requested message was found
153  */
154  bool waitForMessage(XsXbusMessageId xmid, XsMessage& rcv)
155  {
157  XsMessageArray msgs;
158  bool foundAck = false;
159  do
160  {
161  readDataToBuffer(data);
162  processBufferedData(data, msgs);
163  for (XsMessageArray::iterator it = msgs.begin(); it != msgs.end();
164  ++it)
165  if ((*it).getMessageId() == xmid)
166  {
167  foundAck = true;
168  rcv = *it;
169  }
170  } while (!foundAck);
171  return foundAck;
172  }
173 
174  /*! \brief Write a message to the IO device
175  \param msg The message to write
176  \return Whether the message could be written
177  */
178  bool writeMessage(const XsMessage& msg)
179  {
180  XsByteArray raw;
181  if (ProtocolHandler::composeMessage(raw, msg) < 0) return false;
182 
183  return (m_streamInterface->writeData(raw) == XRV_OK);
184  }
185 
186  /*! \brief Put a device in config mode
187  \return True when the device acknowledged config mode
188  */
189  bool gotoConfig()
190  {
191  XsMessage snd(XMID_GotoConfig, 0), rcv;
192  writeMessage(snd);
193 
194  return waitForMessage(XMID_GotoConfigAck, rcv);
195  }
196 
197  /*! \brief Put a device in measurement mode
198  \return True when the device acknowledged measurement mode
199  */
200  bool gotoMeasurement()
201  {
202  XsMessage snd(XMID_GotoMeasurement, 0), rcv;
203  writeMessage(snd);
204 
205  return waitForMessage(XMID_GotoMeasurementAck, rcv);
206  }
207 
208  /*! \brief Request the product code from a device
209  \return The product code when ok, otherwise an empty XsString
210  */
211  XsString getProductCode()
212  {
213  XsMessage snd(XMID_ReqProductCode, 0), rcv;
214  writeMessage(snd);
215 
216  if (waitForMessage(XMID_ProductCode, rcv))
217  {
218  const char* pc = (const char*)rcv.getDataBuffer(0);
219  std::string result(pc ? pc : "", rcv.getDataSize());
220  std::string::size_type thingy = result.find(" ");
221  if (thingy < 20)
222  result.erase(
223  result.begin() + thingy, result.end()); // lint !e534
224  return XsString(result);
225  }
226  else
227  return XsString();
228  }
229 
230  /*! \brief Request the device id from a device
231  \return The device id (XsDeviceId) when ok, otherwise an empty
232  XsDeviceId
233  */
234  XsDeviceId getDeviceId()
235  {
236  XsMessage snd(XMID_ReqDid, 0), rcv;
237  writeMessage(snd);
238 
239  if (waitForMessage(XMID_DeviceId, rcv))
240  {
241  return rcv.getDataLong();
242  }
243  else
244  return XsDeviceId();
245  }
246 
247  /*! \brief Set the device mode of a device (outputmode and outputsettings)
248  \param outputMode The XsOutputMode to set
249  \param outputSettings The XsOutputSettings to set
250  \return True when successful
251  */
252  bool setDeviceMode(
253  const XsOutputMode& outputMode, const XsOutputSettings& outputSettings)
254  {
256 
257  sndOM.resizeData(2);
258  sndOM.setDataShort((uint16_t)outputMode);
259  writeMessage(sndOM);
260  if (!waitForMessage(XMID_SetOutputModeAck, rcv)) return false;
261 
263  snd.resizeData(4);
264  snd.setDataLong((uint32_t)outputSettings);
265  writeMessage(sndOS);
266  if (!waitForMessage(XMID_SetOutputSettingsAck, rcv)) return false;
267 
268  return true;
269  }
270 
271  /*! \brief Set the output configuration of a device
272  \param config An array XsOutputConfigurationArray) containing the one or
273  multiple XsOutputConfigurations
274  \return True when successful
275  */
276  bool setOutputConfiguration(XsOutputConfigurationArray& config)
277  {
279  if (config.size() == 0)
280  {
281  snd.setDataShort((uint16_t)XDI_None, 0);
282  snd.setDataShort(0, 2);
283  }
284  else
285  {
286  for (XsSize i = 0; i < (XsSize)config.size(); ++i)
287  {
288  snd.setDataShort((uint16_t)config[i].m_dataIdentifier, i * 4);
289  snd.setDataShort(config[i].m_frequency, i * 4 + 2);
290  }
291  }
292  writeMessage(snd);
293 
294  return waitForMessage(XMID_SetOutputConfigurationAck, rcv);
295  }
296 
297  private:
298  StreamInterface* m_streamInterface;
299  XsByteArray m_dataBuffer;
300 };
301 #endif
302 
303 // Adaptors for the "void*" memory blocks:
304 #define my_xsens_device (*static_cast<DeviceClass*>(m_dev_ptr))
305 #define my_xsens_devid (*static_cast<XsDeviceId*>(m_devid_ptr))
306 
307 // Include libraries in linking:
308 #if MRPT_HAS_xSENS_MT4
309 #ifdef _WIN32
310 // WINDOWS:
311 #if defined(_MSC_VER)
312 #pragma comment(lib, "SetupAPI.lib")
313 #pragma comment(lib, "WinUsb.lib")
314 #endif
315 #endif // _WIN32
316 #endif // MRPT_HAS_xSENS_MT4
317 
319 
320 using namespace mrpt::obs;
321 using namespace mrpt::hwdrivers;
322 using namespace std;
323 
324 /*-------------------------------------------------------------
325  CIMUXSens_MT4
326 -------------------------------------------------------------*/
327 CIMUXSens_MT4::CIMUXSens_MT4()
328  : m_port_bauds(0),
329  m_portname(),
330  m_sampleFreq(100),
331  m_timeStartUI(),
332  m_timeStartTT(),
333  m_sensorPose(),
334  m_dev_ptr(nullptr),
335  m_devid_ptr(nullptr)
336 {
337  m_sensorLabel = "XSensMTi_MT4";
338 
339 #if MRPT_HAS_xSENS_MT4
340  m_dev_ptr = new DeviceClass;
341  m_devid_ptr = new XsDeviceId;
342 #else
344  "MRPT has been compiled with 'BUILD_XSENS_MT4'=OFF, so this class "
345  "cannot be used.");
346 #endif
347 }
348 
349 /*-------------------------------------------------------------
350  ~CIMUXSens_MT4
351 -------------------------------------------------------------*/
353 {
354 #if MRPT_HAS_xSENS_MT4
355  my_xsens_device.close();
356  delete static_cast<DeviceClass*>(m_dev_ptr);
357  m_dev_ptr = nullptr;
358 
359  delete static_cast<XsDeviceId*>(m_devid_ptr);
360  m_devid_ptr = nullptr;
361 #endif
362 }
363 
364 /*-------------------------------------------------------------
365  doProcess
366 -------------------------------------------------------------*/
368 {
369 #if MRPT_HAS_xSENS_MT4
370  if (m_state == ssError)
371  {
372  std::this_thread::sleep_for(200ms);
373  initialize();
374  }
375 
376  if (m_state == ssError) return;
377 
379  XsMessageArray msgs;
380 
381  my_xsens_device.readDataToBuffer(data);
382  my_xsens_device.processBufferedData(data, msgs);
383  for (XsMessageArray::iterator it = msgs.begin(); it != msgs.end(); ++it)
384  {
385  // Retrieve a packet
386  XsDataPacket packet;
387  if ((*it).getMessageId() == XMID_MtData)
388  {
389  LegacyDataPacket lpacket(1, false);
390 
391  lpacket.setMessage((*it));
392  lpacket.setXbusSystem(false, false);
393  lpacket.setDeviceId(my_xsens_devid, 0);
394  lpacket.setDataFormat(
397  XOS_CalibratedMode_All /*XOS_OrientationMode_Quaternion*/,
398  0); // lint !e534
399  XsDataPacket_assignFromXsLegacyDataPacket(&packet, &lpacket, 0);
400  }
401  else if ((*it).getMessageId() == XMID_MtData2)
402  {
403  packet.setMessage((*it));
404  packet.setDeviceId(my_xsens_devid);
405  }
406 
407  // Data properly collected: extract data fields
408  // -------------------------------------------------
409  m_state = ssWorking;
410  CObservationIMU::Ptr obs = mrpt::make_aligned_shared<CObservationIMU>();
411 
412  if (packet.containsOrientation())
413  {
414  XsEuler euler = packet.orientationEuler();
415  obs->rawMeasurements[IMU_YAW] = DEG2RAD(euler.yaw());
416  obs->dataIsPresent[IMU_YAW] = true;
417  obs->rawMeasurements[IMU_PITCH] = DEG2RAD(euler.pitch());
418  obs->dataIsPresent[IMU_PITCH] = true;
419  obs->rawMeasurements[IMU_ROLL] = DEG2RAD(euler.roll());
420  obs->dataIsPresent[IMU_ROLL] = true;
421 
422  XsQuaternion quat = packet.orientationQuaternion();
423  obs->rawMeasurements[IMU_ORI_QUAT_X] = quat.x();
424  obs->dataIsPresent[IMU_ORI_QUAT_X] = true;
425  obs->rawMeasurements[IMU_ORI_QUAT_Y] = quat.y();
426  obs->dataIsPresent[IMU_ORI_QUAT_Y] = true;
427  obs->rawMeasurements[IMU_ORI_QUAT_Z] = quat.z();
428  obs->dataIsPresent[IMU_ORI_QUAT_Z] = true;
429  obs->rawMeasurements[IMU_ORI_QUAT_W] = quat.w();
430  obs->dataIsPresent[IMU_ORI_QUAT_W] = true;
431  }
432 
433  if (packet.containsCalibratedAcceleration())
434  {
435  XsVector acc_data = packet.calibratedAcceleration();
436  obs->rawMeasurements[IMU_X_ACC] = acc_data[0];
437  obs->dataIsPresent[IMU_X_ACC] = true;
438  obs->rawMeasurements[IMU_Y_ACC] = acc_data[1];
439  obs->dataIsPresent[IMU_Y_ACC] = true;
440  obs->rawMeasurements[IMU_Z_ACC] = acc_data[2];
441  obs->dataIsPresent[IMU_Z_ACC] = true;
442  }
443 
444  if (packet.containsCalibratedGyroscopeData())
445  {
446  XsVector gyr_data = packet.calibratedGyroscopeData();
447  obs->rawMeasurements[IMU_YAW_VEL] = gyr_data[2];
448  obs->dataIsPresent[IMU_YAW_VEL] = true;
449  obs->rawMeasurements[IMU_PITCH_VEL] = gyr_data[1];
450  obs->dataIsPresent[IMU_PITCH_VEL] = true;
451  obs->rawMeasurements[IMU_ROLL_VEL] = gyr_data[0];
452  obs->dataIsPresent[IMU_ROLL_VEL] = true;
453  }
454 
455  if (packet.containsCalibratedMagneticField())
456  {
457  XsVector mag_data = packet.calibratedMagneticField();
458  obs->rawMeasurements[IMU_MAG_X] = mag_data[0];
459  obs->dataIsPresent[IMU_MAG_X] = true;
460  obs->rawMeasurements[IMU_MAG_Y] = mag_data[1];
461  obs->dataIsPresent[IMU_MAG_Y] = true;
462  obs->rawMeasurements[IMU_MAG_Z] = mag_data[2];
463  obs->dataIsPresent[IMU_MAG_Z] = true;
464  }
465 
466  if (packet.containsVelocity())
467  {
468  XsVector vel_data = packet.velocity();
469  obs->rawMeasurements[IMU_X_VEL] = vel_data[0];
470  obs->dataIsPresent[IMU_X_VEL] = true;
471  obs->rawMeasurements[IMU_Y_VEL] = vel_data[1];
472  obs->dataIsPresent[IMU_Y_VEL] = true;
473  obs->rawMeasurements[IMU_Z_VEL] = vel_data[2];
474  obs->dataIsPresent[IMU_Z_VEL] = true;
475  }
476 
477  if (packet.containsTemperature())
478  {
479  obs->rawMeasurements[IMU_TEMPERATURE] = packet.temperature();
480  obs->dataIsPresent[IMU_TEMPERATURE] = true;
481  }
482 
483  if (packet.containsAltitude())
484  {
485  obs->rawMeasurements[IMU_ALTITUDE] = packet.altitude();
486  obs->dataIsPresent[IMU_ALTITUDE] = true;
487  }
488 
489  // TimeStamp
490  if (packet.containsSampleTime64())
491  {
492  const uint64_t nowUI = packet.sampleTime64();
493 
494  uint64_t AtUI = 0;
495  if (m_timeStartUI == 0)
496  {
497  m_timeStartUI = nowUI;
499  }
500  else
501  AtUI = nowUI - m_timeStartUI; // ms
502 
503  obs->timestamp = m_timeStartTT + std::chrono::milliseconds(AtUI);
504  }
505  else if (packet.containsUtcTime())
506  {
507  XsUtcTime utc = packet.utcTime();
508 
510 
511  parts.day_of_week = 0;
512  parts.daylight_saving = 0;
513  parts.year = utc.m_year;
514  parts.month = utc.m_month;
515  parts.day = utc.m_day;
516  parts.hour = utc.m_hour;
517  parts.minute = utc.m_minute;
518  parts.second = utc.m_second + (utc.m_nano * 1000000000.0);
519 
520  obs->timestamp = mrpt::system::buildTimestampFromParts(parts);
521  }
522  else
523  obs->timestamp = mrpt::system::now();
524 
525  obs->sensorPose = m_sensorPose;
526  obs->sensorLabel = m_sensorLabel;
527 
528  appendObservation(obs);
529 
530  if (packet.containsLatitudeLongitude())
531  {
532  XsVector lla_data = packet.latitudeLongitude();
533 
534  CObservationGPS::Ptr obsGPS =
538  rGPS.latitude_degrees = lla_data[0];
539  rGPS.longitude_degrees = lla_data[1];
540 
541  if (packet.containsStatus() && packet.status() & XSF_GpsValid)
542  rGPS.validity_char = 'A';
543  else
544  rGPS.validity_char = 'V';
545 
546  if (packet.containsUtcTime())
547  {
548  XsUtcTime utc = packet.utcTime();
549  rGPS.UTCTime.hour = utc.m_hour;
550  rGPS.UTCTime.minute = utc.m_minute;
551  rGPS.UTCTime.sec = utc.m_second + (utc.m_nano * 1000000.0);
552  }
553  else
554  {
555  rGPS.UTCTime.hour =
556  ((obs->timestamp.time_since_epoch().count() /
557  (60 * 60 * ((uint64_t)1000000 / 100))) %
558  24);
559  rGPS.UTCTime.minute =
560  ((obs->timestamp.time_since_epoch().count() /
561  (60 * ((uint64_t)1000000 / 100))) %
562  60);
563  rGPS.UTCTime.sec = fmod(
564  obs->timestamp.time_since_epoch().count() /
565  (1000000.0 / 100),
566  60);
567  }
568 
569  if (packet.containsVelocity())
570  {
571  XsVector vel_data = packet.velocity();
572 
573  rGPS.speed_knots =
574  sqrt(vel_data[0] * vel_data[0] + vel_data[1] * vel_data[1]);
575  rGPS.direction_degrees = 0; // Could be worked out from
576  // velocity and magnatic field
577  // perhaps.
578  }
579  else
580  rGPS.speed_knots = rGPS.direction_degrees = 0;
581 
582  obsGPS->setMsg(rGPSs);
583  obsGPS->timestamp = obs->timestamp;
584  obsGPS->originalReceivedTimestamp = obs->timestamp;
585  obsGPS->has_satellite_timestamp = false;
586  obsGPS->sensorPose = m_sensorPose;
587  obsGPS->sensorLabel = m_sensorLabel;
588 
589  appendObservation(obsGPS);
590  }
591  }
592  msgs.clear();
593 #else
595  "MRPT has been compiled with 'BUILD_XSENS_MT4'=OFF, so this class "
596  "cannot be used.");
597 #endif
598 }
599 
600 /*-------------------------------------------------------------
601  initialize
602 -------------------------------------------------------------*/
604 {
605 #if MRPT_HAS_xSENS_MT4
607 
608  try
609  {
610  // Try to open a specified device, or scan the bus?
611  XsPortInfoArray portInfoArray;
612 
613  if (m_portname.empty())
614  {
615  if (m_verbose)
616  cout << "[CIMUXSens_MT4] Scanning for USB devices...\n";
617  xsEnumerateUsbDevices(portInfoArray);
618 
619  if (portInfoArray.empty())
621  "CIMUXSens_MT4: No 'portname' was specified and no XSens "
622  "device was found after scanning the system!")
623 
624  if (m_verbose)
625  cout << "[CIMUXSens_MT4] Found " << portInfoArray.size()
626  << " devices. Opening the first one.\n";
627  }
628  else
629  {
630  XsPortInfo portInfo(
631  m_portname, XsBaud::numericToRate(m_port_bauds));
632  if (m_verbose)
633  cout << "[CIMUXSens_MT4] Using user-supplied portname '"
634  << m_portname << "' at " << m_port_bauds << " baudrate.\n";
635  portInfoArray.push_back(portInfo);
636  }
637 
638  // Use the first detected device
639  XsPortInfo mtPort = portInfoArray.at(0);
640 
641  // Open the port with the detected device
642  cout << "[CIMUXSens_MT4] Opening port "
643  << mtPort.portName().toStdString() << std::endl;
644 
645  if (!my_xsens_device.openPort(mtPort))
646  throw std::runtime_error("Could not open port. Aborting.");
647 
648  // Put the device in configuration mode
649  if (m_verbose)
650  cout << "[CIMUXSens_MT4] Putting device into configuration "
651  "mode...\n";
652  if (!my_xsens_device.gotoConfig()) // Put the device into configuration
653  // mode before configuring the
654  // device
655  throw std::runtime_error(
656  "Could not put device into configuration mode. Aborting.");
657 
658  // Request the device Id to check the device type
659  mtPort.setDeviceId(my_xsens_device.getDeviceId());
660 
661  my_xsens_devid = mtPort.deviceId();
662 
663  // Check if we have an MTi / MTx / MTmk4 device
664  if (!mtPort.deviceId().isMtix() && !mtPort.deviceId().isMtMk4())
665  {
666  throw std::runtime_error(
667  "No MTi / MTx / MTmk4 device found. Aborting.");
668  }
669  cout << "[CIMUXSens_MT4] Found a device with id: "
670  << mtPort.deviceId().toString().toStdString()
671  << " @ port: " << mtPort.portName().toStdString()
672  << ", baudrate: " << mtPort.baudrate() << std::endl;
673 
674  // Print information about detected MTi / MTx / MTmk4 device
675  if (m_verbose)
676  cout << "[CIMUXSens_MT4] Device: "
677  << my_xsens_device.getProductCode().toStdString() << " opened."
678  << std::endl;
679 
680  // Configure the device. Note the differences between MTix and MTmk4
681  if (m_verbose)
682  cout << "[CIMUXSens_MT4] Configuring the device..." << std::endl;
683  if (mtPort.deviceId().isMtix())
684  {
685  XsOutputMode outputMode =
686  XOM_Orientation; // output orientation data
687  XsOutputSettings outputSettings =
689  XOS_CalibratedMode_All; // XOS_OrientationMode_Quaternion; //
690  // output orientation data as
691  // quaternion
692 
693  // set the device configuration
694  if (!my_xsens_device.setDeviceMode(outputMode, outputSettings))
695  throw std::runtime_error(
696  "Could not configure MT device. Aborting.");
697  }
698  else if (mtPort.deviceId().isMtMk4())
699  {
700  XsOutputConfigurationArray configArray;
701  configArray.push_back(
703  configArray.push_back(
705  configArray.push_back(
707  configArray.push_back(
709  configArray.push_back(
711  configArray.push_back(
713  configArray.push_back(
715  configArray.push_back(
717  configArray.push_back(
719 
720  configArray.push_back(
722  configArray.push_back(
724  configArray.push_back(
726  configArray.push_back(
728 
729  if (!my_xsens_device.setOutputConfiguration(configArray))
730  throw std::runtime_error(
731  "Could not configure MTmk4 device. Aborting.");
732  }
733  else
734  {
735  throw std::runtime_error(
736  "Unknown device while configuring. Aborting.");
737  }
738 
739  // Put the device in measurement mode
740  if (m_verbose)
741  cout << "[CIMUXSens_MT4] Putting device into measurement mode..."
742  << std::endl;
743  if (!my_xsens_device.gotoMeasurement())
744  throw std::runtime_error(
745  "Could not put device into measurement mode. Aborting.");
746 
747  m_state = ssWorking;
748  }
749  catch (std::exception&)
750  {
751  m_state = ssError;
752  std::cerr << "Error Could not initialize the device" << std::endl;
753  throw;
754  }
755 
756 #else
758  "MRPT has been compiled with 'BUILD_XSENS_MT4'=OFF, so this class "
759  "cannot be used.");
760 #endif
761 }
762 
763 /*-------------------------------------------------------------
764  loadConfig_sensorSpecific
765 -------------------------------------------------------------*/
767  const mrpt::config::CConfigFileBase& configSource,
768  const std::string& iniSection)
769 {
771  configSource.read_float(iniSection, "pose_x", 0, false),
772  configSource.read_float(iniSection, "pose_y", 0, false),
773  configSource.read_float(iniSection, "pose_z", 0, false),
774  DEG2RAD(configSource.read_float(iniSection, "pose_yaw", 0, false)),
775  DEG2RAD(configSource.read_float(iniSection, "pose_pitch", 0, false)),
776  DEG2RAD(configSource.read_float(iniSection, "pose_roll", 0, false)));
777 
778  m_sampleFreq =
779  configSource.read_int(iniSection, "sampleFreq", m_sampleFreq, false);
780 
781  m_port_bauds =
782  configSource.read_int(iniSection, "baudRate", m_port_bauds, false);
783 
784 #ifdef _WIN32
785  m_portname =
786  configSource.read_string(iniSection, "portname_WIN", m_portname, false);
787 #else
788  m_portname =
789  configSource.read_string(iniSection, "portname_LIN", m_portname, false);
790 #endif
791 }
XsOutputMode
Bit values for legacy output mode.
Definition: xsoutputmode.h:16
Operation was performed successfully.
Definition: xsens_std.h:34
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection)
See the class documentation at the top for expected parameters.
mrpt::system::TTimeStamp m_timeStartTT
Definition: CIMUXSens_MT4.h:67
Scalar * iterator
Definition: eigen_plugins.h:26
content_t fields
Message content, accesible by individual fields.
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
void XsDataPacket_assignFromXsLegacyDataPacket(struct XsDataPacket *thisPtr, struct LegacyDataPacket const *pack, int index)
unsigned __int16 uint16_t
Definition: rptypes.h:44
void doProcess()
This method will be invoked at a minimum rate of "process_rate" (Hz)
void appendObservation(const mrpt::serialization::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
virtual ~CIMUXSens_MT4()
Destructor.
void setMessage(const XsMessage &message)
Set the source message to msg.
mrpt::poses::CPose3D m_sensorPose
Definition: CIMUXSens_MT4.h:69
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
GLint location
Definition: glext.h:4086
std::string m_sensorLabel
See CGenericSensor.
double DEG2RAD(const double x)
Degrees to radians.
orientation pitch absolute value (global/navigation frame) (rad)
A stream interface.
mrpt::system::TTimeStamp buildTimestampFromParts(const mrpt::system::TTimeParts &p)
Builds a timestamp from the parts (Parts are in UTC)
Definition: datetime.cpp:85
struct XsByteArray XsByteArray
Definition: xsbytearray.h:25
bool setDataFormat(const XsDataFormat &format, int32_t index=0)
Sets the data format of the device with the given index to format.
uint8_t m_day
The day of the month (if date is valid)
Definition: xsutctime.h:24
uint8_t day_of_week
Seconds (0.0000-59.9999)
Definition: datetime.h:57
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:87
Contains classes for various device interfaces.
uint16_t m_year
The year (if date is valid)
Definition: xsutctime.h:20
temperature (degrees Celsius)
float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound=false) const
x magnetic field value (local/vehicle frame) (gauss)
size_t XsSize
XsSize must be unsigned number!
Definition: xstypedefs.h:19
y-axis acceleration (local/vehicle frame) (m/sec2)
STL namespace.
Orientation Quaternion X (global/navigation frame)
struct XsOutputConfiguration XsOutputConfiguration
z-axis acceleration (local/vehicle frame) (m/sec2)
x-axis velocity (global/navigation frame) (m/sec)
int8_t validity_char
This will be: &#39;A&#39;=OK or &#39;V&#39;=void.
uint8_t m_minute
The minute (if time is valid)
Definition: xsutctime.h:28
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)
std::string m_portname
The USB or COM port name (if blank -> autodetect)
Definition: CIMUXSens_MT4.h:63
int m_port_bauds
Baudrate, only for COM ports.
Definition: CIMUXSens_MT4.h:61
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
uint32_t m_nano
Nanosecond part of the time.
Definition: xsutctime.h:18
struct XsMessageArray XsMessageArray
pitch angular velocity (local/vehicle frame) (rad/sec)
int daylight_saving
Day of week (1:Sunday, 7:Saturday)
Definition: datetime.h:58
bool xsEnumerateUsbDevices(XsPortInfoList &ports)
Enumerate Xsens USB devices.
This class allows loading and storing values and vectors of different types from a configuration text...
XsResultValue
Xsens result values.
Definition: xsresultvalue.h:27
Stores the location of a message in a buffer using a start position and a size.
Structure for storing a single message.
Definition: xsmessage.h:198
uint8_t m_hour
The hour (if time is valid)
Definition: xsutctime.h:26
The parts of a date/time (it&#39;s like the standard &#39;tm&#39; but with fractions of seconds).
Definition: datetime.h:49
virtual MessageLocation findMessage(XsMessage &rcv, const XsByteArray &raw) const
Find the first message in the raw byte stream.
void initialize()
Turns on the xSens device and configure it for getting orientation data.
uint8_t day
Month (1-12)
Definition: datetime.h:53
void setDeviceId(XsDeviceId deviceId, int32_t index)
Sets the device ID of the device with the given index to deviceid.
This namespace contains representation of robot actions and observations.
struct XsDeviceId XsDeviceId
Definition: xsdeviceid.h:235
Orientation Quaternion Y (global/navigation frame)
Orientation Quaternion Z (global/navigation frame)
static int composeMessage(XsByteArray &raw, const XsMessage &msg)
Compose a message for transmission.
z magnetic field value (local/vehicle frame) (gauss)
GLsizei const GLchar ** string
Definition: glext.h:4101
Orientation Quaternion W (global/navigation frame)
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
#define my_xsens_devid
XsXbusMessageId
Xsens Xbus Message Identifiers.
double second
Minute (0-59)
Definition: datetime.h:56
y magnetic field value (local/vehicle frame) (gauss)
unsigned __int64 uint64_t
Definition: rptypes.h:50
Message protocol handling class.
Contains an MTData XsMessage and supports functions for extracting contained data.
void setXbusSystem(bool xbus, bool convert=false)
Sets the xbus flag.
XsOutputSettings
Bit values for output settings.
The low-level serial communication class.
int m_size
The size of the message, when less than 0 it indicates the expected message size. ...
uint8_t minute
Hour (0-23)
Definition: datetime.h:55
A structure for storing UTC Time values.
Definition: xsutctime.h:15
double direction_degrees
Measured speed direction (in degrees)
struct XsPortInfoArray XsPortInfoArray
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
Definition: CPose3D.cpp:239
uint8_t month
The year.
Definition: datetime.h:52
Contains data received from a device or read from a file.
Definition: xsdatapacket.h:302
A class for interfacing XSens 4th generation Inertial Measuring Units (IMUs): MTi 10-series...
Definition: CIMUXSens_MT4.h:56
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
uint8_t hour
Day (1-31)
Definition: datetime.h:54
uint8_t m_month
The month (if date is valid)
Definition: xsutctime.h:22
orientation yaw absolute value (global/navigation frame) (rad)
#define my_xsens_device
y-axis velocity (global/navigation frame) (m/sec)
GLuint res
Definition: glext.h:7268
orientation roll absolute value (global/navigation frame) (rad)
struct XsString XsString
Definition: xsstring.h:34
yaw angular velocity (local/vehicle frame) (rad/sec)
This class stores messages from GNSS or GNSS+IMU devices, from consumer-grade inexpensive GPS receive...
roll angular velocity (local/vehicle frame) (rad/sec)
unsigned __int32 uint32_t
Definition: rptypes.h:47
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3546
x-axis acceleration (local/vehicle frame) (m/sec2)
z-axis velocity (global/navigation frame) (m/sec)
uint8_t m_second
The second (if time is valid)
Definition: xsutctime.h:30
struct XsOutputConfigurationArray XsOutputConfigurationArray
An IoInterface for dealing specifically with Xsens USB devices.
Definition: usbinterface.h:35
altitude from an altimeter (meters)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020