29 #define XDA_STATIC_LIB 31 #include <xscontroller/xscallback.h> 32 #include <xscontroller/xscontrol_def.h> 33 #include <xscontroller/xsdevice_def.h> 34 #include <xscontroller/xsscanner.h> 35 #include <xstypes/xsdatapacket.h> 36 #include <xstypes/xsoutputconfigurationarray.h> 37 #include <xstypes/xsportinfo.h> 38 #include <xstypes/xsstatusflag.h> 41 Journaller* gJournal = 0;
45 class MyXSensCallback :
public XsCallback
55 void onLiveDataAvailable(XsDevice*,
const XsDataPacket* ptrpacket)
override 60 if (!ptrpacket)
return;
61 const XsDataPacket& packet = *ptrpacket;
68 if (packet.containsOrientation())
70 XsEuler euler = packet.orientationEuler();
72 obs->dataIsPresent[
IMU_YAW] =
true;
78 XsQuaternion quat = packet.orientationQuaternion();
89 if (packet.containsCalibratedAcceleration())
91 XsVector acc_data = packet.calibratedAcceleration();
92 obs->rawMeasurements[
IMU_X_ACC] = acc_data[0];
94 obs->rawMeasurements[
IMU_Y_ACC] = acc_data[1];
96 obs->rawMeasurements[
IMU_Z_ACC] = acc_data[2];
100 if (packet.containsCalibratedGyroscopeData())
102 XsVector gyr_data = packet.calibratedGyroscopeData();
111 if (packet.containsCalibratedMagneticField())
113 XsVector mag_data = packet.calibratedMagneticField();
114 obs->rawMeasurements[
IMU_MAG_X] = mag_data[0];
116 obs->rawMeasurements[
IMU_MAG_Y] = mag_data[1];
118 obs->rawMeasurements[
IMU_MAG_Z] = mag_data[2];
122 if (packet.containsVelocity())
124 XsVector vel_data = packet.velocity();
125 obs->rawMeasurements[
IMU_X_VEL] = vel_data[0];
127 obs->rawMeasurements[
IMU_Y_VEL] = vel_data[1];
129 obs->rawMeasurements[
IMU_Z_VEL] = vel_data[2];
133 if (packet.containsTemperature())
139 if (packet.containsAltitude())
146 #if 0 // I can't find a generic conversion between sample time and seconds! 147 if (packet.containsSampleTime64())
149 dev->getDataPacketByIndex()
150 const uint64_t nowUI = packet.sampleTime64();
151 std::cout <<
"nowUI: " << nowUI <<
"\n";
154 if (m_timeStartUI == 0)
156 m_timeStartUI = nowUI;
160 AtUI = nowUI - m_timeStartUI;
162 obs->timestamp = m_timeStartTT + std::chrono::milliseconds(AtUI);
165 if (packet.containsUtcTime())
167 XsTimeInfo utc = packet.utcTime();
173 parts.
year = utc.m_year;
174 parts.
month = utc.m_month;
175 parts.
day = utc.m_day;
176 parts.
hour = utc.m_hour;
177 parts.
minute = utc.m_minute;
178 parts.
second = utc.m_second + (utc.m_nano * 1000000000.0);
191 if (packet.containsLatitudeLongitude())
193 XsVector lla_data = packet.latitudeLongitude();
201 if (packet.containsStatus() && packet.status() & XSF_GpsValid)
206 if (packet.containsUtcTime())
208 auto utc = packet.utcTime();
211 rGPS.
UTCTime.
sec = utc.m_second + (utc.m_nano * 1000000.0);
216 ((obs->timestamp.time_since_epoch().count() /
217 (60 * 60 * ((uint64_t)1000000 / 100))) %
220 ((obs->timestamp.time_since_epoch().count() /
221 (60 * ((uint64_t)1000000 / 100))) %
224 obs->timestamp.time_since_epoch().count() /
229 if (packet.containsVelocity())
231 XsVector vel_data = packet.velocity();
234 sqrt(vel_data[0] * vel_data[0] + vel_data[1] * vel_data[1]);
242 obsGPS->setMsg(rGPSs);
243 obsGPS->timestamp = obs->timestamp;
244 obsGPS->originalReceivedTimestamp = obs->timestamp;
245 obsGPS->has_satellite_timestamp =
false;
258 XsControl* m_xscontrol =
nullptr;
259 XsDevice* m_device =
nullptr;
262 std::make_shared<MyXSensCallback>();
273 #if defined(_MSC_VER) 274 #pragma comment(lib, "SetupAPI.lib") 275 #pragma comment(lib, "WinUsb.lib") 278 #endif // MRPT_HAS_xSENS 291 m_impl->m_xscontrol = XsControl::construct();
292 m_impl->myCallback->me =
this;
296 "MRPT has been compiled with 'BUILD_XSENS'=OFF, so this class " 305 m_impl->m_xscontrol->destruct();
312 if (
m_impl->m_device !=
nullptr)
314 m_impl->m_device->stopRecording();
315 m_impl->m_device->closeLogFile();
316 m_impl->m_device->removeCallbackHandler(
m_impl->myCallback.get());
331 std::this_thread::sleep_for(200ms);
339 "MRPT has been compiled with 'BUILD_XSENS'=OFF, so this class " 360 cout <<
"[CIMUXSens_MT4] Scanning for USB devices...\n";
362 XsPortInfoArray portInfoArray = XsScanner::scanPorts();
364 for (
const auto& portInfo : portInfoArray)
366 if (portInfo.deviceId().isMti() || portInfo.deviceId().isMtig())
375 "CIMUXSens_MT4: No 'portname' was specified and no " 376 "compatible XSens device was found in the system (%u " 377 "devices connected)",
378 portInfoArray.size());
381 cout <<
"[CIMUXSens_MT4] Found " << portInfoArray.size()
382 <<
" devices. Opening the first one.\n";
386 cout <<
"[CIMUXSens_MT4] Using user-supplied portname '" 397 if (mtPort.deviceId().toString().c_str() !=
m_deviceId)
399 "Device with ID: %s not found",
m_deviceId.c_str());
403 "[CIMUXSens_MT4] Found a device with ID: %s @ port: %s, baudrate: " 405 mtPort.deviceId().toString().toStdString().c_str(),
406 mtPort.portName().toStdString().c_str(), mtPort.baudrate());
408 if (!
m_impl->m_xscontrol->openPort(
409 mtPort.portName().toStdString(), mtPort.baudrate()))
412 m_impl->m_device =
m_impl->m_xscontrol->device(mtPort.deviceId());
416 "[CIMUXSens_MT4] Device: %s, with ID: %s opened.",
417 m_impl->m_device->productCode().toStdString().c_str(),
418 m_impl->m_device->deviceId().toString().c_str());
420 m_impl->m_device->addCallbackHandler(
m_impl->myCallback.get());
424 cout <<
"[CIMUXSens_MT4] Putting device into configuration " 427 if (!
m_impl->m_device->gotoConfig())
431 if (!
m_impl->m_device->readEmtsAndDeviceConfiguration())
437 XsOutputConfigurationArray configArray;
438 configArray.push_back(
440 configArray.push_back(
441 XsOutputConfiguration(XDI_SampleTimeFine,
m_sampleFreq));
442 configArray.push_back(
443 XsOutputConfiguration(XDI_SampleTimeCoarse,
m_sampleFreq));
444 configArray.push_back(
446 configArray.push_back(
448 configArray.push_back(
450 configArray.push_back(
452 configArray.push_back(
453 XsOutputConfiguration(XDI_MagneticField,
m_sampleFreq));
454 configArray.push_back(
457 configArray.push_back(
459 configArray.push_back(
461 configArray.push_back(
463 configArray.push_back(
464 XsOutputConfiguration(XDI_AltitudeEllipsoid,
m_sampleFreq));
466 if (!
m_impl->m_device->setOutputConfiguration(configArray))
467 throw std::runtime_error(
468 "Could not configure MTi device. Aborting.");
473 cout <<
"[CIMUXSens_MT4] Putting device into measurement mode..." 476 if (!
m_impl->m_device->gotoMeasurement())
483 "Failed to create a log file! (%s)",
487 "[CIMUXSens_MT4] Created a log file: %s",
490 if (!
m_impl->m_device->startRecording())
496 catch (std::exception&)
499 std::cerr <<
"[CIMUXSens_MT4] Error Could not initialize the device" 506 "MRPT has been compiled with 'BUILD_XSENS'=OFF, so this class " void initialize() override
Turns on the xSens device and configure it for getting orientation data.
content_t fields
Message content, accesible by individual fields.
double longitude_degrees
The measured longitude, in degrees (East:+ , West:-)
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
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 std::string format(std::string_view fmt, ARGS &&... args)
std::string m_sensorLabel
See CGenericSensor.
std::string m_deviceId
Device ID to open, or first one if empty string.
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)
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.
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)
y-axis acceleration (local/vehicle frame) (m/sec2)
Orientation Quaternion X (global/navigation frame)
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.
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
#define ASSERT_(f)
Defines an assertion mechanism.
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
pitch angular velocity (local/vehicle frame) (rad/sec)
int daylight_saving
Day of week (1:Sunday, 7:Saturday)
This class allows loading and storing values and vectors of different types from a configuration text...
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &iniSection) override
See the class documentation at the top for expected parameters.
constexpr double DEG2RAD(const double x)
Degrees to radians.
The parts of a date/time (it's like the standard 'tm' but with fractions of seconds).
This namespace contains representation of robot actions and observations.
Orientation Quaternion Y (global/navigation frame)
~CIMUXSens_MT4() override
Orientation Quaternion Z (global/navigation frame)
z magnetic field value (local/vehicle frame) (gauss)
Orientation Quaternion W (global/navigation frame)
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
double second
Minute (0-59)
y magnetic field value (local/vehicle frame) (gauss)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double speed_knots
Measured speed (in knots)
uint8_t minute
Hour (0-23)
double direction_degrees
Measured speed direction (in degrees)
mrpt::pimpl< Impl > m_impl
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...
A class for interfacing XSens 4th generation Inertial Measuring Units (IMUs): MTi 10-series...
pimpl< T > make_impl(Args &&... args)
double latitude_degrees
The measured latitude, in degrees (North:+ , South:-)
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)
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
x-axis acceleration (local/vehicle frame) (m/sec2)
z-axis velocity (global/navigation frame) (m/sec)
altitude from an altimeter (meters)
std::string m_xsensLogFile