diff --git a/motionPose/MotionPoseController.cpp b/motionPose/MotionPoseController.cpp index 0d455a2..5c8756b 100644 --- a/motionPose/MotionPoseController.cpp +++ b/motionPose/MotionPoseController.cpp @@ -10,7 +10,7 @@ namespace driver m_unObjectId = vr::k_unTrackedDeviceIndexInvalid; m_ulPropertyContainer = vr::k_ulInvalidPropertyContainer; - m_sSerialNumber = "MotionPoseVirtualController 0.2.0"; + m_sSerialNumber = "MotionPoseVirtualController 0.2.1"; m_sModelNumber = "MotionPoseVirtualController"; rigYawOffset = 0; @@ -121,64 +121,101 @@ namespace driver pchResponseBuffer[0] = 0; } - vr::DriverPose_t CMotionPoseControllerDriver::GetPose() + // Create a string with last error message + std::string CMotionPoseControllerDriver::GetLastErrorStdStr() { - _pose.poseIsValid = false; - _pose.deviceIsConnected = _moverConnected; - _pose.shouldApplyHeadModel = false; - _pose.willDriftInYaw = false; - - vr::HmdQuaternion_t yaw = vrmath::quaternionFromRotationY(rigYawOffset); - - // Create connection to OVRMC - if (!_ovrmcConnected) + DWORD error = GetLastError(); + if (error) { - if (openMmf(MapFile_OVRMC, mmfFile_OVRMC, L"Local\\OVRMC_MMFv1", 4096, _ovrmcConnected)) + LPVOID lpMsgBuf; + DWORD bufLen = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf, + 0, NULL); + if (bufLen) { - Data_OVRMC = (MMFstruct_OVRMC_v1*)mmfFile_OVRMC; - } - } - else - { - // Get data from OVRMC - rigOffset = Data_OVRMC->Translation; - rigYawOffset = Data_OVRMC->Rotation.v[1]; - } + LPCSTR lpMsgStr = (LPCSTR)lpMsgBuf; + std::string result(lpMsgStr, lpMsgStr + bufLen); - if (!_moverConnected) - { - _pose.result = vr::TrackingResult_Calibrating_InProgress; - _pose.qRotation = vrmath::quaternionFromYawRollPitch(rigYawOffset, 0, 0); + LocalFree(lpMsgBuf); - // Init was unsuccessful, return empty pose - if (!openMmf(MapFile_Mover, mmfFile_Mover, L"Local\\motionRigPose", 4096, _moverConnected)) - { - return _pose; + return result; } - - rigPose = (MMFstruct_Mover_v1*)mmfFile_Mover; } + return std::string(); + } + vr::DriverPose_t CMotionPoseControllerDriver::GetPose() + { + __try + { + _pose.poseIsValid = false; + _pose.deviceIsConnected = _moverConnected; + _pose.shouldApplyHeadModel = false; + _pose.willDriftInYaw = false; - // Convert from mm to m - vr::HmdVector3d_t rigTranslation = { 0 }; - rigTranslation.v[0] = rigPose->rigSway / (double)1000.0; - rigTranslation.v[1] = rigPose->rigHeave / (double)1000.0; - rigTranslation.v[2] = -rigPose->rigSurge / (double)1000.0; + vr::HmdQuaternion_t yaw = vrmath::quaternionFromRotationY(rigYawOffset); - // Create the rotation. Convert from degree to radian - _pose.qRotation = vrmath::quaternionFromYawRollPitch(rigYawOffset + rigPose->rigYaw * 0.01745329251994329, -rigPose->rigRoll * 0.01745329251994329, rigPose->rigPitch * 0.01745329251994329); + // Create connection to OVRMC + if (!_ovrmcConnected) + { + if (openMmf(MapFile_OVRMC, mmfFile_OVRMC, L"Local\\OVRMC_MMFv1", 4096, _ovrmcConnected)) + { + Data_OVRMC = (MMFstruct_OVRMC_v1*)mmfFile_OVRMC; + } + } + else if (Data_OVRMC != nullptr) + { + // Get data from OVRMC + rigOffset = Data_OVRMC->Translation; + rigYawOffset = Data_OVRMC->Rotation.v[1]; + } - // Create the translation (XYZ position in 3d space) - vr::HmdVector3d_t rigVector = vrmath::quaternionRotateVector(_pose.qRotation, rigTranslation) + rigOffset; - _pose.vecPosition[0] = rigVector.v[0]; - _pose.vecPosition[1] = rigVector.v[1]; - _pose.vecPosition[2] = rigVector.v[2]; + if (!_moverConnected) + { + _pose.result = vr::TrackingResult_Calibrating_InProgress; + _pose.qRotation = vrmath::quaternionFromYawRollPitch(rigYawOffset, 0, 0); - _pose.poseIsValid = true; - _pose.result = vr::TrackingResult_Running_OK; + // Init was unsuccessful, return empty pose + if (!openMmf(MapFile_Mover, mmfFile_Mover, L"Local\\motionRigPose", 4096, _moverConnected)) + { + return _pose; + } - return _pose; + rigPose = (MMFstruct_Mover_v1*)mmfFile_Mover; + } + + if (rigPose != nullptr) + { + // Convert from mm to m + vr::HmdVector3d_t rigTranslation = { 0 }; + rigTranslation.v[0] = rigPose->rigSway / (double)1000.0; + rigTranslation.v[1] = rigPose->rigHeave / (double)1000.0; + rigTranslation.v[2] = -rigPose->rigSurge / (double)1000.0; + + // Create the rotation. Convert from degree to radian + _pose.qRotation = vrmath::quaternionFromYawRollPitch(rigYawOffset + rigPose->rigYaw * 0.01745329251994329, -rigPose->rigRoll * 0.01745329251994329, rigPose->rigPitch * 0.01745329251994329); + + // Create the translation (XYZ position in 3d space) + vr::HmdVector3d_t rigVector = vrmath::quaternionRotateVector(_pose.qRotation, rigTranslation) + rigOffset; + _pose.vecPosition[0] = rigVector.v[0]; + _pose.vecPosition[1] = rigVector.v[1]; + _pose.vecPosition[2] = rigVector.v[2]; + + _pose.poseIsValid = true; + _pose.result = vr::TrackingResult_Running_OK; + } + return _pose; + } + __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + throw std::exception(); + } } void CMotionPoseControllerDriver::RunFrame() @@ -189,7 +226,8 @@ namespace driver } catch (std::exception& e) { - LOG(ERROR) << "MMF failed: " << e.what(); + LOG(ERROR) << "MMF failed: " << e.what() << " " << GetLastErrorStdStr(); + // Close mover connection if (CloseHandle(MapFile_Mover) == 0) diff --git a/motionPose/MotionPoseController.h b/motionPose/MotionPoseController.h index 3bad2cf..163b603 100644 --- a/motionPose/MotionPoseController.h +++ b/motionPose/MotionPoseController.h @@ -67,7 +67,7 @@ namespace driver const char* logConfigDefault = "* GLOBAL:\n" " FORMAT = \"[%level] %datetime{%Y-%M-%d %H:%m:%s}: %msg\"\n" - " FILENAME = \"driver_motioncompensation.log\"\n" + " FILENAME = \"driver_motionpose.log\"\n" " ENABLED = true\n" " TO_FILE = true\n" " TO_STANDARD_OUTPUT = true\n" @@ -95,10 +95,6 @@ namespace driver void init_logging(); - bool initializeMoverMmf(); - - void initializeOvrmcMmf(); - bool openMmf(HANDLE& MapFile, char*& mmfFile, LPCWSTR szName, int BufferSize, bool& Connected); virtual void Deactivate(); @@ -112,6 +108,8 @@ namespace driver /** debug request from a client */ virtual void DebugRequest(const char* pchRequest, char* pchResponseBuffer, uint32_t unResponseBufferSize); + std::string GetLastErrorStdStr(); + virtual vr::DriverPose_t GetPose(); void RunFrame(); diff --git a/motionPose/motionPose.vcxproj b/motionPose/motionPose.vcxproj index 498e2e0..9d23b89 100644 --- a/motionPose/motionPose.vcxproj +++ b/motionPose/motionPose.vcxproj @@ -162,6 +162,7 @@ third-party\easylogging++;openvr\headers;%(AdditionalIncludeDirectories) + Async Windows