19 #if MRPT_HAS_xSENS_MT4 55 DeviceClass() =
default;
58 if (m_streamInterface)
60 delete m_streamInterface;
61 m_streamInterface =
nullptr;
76 if (m_streamInterface->open(portInfo) !=
XRV_OK)
return false;
84 if (m_streamInterface) m_streamInterface->close();
99 const int maxSz = 8192;
101 if (raw.size())
return XRV_OK;
120 if (rawIn.size()) m_dataBuffer.append(rawIn);
128 m_dataBuffer.data() + popped, m_dataBuffer.size() - popped);
136 messages.push_back(message);
140 if (popped) m_dataBuffer.pop_front(popped);
158 bool foundAck =
false;
161 readDataToBuffer(
data);
162 processBufferedData(
data, msgs);
163 for (XsMessageArray::iterator it = msgs.begin(); it != msgs.end();
165 if ((*it).getMessageId() == xmid)
183 return (m_streamInterface->writeData(raw) ==
XRV_OK);
200 bool gotoMeasurement()
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(
" ");
223 result.begin() + thingy, result.end());
241 return rcv.getDataLong();
258 sndOM.setDataShort((
uint16_t)outputMode);
264 snd.setDataLong((
uint32_t)outputSettings);
279 if (config.size() == 0)
282 snd.setDataShort(0, 2);
288 snd.setDataShort((
uint16_t)config[i].m_dataIdentifier, i * 4);
289 snd.setDataShort(config[i].m_frequency, i * 4 + 2);
304 #define my_xsens_device (*static_cast<DeviceClass*>(m_dev_ptr)) 305 #define my_xsens_devid (*static_cast<XsDeviceId*>(m_devid_ptr)) 308 #if MRPT_HAS_xSENS_MT4 311 #if defined(_MSC_VER) 312 #pragma comment(lib, "SetupAPI.lib") 313 #pragma comment(lib, "WinUsb.lib") 316 #endif // MRPT_HAS_xSENS_MT4 327 CIMUXSens_MT4::CIMUXSens_MT4() : m_portname(), m_timeStartTT(), m_sensorPose()
332 #if MRPT_HAS_xSENS_MT4 337 "MRPT has been compiled with 'BUILD_XSENS_MT4'=OFF, so this class " 347 #if MRPT_HAS_xSENS_MT4 349 delete static_cast<DeviceClass*
>(
m_dev_ptr);
362 #if MRPT_HAS_xSENS_MT4 365 std::this_thread::sleep_for(200ms);
376 for (XsMessageArray::iterator it = msgs.begin(); it != msgs.end(); ++it)
396 packet.setMessage((*it));
405 if (packet.containsOrientation())
407 XsEuler euler = packet.orientationEuler();
409 obs->dataIsPresent[
IMU_YAW] =
true;
413 obs->dataIsPresent[
IMU_ROLL] =
true;
426 if (packet.containsCalibratedAcceleration())
428 XsVector acc_data = packet.calibratedAcceleration();
429 obs->rawMeasurements[
IMU_X_ACC] = acc_data[0];
431 obs->rawMeasurements[
IMU_Y_ACC] = acc_data[1];
433 obs->rawMeasurements[
IMU_Z_ACC] = acc_data[2];
437 if (packet.containsCalibratedGyroscopeData())
439 XsVector gyr_data = packet.calibratedGyroscopeData();
448 if (packet.containsCalibratedMagneticField())
450 XsVector mag_data = packet.calibratedMagneticField();
451 obs->rawMeasurements[
IMU_MAG_X] = mag_data[0];
453 obs->rawMeasurements[
IMU_MAG_Y] = mag_data[1];
455 obs->rawMeasurements[
IMU_MAG_Z] = mag_data[2];
459 if (packet.containsVelocity())
461 XsVector vel_data = packet.velocity();
462 obs->rawMeasurements[
IMU_X_VEL] = vel_data[0];
464 obs->rawMeasurements[
IMU_Y_VEL] = vel_data[1];
466 obs->rawMeasurements[
IMU_Z_VEL] = vel_data[2];
470 if (packet.containsTemperature())
476 if (packet.containsAltitude())
483 if (packet.containsSampleTime64())
485 const uint64_t nowUI = packet.sampleTime64();
496 obs->timestamp =
m_timeStartTT + std::chrono::milliseconds(AtUI);
498 else if (packet.containsUtcTime())
523 if (packet.containsLatitudeLongitude())
525 XsVector lla_data = packet.latitudeLongitude();
533 if (packet.containsStatus() && packet.status() &
XSF_GpsValid)
538 if (packet.containsUtcTime())
548 ((obs->timestamp.time_since_epoch().count() /
549 (60 * 60 * ((
uint64_t)1000000 / 100))) %
552 ((obs->timestamp.time_since_epoch().count() /
556 obs->timestamp.time_since_epoch().count() /
561 if (packet.containsVelocity())
563 XsVector vel_data = packet.velocity();
566 sqrt(vel_data[0] * vel_data[0] + vel_data[1] * vel_data[1]);
574 obsGPS->setMsg(rGPSs);
575 obsGPS->timestamp = obs->timestamp;
576 obsGPS->originalReceivedTimestamp = obs->timestamp;
577 obsGPS->has_satellite_timestamp =
false;
587 "MRPT has been compiled with 'BUILD_XSENS_MT4'=OFF, so this class " 597 #if MRPT_HAS_xSENS_MT4 608 cout <<
"[CIMUXSens_MT4] Scanning for USB devices...\n";
611 if (portInfoArray.empty())
613 "CIMUXSens_MT4: No 'portname' was specified and no XSens " 614 "device was found after scanning the system!");
617 cout <<
"[CIMUXSens_MT4] Found " << portInfoArray.size()
618 <<
" devices. Opening the first one.\n";
625 cout <<
"[CIMUXSens_MT4] Using user-supplied portname '" 627 portInfoArray.push_back(portInfo);
634 cout <<
"[CIMUXSens_MT4] Opening port " 635 << mtPort.portName().toStdString() << std::endl;
638 throw std::runtime_error(
"Could not open port. Aborting.");
642 cout <<
"[CIMUXSens_MT4] Putting device into configuration " 647 throw std::runtime_error(
648 "Could not put device into configuration mode. Aborting.");
656 if (!mtPort.deviceId().isMtix() && !mtPort.deviceId().isMtMk4())
658 throw std::runtime_error(
659 "No MTi / MTx / MTmk4 device found. Aborting.");
661 cout <<
"[CIMUXSens_MT4] Found a device with id: " 662 << mtPort.deviceId().toString().toStdString()
663 <<
" @ port: " << mtPort.portName().toStdString()
664 <<
", baudrate: " << mtPort.baudrate() << std::endl;
668 cout <<
"[CIMUXSens_MT4] Device: " 674 cout <<
"[CIMUXSens_MT4] Configuring the device..." << std::endl;
675 if (mtPort.deviceId().isMtix())
687 throw std::runtime_error(
688 "Could not configure MT device. Aborting.");
690 else if (mtPort.deviceId().isMtMk4())
693 configArray.push_back(
695 configArray.push_back(
697 configArray.push_back(
699 configArray.push_back(
701 configArray.push_back(
703 configArray.push_back(
705 configArray.push_back(
707 configArray.push_back(
709 configArray.push_back(
712 configArray.push_back(
714 configArray.push_back(
716 configArray.push_back(
718 configArray.push_back(
722 throw std::runtime_error(
723 "Could not configure MTmk4 device. Aborting.");
727 throw std::runtime_error(
728 "Unknown device while configuring. Aborting.");
733 cout <<
"[CIMUXSens_MT4] Putting device into measurement mode..." 736 throw std::runtime_error(
737 "Could not put device into measurement mode. Aborting.");
741 catch (std::exception&)
744 std::cerr <<
"Error Could not initialize the device" << std::endl;
750 "MRPT has been compiled with 'BUILD_XSENS_MT4'=OFF, so this class " 763 configSource.
read_float(iniSection,
"pose_x", 0,
false),
764 configSource.
read_float(iniSection,
"pose_y", 0,
false),
765 configSource.
read_float(iniSection,
"pose_z", 0,
false),
XsOutputMode
Bit values for legacy output mode.
void initialize() override
Turns on the xSens device and configure it for getting orientation data.
Operation was performed successfully.
mrpt::system::TTimeStamp m_timeStartTT
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
void appendObservation(const mrpt::serialization::CSerializable::Ptr &obj)
Like appendObservations() but for just one observation.
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
void setMessage(const XsMessage &message)
Set the source message to msg.
mrpt::poses::CPose3D m_sensorPose
#define THROW_EXCEPTION(msg)
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz)
std::string m_sensorLabel
See CGenericSensor.
double DEG2RAD(const double x)
Degrees to radians.
orientation pitch absolute value (global/navigation frame) (rad)
mrpt::system::TTimeStamp buildTimestampFromParts(const mrpt::system::TTimeParts &p)
Builds a timestamp from the parts (Parts are in UTC)
struct XsByteArray XsByteArray
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)
uint8_t day_of_week
Seconds (0.0000-59.9999)
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Contains classes for various device interfaces.
uint16_t m_year
The year (if date is valid)
temperature (degrees Celsius)
float read_float(const std::string §ion, 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!
y-axis acceleration (local/vehicle frame) (m/sec2)
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: 'A'=OK or 'V'=void.
uint8_t m_minute
The minute (if time is valid)
UTC_time UTCTime
The GPS sensor measured timestamp (in UTC time)
std::string m_portname
The USB or COM port name (if blank -> autodetect)
int m_port_bauds
Baudrate, only for COM ports.
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
uint32_t m_nano
Nanosecond part of the time.
struct XsMessageArray XsMessageArray
pitch angular velocity (local/vehicle frame) (rad/sec)
int daylight_saving
Day of week (1:Sunday, 7:Saturday)
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.
Stores the location of a message in a buffer using a start position and a size.
Structure for storing a single message.
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection) override
See the class documentation at the top for expected parameters.
uint8_t m_hour
The hour (if time is valid)
The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).
MessageLocation findMessage(XsMessage &rcv, const XsByteArray &raw) const override
Find the first message in the raw byte stream.
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
Orientation Quaternion Y (global/navigation frame)
~CIMUXSens_MT4() override
Destructor.
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
Orientation Quaternion W (global/navigation frame)
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
XsXbusMessageId
Xsens Xbus Message Identifiers.
double second
Minute (0-59)
y magnetic field value (local/vehicle frame) (gauss)
unsigned __int64 uint64_t
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.
double speed_knots
Measured speed (in knots)
int m_size
The size of the message, when less than 0 it indicates the expected message size. ...
uint8_t minute
Hour (0-23)
A structure for storing UTC Time values.
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...
Contains data received from a device or read from a file.
A class for interfacing XSens 4th generation Inertial Measuring Units (IMUs): MTi 10-series...
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
uint8_t m_month
The month (if date is valid)
orientation yaw absolute value (global/navigation frame) (rad)
y-axis velocity (global/navigation frame) (m/sec)
orientation roll absolute value (global/navigation frame) (rad)
yaw angular velocity (local/vehicle frame) (rad/sec)
roll angular velocity (local/vehicle frame) (rad/sec)
unsigned __int32 uint32_t
GLsizei GLsizei GLenum GLenum const GLvoid * data
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)
struct XsOutputConfigurationArray XsOutputConfigurationArray
An IoInterface for dealing specifically with Xsens USB devices.
altitude from an altimeter (meters)