18 m_PeriodMicroSeconds(0),
20 m_SamplesPerFusion(0),
21 m_CollectedFusionSamples(0),
23 m_IsDispatching(false),
24 m_IsInitialized(false),
25 m_pInternalThreadHandel(0),
26 m_IMUEventDispatchers(),
33 m_pXsensMTiModule(nullptr)
37 pthread_mutex_init(&m_IsActiveMutex,
nullptr);
38 pthread_mutex_init(&m_IsDispatchingMutex,
nullptr);
39 pthread_mutex_init(&m_EventDispatchersMutex,
nullptr);
40 pthread_mutex_init(&m_DeviceMutex,
nullptr);
45 FinalizeModuleDevice();
62 if (!PortName.length())
64 std::cerr <<
"[IMU Error: Cannot connect to empty port name!]\n\t[Operation result: "
65 "(PortName.length()==0)]\n[Source location: "
66 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
70 m_IsInitialized = InitializeDevice(PortName, Frequency);
72 return m_IsInitialized;
78 if (m_IsInitialized && (!m_IsActive))
80 const int Result = pthread_create(
81 &m_pInternalThreadHandel,
nullptr, CIMUDevice::ThreadLoop, (
void*)
this);
85 while (Blocking && !m_IsActive)
105 pthread_join(m_pInternalThreadHandel,
nullptr);
107 while (Blocking && m_IsDispatching)
117 if (SamplesPerFusion > 1)
119 if ((m_FusionStrategy != Strategy) || (m_SamplesPerFusion != SamplesPerFusion))
121 m_FusionStrategy = Strategy;
122 m_SamplesPerFusion = SamplesPerFusion;
123 m_CollectedFusionSamples = 0;
130 std::cerr <<
"[IMU Device error: Cannot set fusion with less than 2 samples per "
131 "fusion!]\n\t[Source location: "
132 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
146 if (pIMUEventDispatcher)
150 if (m_IMUEventDispatchers.find(pIMUEventDispatcher) == m_IMUEventDispatchers.end())
152 pIMUEventDispatcher->
SetIMU(
this);
154 std::pair<std::set<IIMUEventDispatcher*>::iterator,
bool> Result =
155 m_IMUEventDispatchers.insert(pIMUEventDispatcher);
157 return Result.second;
169 if (pIMUEventDispatcher)
172 std::set<IIMUEventDispatcher*>::iterator ppElement =
173 m_IMUEventDispatchers.find(pIMUEventDispatcher);
175 if (ppElement != m_IMUEventDispatchers.end())
177 pIMUEventDispatcher->
SetIMU(
nullptr);
178 m_IMUEventDispatchers.erase(ppElement);
190 CIMUDevice::UnregisterEventDispatchers()
192 if (m_IMUEventDispatchers.size())
196 for (
auto m_IMUEventDispatcher : m_IMUEventDispatchers)
198 m_IMUEventDispatcher->SetIMU(
nullptr);
201 m_IMUEventDispatchers.clear();
206#ifdef _IMU_USE_XSENS_DEVICE_
209 CIMUDevice::InitializeXsensDevice(
const std::string& PortName,
210 const SamplingFrequency Frequency)
217 m_pXsensMTiModule =
new Xsens::CXsensMTiModule();
219 if (m_pXsensMTiModule->openPort(PortName.c_str()) !=
MTRV_OK)
221 std::cerr <<
"[IMU Device error: Cannot open port!]\n\t[Operation result: "
222 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
223 <<
":" << __LINE__ <<
"]" << std::endl;
224 DestroyXsensModuleDevice();
231 <<
"[IMU Device error: Cannot set configuration state!]\n\t[Operation result: "
232 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
233 <<
":" << __LINE__ <<
"]" << std::endl;
234 DestroyXsensModuleDevice();
242 std::cerr <<
"[IMU Device error: Cannot set output mode!]\n\t[Operation result: "
243 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
244 <<
":" << __LINE__ <<
"]" << std::endl;
245 DestroyXsensModuleDevice();
251 std::cerr <<
"[IMU Device error: Cannot set sampling period!]\n\t[Operation result: "
252 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
253 <<
":" << __LINE__ <<
"]" << std::endl;
254 DestroyXsensModuleDevice();
258 unsigned long DeviceId;
262 std::cerr <<
"[IMU Device error: Cannot get device ID!]\n\t[Operation result: "
263 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
264 <<
":" << __LINE__ <<
"]" << std::endl;
265 DestroyXsensModuleDevice();
269 m_DeviceId = DeviceId;
274 <<
"[IMU Device error: Cannot enter measurement state!]\n\t[Operation result: "
275 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
276 <<
":" << __LINE__ <<
"]" << std::endl;
277 DestroyXsensModuleDevice();
285 CIMUDevice::FinalizeXsensModuleDevice()
289 while (m_IsActive || m_IsDispatching)
295 DestroyXsensModuleDevice();
301 CIMUDevice::DestroyXsensModuleDevice()
303 if (m_pXsensMTiModule)
305 if (m_pXsensMTiModule->isPortOpen())
307 m_pXsensMTiModule->close();
310 delete m_pXsensMTiModule;
311 m_pXsensMTiModule =
nullptr;
324#ifdef _IMU_USE_XSENS_DEVICE_
326 if (m_pXsensMTiModule->readDataMessage(m_XsensMTiFrame.m_Data,
327 m_XsensMTiFrame.m_DataLength) ==
MTRV_OK)
328 if (m_pXsensMTiModule->getValue(
330 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration,
331 m_XsensMTiFrame.m_Data) ==
MTRV_OK)
332 if (m_pXsensMTiModule->getValue(
334 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_GyroscopeRotation,
335 m_XsensMTiFrame.m_Data) ==
MTRV_OK)
336 if (m_pXsensMTiModule->getValue(
338 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_MagneticRotation,
339 m_XsensMTiFrame.m_Data) ==
MTRV_OK)
340 if (m_pXsensMTiModule->getValue(
342 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_QuaternionRotation,
343 m_XsensMTiFrame.m_Data) ==
MTRV_OK)
344 if (m_pXsensMTiModule->getValue(
346 m_XsensMTiFrame.m_IMUState.m_ControlData.m_CurrentSampleCount,
347 m_XsensMTiFrame.m_Data) ==
MTRV_OK)
349 if (m_XsensMTiFrame.m_IMUState.m_ControlData
350 .m_PreviousSampleCount != -1)
352 m_XsensMTiFrame.m_IMUState.m_ControlData.m_IsConsecutive =
353 ((m_XsensMTiFrame.m_IMUState.m_ControlData
354 .m_PreviousSampleCount +
356 65536) == m_XsensMTiFrame.m_IMUState.m_ControlData
357 .m_CurrentSampleCount;
360 m_XsensMTiFrame.m_IMUState.m_ControlData.m_PreviousSampleCount =
361 m_XsensMTiFrame.m_IMUState.m_ControlData.m_CurrentSampleCount;
362 m_XsensMTiFrame.m_IMUState.m_ControlData.m_MessageCounter++;
363 gettimeofday(&m_XsensMTiFrame.m_IMUState.m_ControlData.m_TimeStamp,
365 m_LastFrameTimeStamp =
366 m_XsensMTiFrame.m_IMUState.m_ControlData.m_TimeStamp;
368 m_XsensMTiFrame.m_IMUState.m_PhysicalData
369 .UpdateAccelerationMagnitud();
376 std::cerr <<
"[IMU Device error: Fail to get sample "
377 "count!]\n\t[Operation result: "
378 << m_pXsensMTiModule->getLastRetVal()
379 <<
"]\n\t[Source location: " << __FILE__ <<
":"
380 << __LINE__ <<
"]" << std::endl;
384 std::cerr <<
"[IMU Device error: Fail to get quaternion "
385 "rotation!]\n\t[Operation result: "
386 << m_pXsensMTiModule->getLastRetVal()
387 <<
"]\n\t[Source location: " << __FILE__ <<
":" << __LINE__
392 std::cerr <<
"[IMU Device error: Fail to get magnetic "
393 "rotation!]\n\t[Operation result: "
394 << m_pXsensMTiModule->getLastRetVal()
395 <<
"]\n\t[Source location: " << __FILE__ <<
":" << __LINE__ <<
"]"
400 std::cerr <<
"[IMU Device error: Fail to get gyroscope "
401 "rotation!]\n\t[Operation result: "
402 << m_pXsensMTiModule->getLastRetVal()
403 <<
"]\n\t[Source location: " << __FILE__ <<
":" << __LINE__ <<
"]"
409 <<
"[IMU Device error: Fail to get acceleration vector!]\n\t[Operation result: "
410 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
411 <<
":" << __LINE__ <<
"]" << std::endl;
415 std::cerr <<
"[IMU Device error: Fail to read message!]\n\t[Operation result: "
416 << m_pXsensMTiModule->getLastRetVal() <<
"]\n\t[Source location: " << __FILE__
417 <<
":" << __LINE__ <<
"]" << std::endl;
432 if (m_CollectedFusionSamples == m_SamplesPerFusion)
444 m_FusedPhysicalData.m_Acceleration[0] +=
445 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration[0];
446 m_FusedPhysicalData.m_Acceleration[1] +=
447 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration[1];
448 m_FusedPhysicalData.m_Acceleration[2] +=
449 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration[2];
450 ++m_CollectedFusionSamples;
457 const float NormalizationFactor = 1.0f /
float(m_CollectedFusionSamples);
458 m_FusedIMUState.m_PhysicalData.m_Acceleration[0] =
459 m_FusedPhysicalData.m_Acceleration[0] * NormalizationFactor;
460 m_FusedIMUState.m_PhysicalData.m_Acceleration[1] =
461 m_FusedPhysicalData.m_Acceleration[1] * NormalizationFactor;
462 m_FusedIMUState.m_PhysicalData.m_Acceleration[2] =
463 m_FusedPhysicalData.m_Acceleration[2] * NormalizationFactor;
466 m_FusedIMUState.m_PhysicalData.UpdateAccelerationMagnitud();
469 memset(m_FusedPhysicalData.m_Acceleration, 0,
sizeof(
float) * 3);
470 m_CollectedFusionSamples = 0;
478 if (m_CollectedFusionSamples == m_SamplesPerFusion)
490 m_FusedPhysicalData.m_Acceleration[0] +=
491 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration[0];
492 m_FusedPhysicalData.m_Acceleration[1] +=
493 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration[1];
494 m_FusedPhysicalData.m_Acceleration[2] +=
495 m_XsensMTiFrame.m_IMUState.m_PhysicalData.m_Acceleration[2];
497 ++m_CollectedFusionSamples;
504 const float NormalizationFactor = 1.0f /
float(m_CollectedFusionSamples);
505 m_FusedIMUState.m_PhysicalData.m_Acceleration[0] =
506 m_FusedPhysicalData.m_Acceleration[0] * NormalizationFactor;
507 m_FusedIMUState.m_PhysicalData.m_Acceleration[1] =
508 m_FusedPhysicalData.m_Acceleration[1] * NormalizationFactor;
509 m_FusedIMUState.m_PhysicalData.m_Acceleration[2] =
510 m_FusedPhysicalData.m_Acceleration[2] * NormalizationFactor;
513 m_FusedIMUState.m_PhysicalData.UpdateAccelerationMagnitud();
516 memset(m_FusedPhysicalData.m_Acceleration, 0,
sizeof(
float) * 3);
517 m_CollectedFusionSamples = 0;
546 CIMUDevice::InitializeDevice(
const std::string& PortName,
const SamplingFrequency Frequency)
551#ifdef _IMU_USE_XSENS_DEVICE_
553 if (InitializeXsensDevice(PortName, Frequency))
555 m_SamplingFrequency = Frequency;
556 const int Cylces = 0X1C200 / int(m_SamplingFrequency);
557 m_PeriodMicroSeconds =
572 CIMUDevice::FinalizeModuleDevice()
576#ifdef _IMU_USE_XSENS_DEVICE_
578 FinalizeXsensModuleDevice();
582 UnregisterEventDispatchers();
586 CIMUDevice::ShouldYield()
588 const long int RemainingTime =
591 if (RemainingTime > 0)
593 usleep(__useconds_t(RemainingTime));
598 CIMUDevice::DispatchCylcle()
604 switch (m_FusionStrategy)
609 SendEvent(CIMUEvent(m_LastFrameTimeStamp,
616 SendEvent(CIMUEvent(m_LastFrameTimeStamp,
619 m_IntegratedIMUState));
628 SendEvent(CIMUEvent(m_LastFrameTimeStamp,
635 SendEvent(CIMUEvent(m_LastFrameTimeStamp,
638 m_IntegratedIMUState));
649 SendEvent(CIMUEvent(m_LastFrameTimeStamp,
653 SendEvent(CIMUEvent(m_LastFrameTimeStamp,
656 m_IntegratedIMUState));
669 CIMUDevice::SendEvent(
const CIMUEvent& Event)
672 const unsigned long int TotalDispatchers = m_IMUEventDispatchers.size();
674 if (TotalDispatchers)
676 if (TotalDispatchers == 1)
678 (*m_IMUEventDispatchers.begin())->ReceiveEvent(Event);
681 for (
auto m_IMUEventDispatcher : m_IMUEventDispatchers)
683 m_IMUEventDispatcher->ReceiveEvent(Event);
691 CIMUDevice::SetReferenceTimeStamps()
694 gettimeofday(&m_ReferenceTimeStamp,
nullptr);
695 gettimeofday(&m_LastFrameTimeStamp,
nullptr);
697 if (m_IMUEventDispatchers.size())
698 for (
auto m_IMUEventDispatcher : m_IMUEventDispatchers)
700 m_IMUEventDispatcher->SetReferenceTimeStamps(m_ReferenceTimeStamp);
708 const float NormalizedPriority)
713 struct sched_param SchedulingParameters;
715 if (pthread_getschedparam(m_pInternalThreadHandel, &Policy, &SchedulingParameters) == 0)
717 const int MaximalPriority = sched_get_priority_max(ThreadPolicy);
718 const int MinimalPriority = sched_get_priority_min(ThreadPolicy);
719 const int PriorityRange = MaximalPriority - MinimalPriority;
721 int(round(
float(PriorityRange) * NormalizedPriority +
float(MinimalPriority)));
722 SchedulingParameters.sched_priority = Priority;
723 const int Result = pthread_setschedparam(
724 m_pInternalThreadHandel, ThreadPolicy, &SchedulingParameters);
733 std::cerr <<
"[IMU Device error: SetThreadRunnigMode() returns "
734 "EINVAL!]\n[Source location: "
735 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
739 std::cerr <<
"[IMU Device error: SetThreadRunnigMode() returns "
740 "ENOTSUP!]\n[Source location: "
741 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
745 std::cerr <<
"[IMU Device error: SetThreadRunnigMode() returns "
746 "EPERM!]\n[Source location: "
747 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
751 std::cerr <<
"[IMU Device error: SetThreadRunnigMode() returns "
752 "ESRCH!]\n[Source location: "
753 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
762 std::cerr <<
"[IMU Device error: SetThreadRunnigMode() cannot set running mode while "
763 "thread is not active!]\n[Source location: "
764 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
770 CIMUDevice::ThreadLoop(
void* pData)
778 pIMUDevice->m_IsActive = true;
781 pIMUDevice->SetReferenceTimeStamps();
785 while (pIMUDevice->m_IsActive)
787 pIMUDevice->ShouldYield();
790 pIMUDevice->m_IsDispatching = true;
792 const
bool DispatchingResult = pIMUDevice->DispatchCylcle();
794 pIMUDevice->m_IsDispatching = false;
797 if (!DispatchingResult)
800 <<
"[IMU Device error: DispatchCylcle() returns false!]\n[Source location: "
801 << __FILE__ <<
":" << __LINE__ <<
"]" << std::endl;
806 if (pIMUDevice->m_IsActive)
809 pIMUDevice->m_IsActive = false;
813 pIMUDevice->SendEvent(CIMUEvent(CIMUEvent::eOnIMUStop, pIMUDevice));
#define _IMU_DEVICE_DEFAUL_CHECK_PERIOD_FACTOR_
#define _MINIMAL_UNLOCK(MUTEX)
#define _MINIMAL___LOCK(MUTEX)
#define _IMU_USE_XSENS_DEVICE_
#define VALUE_ORIENT_QUAT
#define OUTPUTSETTINGS_ORIENTMODE_QUATERNION
#define OUTPUTMODE_ORIENT
#define OUTPUTSETTINGS_TIMESTAMP_SAMPLECNT
#define MID_GOTOMEASUREMENT
This class contains the the devices module and the thread for read the measurements.
bool Start(const bool Blocking=true)
bool IntegrateWithFusion()
bool SetFusion(const FusionStrategy Strategy, const ushort SamplesPerFusion)
bool SetThreadRunnigMode(const ThreadPolicyType ThreadPolicy, const float NormalizedPriority)
bool MeanFuseCurrentState()
virtual ~CIMUDevice()
The destructor.
void IncorporateCurrentStateGaussianFusion()
CIMUDevice()
The default constructor. The default constructor sets all member variables to zero,...
SamplingFrequency
Enum specifying the supported sampling frequencies.
bool Connect(const std::string &PortName, const SamplingFrequency Frequency)
void Stop(const bool Blocking=true)
bool IntegrateWithOutFusion()
uint64_t GetDeviceId() const
bool UnregisterEventDispatcher(IIMUEventDispatcher *pIMUEventDispatcher)
bool IntegrateCurrentState()
bool GaussianFuseCurrentState()
ThreadPolicyType
Enum specifying the running thread policy.
void IncorporateCurrentStateMeanFusion()
bool RegisterEventDispatcher(IIMUEventDispatcher *pIMUEventDispatcher)
static long GetElapsedMicroseconds(const timeval &Post, const timeval &Pre)
void SetReferenceTimeStamps(const timeval &Reference)
void SetIMU(CIMUDevice *pIMUDevice)