ValveSoftware / openvr

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

Revisiting Bindings and Support for Treadmill devices #1153

Closed AgentMilkshake1 closed 5 years ago

AgentMilkshake1 commented 5 years ago

Hi all,

(Reposting as a new issue as per request) {Posting on behalf of many Treadmill device developers)

Myself and other developers have recently started noticing that Treadmill support has been compromised in recent updates.

I've personally not been very active with OpenVR development over the past few months, but I've recently had reports that since the Index headset has launched many games have updated their SteamVR input systems (a requirement to support Valve Index). As a part of this, game developers are now able to filter actions depending on source (right hand, left hand, any). This means that actions created by game developers are only usable by Treadmill devices in the case that the game developer chooses ANY.

This is a massive step back for Treadmill device developers, as many game developers won't realise the impact their choice at dev level is having at the wider market level. A lot of games previously supported by treadmills are beginning to dwindle in numbers due to this oversight.

We had a brief period where Treadmill devices were becoming quite universal in terms of compatibility, but these recent updates have really damaged the support Treadmill device developers can offer!

What is being done by the OpenVR team to remedy this? Were the team aware that this would be a problem?

JoeLudwig commented 5 years ago

My as-yet-unstarted plan had been to either make bindings from /user/treadmill always show up on both hands. Or maybe let the binding specify which hand to muster with.

How would you like this to work?

cwlmyjm commented 5 years ago

Besides, legacy binding file for Treadmill devices seems not work to these game which has not update with input system on beta 1.6.4. Before this, I have created legacy binding for my driver and the content is similar to vive controller's default, binding the same component to same default action. It work fine on 1.5.16.

kaplat commented 5 years ago

Hello,

I am also a Treadmill device developer and this issue is a big problem for all treadmills.

We thought about a solution and we also think that binding treadmills to both hands is the way to go. This solution is no extra work for game developers and that should be the goal. Games with legacy controls should still bind to the left or right controller.

Best regards

AgentMilkshake1 commented 5 years ago

I think that Treadmills showing up on both hands sounds like an ideal solution. It allows for Treadmills to be mapped to either hand's thumbstick, and in the case that the Treadmill device has button inputs, mapped to either hand's buttons.

This enabled all existing games with thumbstick locomotion options (Onward, Fallout 4 VR, Doom VR, Elder Scrolls VR, Pavlov, any many more) to be supported out the box without any additional work from game developers.

The true agnostic system it should be - All treadmill devices able to map onto whichever thumbstick/button they wish, and for game developers to not even worry about it as it's handled by their default left/right hand input.

CybershoesVR commented 5 years ago

We support this too! 👍

JoeLudwig commented 5 years ago

We talked this over internally and I think what I'm going to go with is two new checkboxes on all threadmill and gamepad bindings:

So the default behavior doesn't change but anyone can make a binding that causes treadmill/gamepad data to flow to the right hand or left hand.

Thoughts?

kaplat commented 5 years ago

This sounds like a good solution for all treadmill devices.

JoeLudwig commented 5 years ago

These new settings will appear in the 1.7.x beta when that emerges.

peroht commented 5 years ago

Late to the party. Yes our system is also hit by this issue. Hope it can be resolved swiftly.

joemarshall commented 5 years ago

In legacy mode my treadmill driver will no longer turn up as anything in games, no matter what hand I set it to report in the extra settings. Legacy debugging info just shows zeros on every axis.

In legacy mode it shouldn't need the report as hand option either, as the hand is set in the action (e.g. left touchpad = left hand), and there's no reason you can't map actions across multiple hands.

This all worked before the recent changes to the input system and legacy mapping stuff, now no old games work.

Does anyone else have a treadmill driver working with legacy input games, or is it broken for everyone?

JoeLudwig commented 5 years ago

The "treat this as left hand" settings apply to any app that uses ulRestrictToDevice when querying action data. That includes any legacy app that is using a binding in with the mirrored option checked. The app doesn't call GetXActionData directly, but SteamVR calls it under the hood when the app calls GetControllerState. So those settings definitely matter for legacy apps.

Can you post the binding files you're using both for the treadmill and the controllers? There's an export button in the binding editor that will dump them into your documents folder.

JoeLudwig commented 5 years ago

It's working for me in Beat Saber: image

I'm using the default bindings for Index Controllers, and a gamepad binding that has this bound: image

And this set: image

(I don't have an actual treadmill to test with, but the treadmill should be exactly the same.)

kaplat commented 5 years ago

I tested about 10 games, new input system and legacy and my treadmill driver works well since 1.7.2

AgentMilkshake1 commented 5 years ago

I'll be able to test fully this weekend to let you know. Many thanks for the update, and fingers crossed I can get back to you within 48 hours with the results!

peroht commented 5 years ago

Since @kaplat gets it working I must be doing something seriously wrong in the setup of our driver or the setup of the binding compared to before. Allow me to describe my headache.

I have both Vive controllers turned on, then I activate our Treadmill driver which uses the treadmill controller type. Thus I now have 3 controllers. First question i have is: are more than two controllers supported?

This version of our driver that I am now testing is isolated to only have trackpad functionality. So when heading to the Input Debugger it shows the /usertreadmill -omnideck with trackpad data for xy and touch/press events being registered fine.

Now, I start a version of Compound which uses the new input system. I observe it has a action called "Locomotion" that in the binding UI is mapped to "Trackpad/Position".

Now, I'd like to know if this should work or not: I set the Vive controller "Locomotion" to "None". Notice that using the Vive touchpad does not move the game anymore. I save its binding. I head back one step, and switch controller to "Omnideck". I select "Locomotion" for the "Trackpad". I try to move around but the game is not registering the movement.

It this supposed to work or have I misunderstood it all? In the driver i set it to be "single_device".

Beta 1.7.8.

Many thanks for the support Joe.

Binding UI stuff: Developer output in Vive Controller.txt

Developer output in Omnideck Controller.txt

Driver stuff (renamed with .txt suffix): default.vrsettings.txt

omnideck_profile.json.txt

JoeLudwig commented 5 years ago

/usertreadmill -omnideck

Does it literally show that string, or does it show /user/treadmill and/or /devices/omnideck/? Can you post a screenshot?

If Compound passes ulRestrictToDevice when it fetches its action data, you will also need to check one or both of the "Return bindings with X hand" checkboxes in the treadmill bindings. That can be hard to know. (And maybe indicates I should write a new input system debugger that's similar to the legacy debugger.)

peroht commented 5 years ago

Of course that was just a typo. It is /user/treadmill. Here is a zipped archive with some screenshots.

SteamVR Omnideck.zip

I have not been able to find the "Return bindings with X hand" option in the UI. Is there a new flag I need to set in the driver init or a resource file? Are these symptoms of me using "single_device" for the driver?

Also, when I've activate our driver the visual legacy controller debugger is all black and I am not able to return to show only the Vive controllers. I need to restart SteamVR to see the Vive controllers again.

Here is a snippet of the activate function I am using for this test. Maybe there are incompatible properties being set by me?

part of activate.txt

Happy weekend.

(Idea: One handy thing would maybe be to have a different color coding for when a legacy app is being edited vs a native one. Now - at least I do sometimes - it can easily be "missed" since the "only" indication is with the string "for legacy apps")

CybershoesVR commented 5 years ago

Thanks! For us the new system works well. Tested on many games. (Arizona, Doom, Skyrim, Nomanssky...)

To make it easy for the user, we consider automatically preselecting “Return as X hand” for the user, depending on game being played. How is it best to set this, and from which side?

JoeLudwig commented 5 years ago

I have not been able to find the "Return bindings with X hand" option in the UI. Is there a new flag I need to set in the driver init or a resource file?

In your Step 4 image, there should be a tab called Extra Settings. That appears when the controller is a "secondary controller", which is defined as having a "root path" of /user/gamepad or /user/treadmill. And THOSE, in turn, are defined by this code:

        else if ( iDevice.second->sControllerType == "gamepad" )
        {
            device["root_path"] = vr::k_pchPathUserGamepad;
        }
        else if ( iDevice.second->eDeviceRole == TrackedControllerRole_Treadmill )
        {
            device["root_path"] = vr::k_pchPathUserTreadmill;
        }

That's a long-winded way to ask, Is the device role of the treadmill device in your driver set to TrackedControllerRole_Treadmill?

If that's not it, please post a system report so I can look at the state of your treadmill device.

JoeLudwig commented 5 years ago

To make it easy for the user, we consider automatically preselecting “Return as X hand” for the user, depending on game being played. How is it best to set this, and from which side?

That needs to be set on the treadmill binding itself. The option shouldn't appear on the other side.

For legacy bindings, you could set it in your default legacy binding file in your driver. For SteamVR Input titles it's tougher because there's no way to predict what the name of the smooth locomotion action is, so you'll have to make a binding file per title.

In both cases, the game might need only left or only right, though, so checking both isn't guaranteed to work correctly.

peroht commented 5 years ago

I have not been able to find the "Return bindings with X hand" option in the UI. Is there a new flag I need to set in the driver init or a resource file?

In your Step 4 image, there should be a tab called Extra Settings. That appears when the controller is a "secondary controller", which is defined as having a "root path" of /user/gamepad or /user/treadmill. And THOSE, in turn, are defined by this code:

      else if ( iDevice.second->sControllerType == "gamepad" )
      {
          device["root_path"] = vr::k_pchPathUserGamepad;
      }
      else if ( iDevice.second->eDeviceRole == TrackedControllerRole_Treadmill )
      {
          device["root_path"] = vr::k_pchPathUserTreadmill;
      }

That's a long-winded way to ask, Is the device role of the treadmill device in your driver set to TrackedControllerRole_Treadmill?

If that's not it, please post a system report so I can look at the state of your treadmill device.

I got it working - but I am not sure if it is working as intended/configured correctly when it comes the config files and your code.

The device role is TrackedControllerRole_Treadmill. As seen in the screenshot Step 6, at the far bottom right for Input Debugger the device is shown as:

/user/treadmill -omnideck

In the Input profile I have this:

"controller_type": "omnideck"'

as per the recommendation in

https://github.com/ValveSoftware/openvr/wiki/Input-Profiles

which recommends the following:

Including your driver name or brand name in the controller type is a good idea so it doesn't collide with controller types from other drivers.

The Input debugger shows the device as this:

/user/treadmill -omnideck

At this point it feels like your code has correctly identified the device as type TrackedControllerRole_Treadmill. Here is my confusion: It does not work and I do not see the Extras menu.

Hmm.. Are you talking in general terms - or is ther a place as a device manufacturer to define this "root path"? I have not specified any instance of "treadmill" or "/user/treadmill" in any of the configuration files. Setting the type role to TrackedControllerRole_Treadmill induces that path right?

Now, if I edit the input profile (influenced by your code shippet) and change it to this instead:

"controller_type": "gamepad"'

the extra menu shows up and I can access "Return bindings as part of the X hand". At this point the game works. Is this what you mean by a "second controller"? By default the "user/treadmill" does not correlate to being a second controller?

At this point the Input debugger lists my device as

/user/gamepad -gamepad

Thanks for the hints on this - however I am not sure if this is .. correct? Mentally to me it is not working/configured as intended although I have configured a device named "omnideck" initialised it with the TrackedControllerRole_Treadmill role meaning the device is being translated as "/user/treadmill -omnideck" in your codebase.

To me it seems like your code does not catch the controller type when it is a custom string (e.g. "omnideck") and thus does not show the extra menu?

I find think that the notion of a "second controller" is a bit vague and needs some updated documentation. Of course - code is developed faster than documentation :)

Again, thanks for the help.

Are anyone else of you treadmill guys having a successful result with "user/treadmill" or do you resort to a "gamepad" as the controller type?

metainf commented 5 years ago

I'm also having issues with getting the treadmill role to work, I've followed the steps, and I can see the options for "Return bindings with X hand". I can see that the trackpad values are changing in the input debugger, but nothing is happening with the legacy input debugger. I've tried the same steps with a gamepad, and that works, but not with our driver. SystemReport

Binding export as txt

metainf commented 5 years ago

After I restarted SteamVR multiple times, it now works for both legacy and current input games. The one game that I've been having issues with is Nature Treks VR, which uses the pose of a controller to move. I tried to bind the pose of the treadmill driver as the left pose, but that didn't do anything. Is there anything that I can do to make that work, or do I have to revert to forcing my treadmill to take on a handed role?

JoeLudwig commented 5 years ago

@peroht I hacked the gamepad driver to set tracked controller role to treadmill and use a new controller type name. Those options are showing up for me: image

Can you post a system report so I can try to sort out what's going on in your case?

Closing this again since it doesn't seem to be a general problem.

peroht commented 5 years ago

Here is a report, thanks. SteamVR-2019-08-27-AM_08_43_58.zip

JoeLudwig commented 5 years ago

Here is a report, thanks. SteamVR-2019-08-27-AM_08_43_58.zip

I didn't see anything in there. With SteamVR running can you grab the output of http://127.0.0.1:8998/input/getstate.json and post that too?

peroht commented 5 years ago

Okidoki, here's to the next: getstate_json.txt

JoeLudwig commented 5 years ago

Hmm. Everything looks fine there too:

      {
         "class" : "TrackedDeviceClass_Controller",
         "components" : [
            {
               "path" : "/input/trackpad/x",
               "scalar_type" : "VRScalarType_Absolute",
               "scalar_units" : "VRScalarUnits_NormalizedTwoSided",
               "type" : "InputValueType_Scalar",
               "visibility" : "InputValueVisibility_Public"
            },
            {
               "path" : "/input/trackpad/y",
               "scalar_type" : "VRScalarType_Absolute",
               "scalar_units" : "VRScalarUnits_NormalizedTwoSided",
               "type" : "InputValueType_Scalar",
               "visibility" : "InputValueVisibility_Public"
            },
            {
               "path" : "/input/trackpad/touch",
               "type" : "InputValueType_Boolean",
               "visibility" : "InputValueVisibility_Public"
            },
            {
               "path" : "/input/trackpad/click",
               "type" : "InputValueType_Boolean",
               "visibility" : "InputValueVisibility_Public"
            },
            {
               "path" : "/pose/raw",
               "type" : "InputValueType_Pose",
               "visibility" : "InputValueVisibility_Public"
            },
            {
               "path" : "/pose/tip",
               "type" : "InputValueType_Pose",
               "visibility" : "InputValueVisibility_Public"
            }
         ],
         "container" : "4294967300",
         "controller_type" : "omnideck",
         "resource_root" : "omnideck",
         "root_path" : "/user/treadmill",
         "serial_number" : "OMN-00000004"
      },

The most important part of that for this issue is root_path, which exactly matches my own test case: "root_path" : "/user/treadmill",

Can you post a screenshot of the tabs on the binding UI screen with the "omnideck" controller type selected?

peroht commented 5 years ago

Only one tab Omnideck_Compound

peroht commented 5 years ago

And simply editing the "controller_type" in omnideck_profile.json from "Omnideck" to "gamepad" gives the following UI: Omnideck_as_gamepad_Compound

and when I configure the Trackpad as in the image before and press enable for left hand locomotion in compound works.

peroht commented 5 years ago

Aaaand.. tada. And when I change "Omnideck" to "omnideck" the "Extra Settings" finally seem to show up. I will test it several more times.

I observe that when I head to the "Input Debugger" my device is it is listed exactly with lowercase "O" as

/user/treadmill -omnideck

in both cases. So, even if I change the "controller_type" to "Omnideck" or "omnideck" the Input Debugger still shows it with a lower case "o".

I guess it is stated somewhere in the guide that the upper/lower case is very important? I get confused when there seems to be code in the Input Debugger seem to convert it to lowercase?

peroht commented 5 years ago

More progress. And the Test Controller UI starts showing this successfully: omnideck_device_Controller_Settings

Before, with "Omnideck" instead of "omnideck" the Test Controller UI just was black and I could not use the UI at all anymore. I had to restart Steam.

peroht commented 5 years ago

So this seems to be the error.

I see that in the http://127.0.0.1:8998/input/getstate.json this snippet is always the same no matter if I use "Omnideck" or "omnideck". I believe this controller type is infered from the driver path - case sensitive?

         "container" : "4294967300",
         "controller_type" : "omnideck",
         "resource_root" : "omnideck",
         "root_path" : "/user/treadmill",
         "serial_number" : "OMN-00000004"

but in the beginning there is this, from my input_profile.json:

   "controller_types" : [
      {
         "controller_type" : "Omnideck",
         "device_class" : "TrackedDeviceClass_Controller",
         "driver_name" : "omnideck",
         "input_bindingui_mode" : "single_device",
         "input_bindingui_right" : {
            "image" : "{omnideck}/icons/barebones.svg",
            "transform" : "scale(-1,1)",
            "uri" : "/omnideck/icons/barebones.svg"
         }

So this seems to be the miss ive done in order for the device/path matching code to work?

So, now if I change the uppercase O to a lower case o in the input_profile.json it will produce

   "controller_types" : [
      {
         "controller_type" : "omnideck",
         "device_class" : "TrackedDeviceClass_Controller",
         "driver_name" : "omnideck",
         "input_bindingui_mode" : "single_device",
         "input_bindingui_right" : {
            "image" : "{omnideck}/icons/barebones.svg",
            "transform" : "scale(-1,1)",
            "uri" : "/omnideck/icons/barebones.svg"
         }

and the Extras menu will begin to appear.

JoeLudwig commented 5 years ago

Ack! I'll fix the code to make sure that's case-insensitive. That fix will go out in a future SteamVR update.

For now, it sounds like you have a workaround.

peroht commented 5 years ago

Superb! Again, thanks for the true support.

joemarshall commented 5 years ago

Just a note here that ours is all working now with the extra menu.

One detail that caught us out yesterday, if the vive controller fails to connect for some reason, I think it no longer maps anything to that hand. Or something like that. We had a vive controller go into pairing mode for some inexplicable reason yesterday and that hand stopped working. Is fine once they're on though. Is that expected behaviour? I guess maybe games are checking which hand is there or something.

AgentMilkshake1 commented 5 years ago

Extraordinarily late to the party, but I can confirm that all is working as expected in the current Steam VR Beta.

Many thanks for the hard work, and explanations above!

JoeLudwig commented 5 years ago

One detail that caught us out yesterday, if the vive controller fails to connect for some reason, I think it no longer maps anything to that hand. Or something like that. We had a vive controller go into pairing mode for some inexplicable reason yesterday and that hand stopped working. Is fine once they're on though. Is that expected behaviour? I guess maybe games are checking which hand is there or something.

It could be apps checking to see if the controller is on. No Man's Sky, for instance, seems to do that. (Which I know because radiation almost killed me yesterday when my controller ran out of juice.)

We don't load bindings for controllers that don't exist, so maybe that is interfering too? Do you have a repro case where you know the app isn't checking for the existence of controllers?

CybershoesVR commented 5 years ago

Thank you, this works great for Cybershoes. Wouldn't it be great to give developers on Unity, Unreal,... the possibility to filter their inputs for treadmills?

e.g. https://github.com/ValveSoftware/steamvr_unity_plugin/pull/486

kaplat commented 5 years ago

Thank you, this works great for Cybershoes. Wouldn't it be great to give developers on Unity, Unreal,... the possibility to filter their inputs for treadmills?

e.g. ValveSoftware/steamvr_unity_plugin#486

While this could be nice to have, it should never replace the current solution. I think the current solution is the most convenient solution for application developers. I am not certain, that all application developers will also implement the filter for treadmills and these applications would not work again. So again, a filter for treadmills could be an additional thing, but should not replace the current solution.

peroht commented 5 years ago

I do not seem to be able to control legacy applications which are not hosted on steam but only locally stored on my harddrive using this method. It works for apps hosted on steam though. Must investigate further.

Anyone else seen an issue with this?

kaplat commented 5 years ago

Hello,

I have also seen this issue, but have not further investigated it yet.

peroht commented 5 years ago

I can not make it work on standalone builds. It happens on many computers. It works when I work with the UnityEditor but once I've built an exe I can not save anymore. I ended up reporting an error on the steamvr unity github

https://github.com/ValveSoftware/steamvr_unity_plugin/issues/536

Lets see what happens and it if works later on.

peroht commented 5 years ago

I have found a temporary solution for this bug, please continue reading here:

https://github.com/ValveSoftware/steamvr_unity_plugin/issues/536#issuecomment-540487404

peroht commented 4 years ago

As of SteamVR 1.8.13 Beta this should be resolved. https://github.com/ValveSoftware/openvr/issues/1193#issuecomment-542853915

CybershoesVR commented 4 years ago

In the Walking Dead Saint & Sinners the steam system button does not work when on a RIFT or QUEST We think the Oculus version launches, maybe because Steam & Oculus plugin are activated in the game engine. The bindings don't work, no movement. Besides affecting treadmills, the game can't be streamed to the Quest via Virtual Desktop.

Is there a way to get by and force the game to the STEAMVR version?

Same with: Alice VR, Apex Construct, Borderlands, Espire1, Hellsplit, Layers of Fear, Never Bound, OrbusVR, Seeking Dawn, The Wizards.