Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisiting Bindings and Support for Treadmill devices #1153

Closed
AgentMilkshake1 opened this issue Jul 17, 2019 · 46 comments
Closed

Revisiting Bindings and Support for Treadmill devices #1153

AgentMilkshake1 opened this issue Jul 17, 2019 · 46 comments

Comments

@AgentMilkshake1
Copy link

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
Copy link
Contributor

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
Copy link

cwlmyjm commented Jul 18, 2019

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
Copy link

kaplat commented Jul 18, 2019

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
Copy link
Author

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
Copy link

We support this too!
👍

@JoeLudwig
Copy link
Contributor

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:

  • Return bindings as part of the left hand
  • Return bindings as part of the right hand

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
Copy link

kaplat commented Jul 23, 2019

This sounds like a good solution for all treadmill devices.

@JoeLudwig
Copy link
Contributor

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

@peroht
Copy link

peroht commented Jul 24, 2019

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

@joemarshall
Copy link

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
Copy link
Contributor

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 JoeLudwig reopened this Aug 22, 2019
@JoeLudwig
Copy link
Contributor

JoeLudwig commented Aug 22, 2019

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
Copy link

kaplat commented Aug 23, 2019

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

@AgentMilkshake1
Copy link
Author

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
Copy link

peroht commented Aug 23, 2019

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
Copy link
Contributor

/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
Copy link

peroht commented Aug 23, 2019

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
Copy link

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
Copy link
Contributor

JoeLudwig commented Aug 23, 2019

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
Copy link
Contributor

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
Copy link

peroht commented Aug 24, 2019

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
Copy link

metainf commented Aug 25, 2019

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
Copy link

metainf commented Aug 26, 2019

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
Copy link
Contributor

@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
Copy link

peroht commented Aug 27, 2019

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

@JoeLudwig
Copy link
Contributor

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
Copy link

peroht commented Aug 27, 2019

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

@JoeLudwig
Copy link
Contributor

JoeLudwig commented Aug 27, 2019

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
Copy link

peroht commented Aug 27, 2019

Only one tab
Omnideck_Compound

@peroht
Copy link

peroht commented Aug 27, 2019

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
Copy link

peroht commented Aug 27, 2019

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
Copy link

peroht commented Aug 27, 2019

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
Copy link

peroht commented Aug 27, 2019

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
Copy link
Contributor

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
Copy link

peroht commented Aug 27, 2019

Superb! Again, thanks for the true support.

@joemarshall
Copy link

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
Copy link
Author

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
Copy link
Contributor

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
Copy link

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

@kaplat
Copy link

kaplat commented Sep 9, 2019

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
Copy link

peroht commented Sep 13, 2019

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
Copy link

kaplat commented Sep 30, 2019

Hello,

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

@peroht
Copy link

peroht commented Sep 30, 2019

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

ValveSoftware/steamvr_unity_plugin#536

Lets see what happens and it if works later on.

@peroht
Copy link

peroht commented Oct 10, 2019

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

ValveSoftware/steamvr_unity_plugin#536 (comment)

@peroht
Copy link

peroht commented Oct 22, 2019

As of SteamVR 1.8.13 Beta this should be resolved.
#1193 (comment)

@CybershoesVR
Copy link

CybershoesVR commented Jan 31, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants