ValveSoftware / openvr

OpenVR SDK
http://steamvr.com
BSD 3-Clause "New" or "Revised" License
6.07k stars 1.28k forks source link

Motion sickness and rendering object edge shake, when drivering HMD with customer IMU orientation #1426

Open lwcode opened 4 years ago

lwcode commented 4 years ago

I have genenrated a project, based on openvr sample project, to replace odyssey(or vive Pro) hmd pose with my imu orientation. Some operation like this: 1) make a generic tracker as hmd tracker:

EVRInitError CServerDriver_StepVR::Init( vr::IVRDriverContext *pDriverContext )
{
    ...
   CStepVRTrackerDriver m_pHmdTracker = new CStepVRTrackerDriver();
   vr::VRServerDriverHost()->TrackedDeviceAdded(m_pHmdTracker->GetSerialNumber().c_str(), vr::TrackedDeviceClass_GenericTracker, m_pHmdTracker);
}

2) update the pose

void CServerDriver_StepVR::RunFrame()
{
        ....
    if (m_pHmdTracker)
    {
        m_pHmdTracker->RunFrame();
    }
}

3) m_pHmdTracker->RunFrame() update the qRotation and AngularVelocity 4) then add the TrackingOverrides option in steamvr.vrsettings 5) my imu orientation update rate is 1KHz

Finally, it was successful to replace, but when I wear the HMD and move my head, motion sickness is blindingly obvious, and the rendering object's edge looks like jittering or shaking or frame drop ... and a little latency, feel not smoothing. I have checked the origin orientation is good, and have smoothing trajectory. I have tried several other ahrs devices, and the results were the same.

What's wrong with me?

metainf commented 4 years ago

Have you checked that the rotation that you get from your system is smooth/constant? For example, a HTC vive headset sitting still will vary ~.0004 rad when using euler angles to measure. In addition, you need to be able to update the rotation and angular velocity with the right timing as well.

lwcode commented 4 years ago

Have you checked that the rotation that you get from your system is smooth/constant? For example, a HTC vive headset sitting still will vary ~.0004 rad when using euler angles to measure. In addition, you need to be able to update the rotation and angular velocity with the right timing as well.

Thanks for your reply@metainf, I can confirm the rotation is smooth , what is the right timing for update the rotation?

metainf commented 4 years ago

Inside DriverPose_t is poseTimeOffset, which is the delay from when the function is called to when you get pose data. Also make sure that you fill in every field in DriverPose_t with valid numbers, even the ones that you aren't using.

lwcode commented 4 years ago

Inside DriverPose_t is poseTimeOffset, which is the delay from when the function is called to when you get pose data. Also make sure that you fill in every field in DriverPose_t with valid numbers, even the ones that you aren't using.

Does it need to calculate the poseTimeOffset every function calling? I have met another intractable problem that WaitGetPoses() in the application refers to vsync signal(if I understand correctly), so the driver's updating pose timing need synchronize with vsync? but it seems there is no direct relationship between the callback function RunFrame in IServerTrackedDeviceProvider and vsync signal(or WaitGetPoses()), when I update the pose in RunFrame, I find the RunFrame calling time does not always synchronize with the returning time of WaitGetPoses(), thereby it always find that two near frame have the same pose in application because the updating time of RunFrame is later than returning time of calling WaitGetPoses(), what can I do for it? In addition, Does it have any relationship between WaitGetPoses() and vr::VRServerDriverHost()->TrackedDevicePoseUpdated? @metainf @JoeLudwig