OpenXR -- Is it no longer possible to get descriptive device names?

I’m struggling with how to get descriptive device names in OpenXR – this is specifically to identify which HMD the player is using to load the correct visual controller models for their headset.

With OculusSDK this code would return a useable name:

// Get Headset Name
UnityEngine.XR.InputDevice headDevice = InputDevices.GetDeviceAtXRNode(XRNode.Head);
string hmdName = headDevice.name;

I know there isn’t really any good method out there to find out what each headset’s manufacturer internally names their piece of hardware – making discovering all of the names for a headsets a major headache unless you already own all of them. From a variety of sources I was able to gather this list which worked well before I switched to OpenXR:

/// <summary>
/// Static utility class contains the names of all the HMDs (I know of).
/// </summary>
public static class KnownHMDNames {
    // Strings may slightly differ, e.g. "Vive. MV" or "Vive MV.", and not just per OS
    public const string model_vive = "Vive MV";
    public const string model_vive_pro = "VIVE_Pro MV";
    public const string model_lenovoExplorer = "Lenovo Explorer";
    public const string model_hpWindowsMixedReality = "HP Windows Mixed Reality Headset";
    public const string model_samsungOdyssey = "Samsung Windows Mixed Reality 800ZAA";
    public const string model_acer = "Acer AH100";
    public const string model_rift_cv1 = "Oculus Rift CV1";
    public const string model_rift_s = "Oculus Rift S";
    public const string model_quest = "Oculus Quest";
    public const string model_quest_2 = "Quest";
}

Now whenever I run the same command as above this is what I get back (for the CV1 and Quest2):

“Head Tracking - OpenXR” ผ(•̀_•́ผ) ( ఠ ͟ʖ ఠ) ( ͡ಠ ʖ̯ ͡ಠ) … Ugh …

Anyone have a better method for finding out what device is attached in OpenXR?

Or even in the XRManagement parent plugin?

Being hardware agnostic is fantastic and all but this is taking it too far.

Am I up a creak without a paddle here? … This can’t be a rare thing to need to know.

1 Like

bump

1 Like

I understand the whole idea about OpenXR is that this is not necessary. Every maker has made sure that at least their newer devices and latest version of their platforms are somewhow OpenXR compliant. OpenXR does the matching/translation.

Outside of the VivePro, the headsets arn’t as easily identifiable. They run totally independent of the Input APIs, and while you can check the Runtime (Windows or Oculus or SteamVR), I don’t think there is a guaranteed way to get headset model. I could be wrong, happy to be corrected, it’s a long, changing spec.

Since it sounds like you are using this to detect controller model, you can still identify the controller type (well, potentially simulated controller type, because of how OpenXR works). The names are ripped right out of this section: The OpenXR™ Specification
You may need to be flexible but here are some examples: “Oculus Touch Controller OpenXR”, “Windows MR Controller OpenXR”, “Index Controller OpenXR”, “HTC Vive Controller OpenXR”. Do a code search for kDeviceLocalizedName in the package and you can find the others ones currently available (all based on the public OpenXR specification).

You can use InputDevice.GetDevices to get an initial list on startup of connected devices, and then register to InputDevices.deviceConnected to get updates to catch controllers that connect late. Keep in mind a device like the Quest, where the user can switch between hands and controllers at any time, so be ready to drop the current model selection and move to a new one.

Here is a quick example using the InputDevices API.

        void OnEnable()
        {
            InputDevices.deviceConnected += DeviceConnected;
            List<InputDevice> devices = new List<InputDevice>();
            InputDevices.GetDevices(devices);
            foreach(var device in devices)
                DeviceConnected(device);
        }

        void OnDisable()
        {
            InputDevices.deviceConnected -= DeviceConnected;
        }

        void DeviceConnected(InputDevice device)
        {
            // The Left Hand
            if ((device.characteristics & InputDeviceCharacteristics.Left) != 0)
            {
                //Use device.name here to identify the current Left Handed Device
            }
            // The Right hand
            else if ((device.characteristics & InputDeviceCharacteristics.Right) != 0)
            {
                //Use device.Name here to identify the current Right Handed Device
            }
        }

I want to push people to use the Input System, it’s more complex, but also more flexible and powerful. In that case there are similar APIs, such as InputSystem.GetDevice(CommonUsages.LeftHand) and InputSystem.onDeviceChange for a callback on device state changes. Input System devices also have a .name property, and also have a class type, so you can do if(device is MixedRealityController) type coding to identify actual device types.

Hopefully this gets you back up and working.

5 Likes

This looks good for differentiating fully separate brands of headsets, but it doesn’t resolve the issue of determining within brands, e.g. the Oculus Rift CV1 controller from Quest2 / RiftS in OpenXR, as the controller are all named “Oculus Touch Controller OpenXR”.

For raw vr specific inputs and outputs (like vibration) yes, but that’s it.

You’ll still need models for each controller if you’ll want them in your game. Plus the logic for how to pose the player’s avatar hands correctly for those controllers generally differs with the varying inputs on different controller/where that input is located. OpenXR minimized duplicate functionality, it can’t necessarily eliminate it.

Another area which having deceptive full headset name is useful is automatically picking which microphone is for the connected HMD (especially if several mics/webcams/hmds are connected).

1 Like

In OpenXR, this information is purposely obscured, even from us. It’s unfortunate, but the Oculus Touch Gen 1 & 2 are the only controllers in the spec currently that cannot be identified uniquely. However, from a quick scan it looks like all other commercial controllers (that I am aware of at least) can be identified by their name, or by going direct to the OpenXR APIs and getting the active interaction profile path. And there are continually new extensions adding new controllers that can be used. The new action based input patterns used in OpenXR have some good intentions behind them. It helps enable accessibility features and user customization without extra developer work, as well as reducing dev costs in porting to different platforms. But that added abstraction makes it more difficult to 100% identify exactly what hardware is being used.

When it comes to controller models keep an eye on this: https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_controller_model
This is coming to the general OpenXR standard, and as it gains traction amongst other vendors will provide a consistent way for the runtime to give you the controller model instead of trying to discern it. Since we expose most of the underlying OpenXR APIs and handles, a smart user may be able to beat us to the punch on implementing the standard as listed.

3 Likes

Omg that is going to be useful and amazing… “Downloading” the controller models directly from the plug-in API at runtime…

I had read on a few posts about the old Oculus SDK (pre XR management plugins) people signing up and using the omnibus Oculus package just to get controller models “showing up and running” in a few lines of code…

  1. Do you happen to know if that was the case?

It never made any sense to me so I ignored it… I had only every used the package it when just the Rift 1 was released like 4 years ago, back then they already provided a fully animated and rigged controller model in the SDK… Which is why I was kinda shocked when they didn’t release something of similar completeness/quality for the later controllers.

(Just a model w/o animations for the Rift 2/Quest 1. And for the Quest 2 just a model with a single animation you have to cut apart into dozens of clips and then restitched back together in an animator to make it useful…)

  1. Is there any place that describes how those models are provided (model file formats/object setups/animator controller scripts)?

I would imagine something like an asset bundle would be necessary, but that wouldn’t work between various other engines. It would have to be in a standard format like fbx… But I haven’t heard of any system that can export controlling scripts for “Animator” like controllers cross engines… Just animations and skeletons/meshes.

Ok I think I’ve found a way of determining Rift 1 vs 2, it’s not a huge difference but the aspect ratio of the per eye resolution for Rift 1 is 0.9 (1080 / 1200) while the aspect ratio for the Rift 2 is 0.8889… (1280 / 1440).

Edit (June 2021): Ok using the resolution aspect ratio has other problem I had not encountered when I originally wrote this, see AndreasWang’s post below for details.

I think that plus the above method for using device controller type should (95%?) fix the identifying HMD problem for me.

At least for Oculus devices it may be possible to differentiate models using OVR. The below code should differentiate between Quest and Quest 2.

OVRPlugin.SystemHeadset headset = OVRPlugin.GetSystemHeadsetType();
if(headset==OVRPlugin.SystemHeadset.Oculus_Quest){
// Quest 1 stuff here
}else if (headset==(OVRPlugin.SystemHeadset.Oculus_Quest+1)){
// Quest 2 stuff here
}

just want to track this forum

This is really frustrating because I need the actual controller models, not goofy looking hands for my application, and it seems like there’s no way to show the proper controllers!
My other thought-of solution is to create a generic-looking controller that shows the common buttons and inputs across all controller models (touchpad/thumbstick, primary button, trigger, grip), but I can’t think of a design that would work.
Any ideas?

1 Like

I’ve attempted to use aspect ratios based on XRSettings.eyeTextureWidth and XRSettings.eyeTextureHeight as a means to identify the different types of oculus controllers, but it has its fair share of issues. The output of those two variables will change depending on the amount of supersampling that the user has applied through SteamVR (or other runtimes). It also seems like the scaling isnt quite uniform so you end up with slightly different aspect ratios for the same headset as the user changes their resolution multiplier.

You could potentially have a threshold that you use to test for specific aspect ratios but this feels like a very shaky solution that could result in an incorrect HMD type choice as it would need to be used for several vendors. If there is some way to fetch the base resolution of HMD instead of scaled ones then that might have helped.

Without the ability to determine the controller type, we cannot implement things like custom controller models (for example rift/quest controllers without the tracking rings at the front) and controller specific tooltips which is an requirement in my case :frowning:

2 Likes

Bumping to see if anyone has any workarounds to figure out device type, is an important feature for us.

I’ve given up on attempting to automatically figure out controller/hmd type for now and instead opted to give the user a desktop dropdown where they choose the controller type. It’s far from ideal, but it’s better than nothing while we wait for the controller model related extensions to be implemented into the OpenXR spec. Hopefully it will get a bit easier to work with whenever that happens :slight_smile:

1 Like

This is the exact same thing I’ve fallen back to doing.

Turns out the HP Reverb G2 controllers report themselves to OpenXR as “Oculus Touch Controller OpenXR.” Is there a way to determine the current OpenXR runtime in use? At least that way if you knew you were in a Windows Mixed Reality OpenXR session you’d know to load the Reverb G2 model.

Otherwise, I’ll have to resort to the hack of measuring the distance between the grip pose and the aim pose (yeah). This doesn’t work to distinguish Oculus controllers apart, as far as I can tell, but the Reverb G2 has a different aim pose from the “real” Oculus Controllers.

I just need to get a little rant out of my system.

With the above hacks I can fairly reliably determine that the OpenXR device is an Oculus device. I can make an educated guess that it’s a Quest 2 or not, based on the display’s aspect ratio. BUT you have to remember that the HP Reverb G2 also claims it has Oculus Touch controllers. So if the screen’s aspect ratio > 0.925 and < 0.975 it’s PROBABLY an Oculus Quest. Larger than 0.975 it’s PROBABLY an HP Reverb G2. If the screen’s aspect ratio is < 0.925 it’s PROBABLY a Rift S or Quest 1.

BUT if Pico (for example) releases an OpenXR runtime, dollar to donuts it’s going to report its controllers as Oculus Touch. Now you’ve got to figure out some quirk in the reported specs that let you uniquely identify the Pico. Maybe it’s aim pose is also a little different from the Quest’s?

Further, since you can run OpenXR apps in SteamVR with any of the above headsets, you need yet another way to identify the headset/controllers, because now you can’t just rely on the name of the current OpenXR runtime and the name of connected controller.

If OpenXR is the future interface for the whole AR/VR industry, how are we going to deal with this moving forward? Say for example, I want to load low res assets for the Quest 1 and higher res assets for the Quest 2 (this isn’t just about displaying correct controller models for everyone) how do I reliably handle that with OpenXR in its current state?

This idea that developers don’t need to know about the device their application is running on is bananas.

This would be like if the people developing the JavaScript spec decided that nobody needs access to the userAgent string anymore. Any browser-specific quirks now have to be solved by browser vendors implementing extensions. So if div tag alignment is a little off in Microsoft Edge, just send a support request to Microsoft and they’ll consider it for a fix in a future version of their browser, or not.

OpenXR simply needs to give us access to a string that tells us device model, the system its running on, and let developers get work done.

9 Likes

Have you reported this as a bug yet?

It might take them forever to fix it but that sounds like a really easy bug to address for whoever coded it.

Swapping the controllers in and out actually isn’t too bad, I do it using the addressable system and it can swap out the controllers in a fraction of a second with no noticeable frame jitter.

It’s basically just spawning in a new visual model which I then set as a child of a “empty holder” which I have spawning in as the “visual controller” in the standard action based controller. (I’m actually using a slightly customized one in this photo since I use my own abstraction layer on top multiple of Unity’s default input processing system.)

7471463--918044--Customized Action Based Controller With Blank Model Prefab.jpg

At runtime I just check a user setting I have for which controller model is selected then I spawn in the controller like this:

7471463--918038--Controller In Hierachy With Spawned In Conroller For Quest 2.jpg

For me I’ve decided that it’s not work weeks for my time of try to hack something better together when the solution can just be addressed by a single dropdown menu.

<3.

Um… A really good solution which doesn’t use the names is listed above, I wasn’t sure if you read it or not, see:

That might not get you the exact headset model or runtime, but it should get you the correct type of controller in most cases.
(Note: I haven’t tested this yet.)

The problem is this isn’t a bug. This is intentional. It looks like every XR controller that has ab/xy button layout with two joysticks is supposed to describe itself to OpenXR as an “Oculus Touch” controller so the running application knows how to map inputs. I think there are probably more controllers that do this, like the Vive Cosmo and Pico Neo 3, but I don’t have those headsets to test with.