openvr icon indicating copy to clipboard operation
openvr copied to clipboard

How can I get controller roles from within a driver?

Open jangxx opened this issue 5 years ago • 12 comments

I'm working on a driver which creates virtual trackers based on the position of the controllers and the HMD. I am able to get the poses of the HMD as well as the controllers with vr::VRServerDriverHost()->GetRawTrackedDevicePoses(), but I can't find a way to tell which index corresponds to which controller role. Index 0 is always the HMD, but how can I find the index of TrackedControllerRole_LeftHand and TrackedControllerRole_RightHand?

vr::VRSystem()->GetTrackedDeviceIndexForControllerRole() is not available within a driver and according to the header file it's deprecated anyway, so I don't really want to use it.

Using vr::VRProperties() is recommended in the header file, but I only see a property called Prop_ControllerRoleHint_Int32, which is just a hint and not a definite value.

In the end I could always write a "feeder application" which uses the VRInput system, but this seems like way too much overhead considering there is a way to get the input from within a driver already.

jangxx avatar Nov 12 '20 20:11 jangxx

It is a bit cluttery, but on the client side you can use GetOriginTrackedDeviceInfo() and compare it with the vr::VRInputValueHandle_t you've assigned to one your hands using vr::VRInput()->GetInputSourceHandle().

https://github.com/Omnifinity/OpenVR-Tracking-Example/blob/master/HTC%20Lighthouse%20Tracking%20Example/LightHouseTracking.h#L42

https://github.com/Omnifinity/OpenVR-Tracking-Example/blob/master/HTC%20Lighthouse%20Tracking%20Example/LighthouseTracking.cpp#L136

https://github.com/Omnifinity/OpenVR-Tracking-Example/blob/master/HTC%20Lighthouse%20Tracking%20Example/LighthouseTracking.cpp#L621

Yes, it used to be simply about accessing a controller with an index number but that is not suggested nor supported anymore.

peroht avatar Nov 13 '20 13:11 peroht

If I Ctrl+F for GetOriginTrackedDeviceInfo within the openvr_driver.h I don't get any results, so I think your suggestion is for an OpenVR client instead of a driver? I know how to access the data I need from a client, but I'm pretty sure that there is also a recommended way to do it from within a driver, but I couldn't find it unfortunately.

jangxx avatar Nov 13 '20 13:11 jangxx

Yes, that example was explaining how to find the hand on the client side - maybe you already knew how to do it? Sorry if you already did.

Anyway, from my understanding, and as you point out, is that inside your driver you have an ability to extract data from device 0 (HMD) but only publish events etc for your own device. Could be by design on how it is architected to prevent infinite feedback/driver/emulator hookup loops from us crazy driver hackers :)?

A few years ago matzman666 hooked into the driver side to do advanced remappings. This was before the new input system was implemented.

Yes, I've had to roll a feeder application pushing data to our drivers for our use cases.

Maybe someone else has a more clever solution and will comment this.

peroht avatar Nov 13 '20 16:11 peroht

Anyway, from my understanding, and as you point out, is that inside your driver you have an ability to extract data from device 0 (HMD) but only publish events etc for your own device.

Publishing events from my own devices is fine, I just need to access the poses of the controllers as well as the HMD, which I can totally do with vr::VRServerDriverHost()->GetRawTrackedDevicePoses(). My only problem is the correlation between the indices of the returned array and the roles of the devices.

Imagine this scenario: I want to build a driver which creates a virtual tracker hovering 50cm over the right controller, so all I need to do is get the pose of the right controller and add [0, 0.5, 0] to the position vector (and do some coordinate system stuff, but let's ignore that for now). If I try to access the array of tracked devices, I get an array with 4 elements, where 0 is the HMD and 1, 2 and 3 are the controllers and my virtual tracker. I can easily find out which index my virtual tracker has (let's say it's 2), so all I need to find out now is which controller is the right hand one. Both are possible and without a way to access the devices role, there is no way to know if index 1 or 3 corresponds to the right hand. That is basically my problem.

jangxx avatar Nov 13 '20 17:11 jangxx

I second your feature request. It would be really handy to get the role inside the driver after the openvr internals have made its best guess.

Today it seems not possible via the PollNextEvent(). I find that the accessing Prop_DeviceClass_Int32 gives correct ETrackedDeviceClass::TrackedDeviceClass_Controller on controller device activation but the Prop_ControllerRoleHint_Int32 is always 0 irrespective on polling later events from the controller. Cheers.

peroht avatar Nov 14 '20 13:11 peroht

In the end I could always write a "feeder application" which uses the VRInput system, but this seems like way too much overhead considering there is a way to get the input from within a driver already.

In general, there are two ways around these kinds of arbitrary boundaries between "client-land" and "driver-land", and otherwise "needs to be here, but isn't" missing functionality in VRServer. The first is to make a "client-land" application that communicates with your driver via IPC, and the other is to hook functions in IVRServerDriverHost. The former is tedious, sure, but just go ahead and do it because Valve developers have been completely MIA for months and I can't even remember the last time they actually added something that was brought up as a feature request. You'll be done with your implementation months/years before your issue is addressed. The latter is much more complex and should only be done when all else fails (and will almost certainly be condemned as "not the way" by Valve developers should they ever deem to grace us with their presence).

TheDeveloperGuy avatar Nov 14 '20 13:11 TheDeveloperGuy

@jangxx This is a bit off topic, but I am interested in knowing if you were able to use the poses from IVRServerDriverHost::GetRawTrackedDevicePoses() successfully?

When I was trying to use this function as a kind of "loopback" (i.e. I used this function to get a pose of my own device, for which I was feeding the raw DriverPose_t data to the runtime, expecting to get filtered/predicted pose from the runtime back) it did give me poses which were stuttering quite a bit. In the end it was far worse than the raw poses I was feeding in, so I eventually dropped the idea.

risa2000 avatar Nov 26 '20 13:11 risa2000

No I have not, but I have not tried doing so either, sorry. After I read that there is no good way to actually get the device roles from the array, I wrote an external feeder instead. Then I found out that my whole project doesn't really work for other reasons, so I've put it on ice for now (and probably forever). I'm currently trying to reuse some of the code for a new project, but for that project I definitely need an external feeder anyway, so I don't need the poses from within the driver anymore.

jangxx avatar Nov 26 '20 13:11 jangxx

Please consider closing this issue @jangxx now that you've set it aside. Cheers.

peroht avatar Nov 27 '20 11:11 peroht

Well, I mean the feature is still not there, right? Just because I don't need it anymore (for now), I still think it would be a good feature to have, maybe for my own future projects or for other peoples projects as well.

jangxx avatar Nov 27 '20 12:11 jangxx

Sorry I was doing some serious tidying up elsewhere and did not think twice and slammed in the comment here. I apologise, you are correct keeping it. Have a good day.

peroht avatar Nov 27 '20 12:11 peroht

Has this problem been solved?

TitansWhale avatar May 11 '23 13:05 TitansWhale