cmbruns / pyopenvr

Unofficial python bindings for Valve's OpenVR virtual reality SDK
BSD 3-Clause "New" or "Revised" License
251 stars 40 forks source link

Improved sample for Use in README.md #17

Closed bo3b closed 8 years ago

bo3b commented 8 years ago

Thanks for these interfaces, it's working well for me.

Your starting sample in the Use section of the README.md was not updating the tracking numbers for me, just repeating the same numbers 100 times.

This might be a Vive/Rift difference. My test case here is a CV1 Rift. Python 3.5.

I tweaked the code by adding the creation of the Compositor object, and then use waitGetPoses, as it seems required to update the head tracking positions.

Here is the sample with the two added lines. While running in my test case, it updates the tracking numbers.

Please feel free to use this or not as you prefer.

import sys
import time
import openvr

vr_system = openvr.init(openvr.VRApplication_Scene)
vr_compositor = openvr.IVRCompositor()

for i in range(100):
    poses = vr_system.getDeviceToAbsoluteTrackingPose(
        openvr.TrackingUniverseStanding,
        0,
        openvr.k_unMaxTrackedDeviceCount)
    pose = poses[openvr.k_unTrackedDeviceIndex_Hmd]
    vr_compositor.waitGetPoses(poses, openvr.k_unMaxTrackedDeviceCount, None, 0)  
    print(pose.mDeviceToAbsoluteTracking)
    sys.stdout.flush()
    time.sleep(0.2)

openvr.shutdown
cmbruns commented 8 years ago

This is the first I've heard of anyone trying the Rift with pyopenvr. I'm pleased it's working for you.

Even with the HTC Vive, VRSystem.getDeviceToAbsoluteTrackingPose(...) spews nonsense for about 10 seconds before actually tracking the headset position. I think it's a bug in openvr and VRSystem.getDeviceToAbsoluteTrackingPose(...) is just broken.

Instead of IVRCompositor(), we should probably use VRCompositor(), which in recent versions of pyopenvr returns a singleton instance which maybe gets updated when the headset changes or something, just like in the C++ API.

I assume you are using pyopenvr instead of pyovr because you want to support both Rift and Vive?

I'll update the examples and Readme after I get a chance to test this. Thanks.

bo3b commented 8 years ago

Yes, I want to use pyopenvr so that I get both Rift and Vive with one interface, and my app is not performance sensitive so I think using Python should be fine.

On the Rift, the VRSystem.getDeviceToAbsoluteTrackingPose() shows legitimate numbers from the start (probably calls into the Oculus SDK). They just never change, which led me to look into the Oculus SDK. That suggests that it needed the waitGetPoses() in a loop to actively update the tracking.

IVRCompositor: Oops! Yeah, using VRCompositor() is clearly the right choice. I tested that change with Rift, and it works like expected.

Edit: You are right that just initializing VRCompositor() makes it work, no waitGetPoses needed.

So a maybe better version is:

import sys
import time
import openvr

vr_system = openvr.init(openvr.VRApplication_Scene)
vr_compositor = openvr.VRCompositor()

for i in range(100):
    poses = vr_system.getDeviceToAbsoluteTrackingPose(
        openvr.TrackingUniverseStanding,
        0,
        openvr.k_unMaxTrackedDeviceCount)
    pose = poses[openvr.k_unTrackedDeviceIndex_Hmd]
    print(pose.mDeviceToAbsoluteTracking)
    sys.stdout.flush()
    time.sleep(0.2)

openvr.shutdown
cmbruns commented 8 years ago

Rather than mysteriously creating but subsequently not using VRCompositor(), I felt it would be simpler to just use waitGetPoses() for this example.

import sys
import time
import openvr

openvr.init(openvr.VRApplication_Scene)

poses_t = openvr.TrackedDevicePose_t * openvr.k_unMaxTrackedDeviceCount
poses = poses_t()

for i in range(100):
    openvr.VRCompositor().waitGetPoses(poses, len(poses), None, 0)
    hmd_pose = poses[openvr.k_unTrackedDeviceIndex_Hmd]
    print(hmd_pose.mDeviceToAbsoluteTracking)
    sys.stdout.flush()
    time.sleep(0.2)

openvr.shutdown()

I update README.md and src/samples/track_hmd.py this way.

Fixed in revision 858181f16454b32d2bc27350a8bb30ee188eb706