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

[Update] Support Tundra Tracker quirks #9

Merged
merged 2 commits into from
Aug 14, 2024

Conversation

digitalf0x
Copy link
Contributor

@digitalf0x digitalf0x commented Mar 25, 2024

UPDATE - merged!

Find downloads from main branch here.

Testing instructions updated below to now point to the main Haptic Pancake branch.

In short

  • Detect and adapt to Tundra Trackers' limitations with legacy haptics API
    • Set Tundra Tracker's internal pulse multiplier to 1 (instead of 100)
    • Run haptics loop every 4 ms (instead of 50 ms)
    • Convert pulses from milliseconds to microseconds
    • If pulse exceeds 4 ms, extend into next haptics loop iteration (e.g. Identify button)

Details

Ideally, we'd use the IVRInput API which appears to be handled correctly by Tundra Trackers, allowing for triggering haptics that last multiple seconds.

However, that API is… complex. Lighthouse Console allows you to trigger it exactly like triggerHapticPulse(), which is great. But the SteamVR API wants you to make a bunch of rebindable haptics outputs.

I've documented this here: Migrate to IVRInput's haptic Actions and/or consider OpenXR?

In the meantime, this pull request hacks around Tundra Trackers/etc using microseconds instead of milliseconds for the legacy triggerHapticPulse() command.

On microseconds vs milliseconds…

Incidentally, going by the lighthouse_console help, Vive Trackers are the odd one out:

:~$ "$HOME/.local/share/Steam/steamapps/common/SteamVR/tools/lighthouse/bin/linux64/lighthouse_console"
lh> help
[…]
haptic [<duration_us>] [<interval_us>] [<repeat_count>] Trigger haptic pulse
haptic2 [<frequency_hz>] [<duration_ms>] [<amplitude_percent>]  Trigger haptics
[…]

The help describes "haptic pulse" (presumably triggerHapticPulse()) as being specified in microseconds, whereas "haptics" (presumably IVRInput) operates in milliseconds.

This could be adjusted so microseconds are the default, and Vive Trackers are the exception..?

Testing

There are builds for Linux and Windows here:
https://github.com/Z4urce/VRC-Haptic-Pancake/actions?query=branch%3Amain+is%3Asuccess

Click the topmost result, then get the downloads below, e.g. hapticpancake_windows_v0.5.2-15-g456a1ab.

If you can't click that text in the Artifacts section, you're not signed into GitHub (if necessary I can look into setting up nightly.link for the project - example of main branch - not this one! - here).

On Linux, I've been setting the pattern to Linear, but that might also not work for you.

@digitalf0x digitalf0x force-pushed the wip-ft-haptic-tundrakes branch 3 times, most recently from 8b823b8 to 955eb35 Compare March 29, 2024 23:43
@digitalf0x
Copy link
Contributor Author

I've been thinking on how to emulate the Vive Tracker behavior until there is time to revisit the IVRInput system that replaces the deprecated triggerHapticPulse() function, but to do so…

What does a Vive Tracker do if you call triggerHapticPulse() again before the previous haptic pulse finished?

  • Scenario 1: triggerHapticPulse(500 ms), sleep(50 ms), triggerHapticPulse(30 ms)
    • Does the second call replace (shorten) the first (80 ms total vibration)?
  • Scenario 2: triggerHapticPulse(500 ms), sleep(450 ms), triggerHapticPulse(500 ms)
    • Does the second call get cut off when the first call would have ended (500 ms total vibration)?
  • Scenario 3: triggerHapticPulse(500 ms), sleep(30 ms), triggerHapticPulse(500 ms)
    • Does the second call extend/continue after the first call? (1000 ms total vibration)?

The exact durations don't matter; pick numbers that work with Vive Trackers and are easy enough to measure.

@digitalf0x
Copy link
Contributor Author

Thanks to preparing Windows as a plan B if Proton fails with Furality (it at least seemed to work in March), I can confirm this appears to work on Windows, too.

Still need to determine if the IVRInput system is the proper way forward, or if it's time to build out the hack described in the source code comments (using tracker model to adjust feedback thread timing and implement a queue to incrementally apply any pulse exceeding 3999 µs or so).

Interestingly, SteamVR's own tracker Identify button appears to have the same issue - it sends several very brief pulses, as if confusing milliseconds (Vive Tracker) with microseconds (Tundra Tracker, possibly other devices).

@digitalf0x
Copy link
Contributor Author

Good news - Identify button now works! And I've implemented Tundra Tracker model detection (shouldn't mess with Vive Trackers/etc), and a slightly less awful method of converting to/from microseconds or other units.

@digitalf0x digitalf0x force-pushed the wip-ft-haptic-tundrakes branch 6 times, most recently from 622475d to e42c6ba Compare June 5, 2024 00:33
@digitalf0x
Copy link
Contributor Author

Note to self: I may want to try modifying this so instead of clipping any vibration intensity above 100%, it extends the pulse beyond a single loop iteration by using the hack_pulse_force_stop_time variable.

That way, quick pokes should trigger the Velocity method to make a longer-than-4ms pulse that has a chance of being felt.

@digitalf0x
Copy link
Contributor Author

digitalf0x commented Jul 8, 2024

Soo… PySimpleGUI v4 is no longer on PyPy, making the GitHub action fail.

PySimpleGUI v5 is a drop-in upgrade but it's also now a commercial product with a free hobbyist license key option. Everyone who uses it (every end user, not just developers!) has to register their own license key and that key expires after 1 year.

You can still use PySimpleGUI v4 if you have a local copy, but this breaks the automated builds here (necessary for me to make Windows versions) and threatens the ability to build the current Haptic Pancake software.

@digitalf0x
Copy link
Contributor Author

@digitalf0x
Copy link
Contributor Author

digitalf0x commented Jul 8, 2024

This pull request now depends on switching to FreeSimpleGUI, which should be reviewed separately.

EDIT: The above was merged!

Set range of intensity spinboxes to 0-100 via range(0, 101).

Python treats range(0, 5) as [0, 1, 2, 3, 4], verifiable with...
> [num for num in range(0, 5)]

This fixes the maximum strength being limited to 99%.
Support the Tundra Tracker (Haptic Tundrakes?) via…

1.  Microseconds instead of milliseconds for "triggerHapticPulse()"

Scale up from milliseconds via a time-based multiplier for the legacy,
deprecated "triggerHapticPulse()" method.

Set Tundra Trackers back to a multiplier of 1.0 elsewhere, matching
the behavior of Vive Trackers.

This could be replaced with support for the IVRInput system instead of
using the deprecated triggerHapticPulse() function.

2.  Limit pulse length to 4000 µs / 4 ms

Tundra Trackers have a limit of around 4000 µs (4 ms) per pulse, so
the update loop must run more frequently to stay within that maximum
duration for a single pulse.

Queue a time-based forced pulse and warn once if attempting to send a
haptic pulse exceeding the max pulse length for the tracker (if set).

Usually this shouldn't happen - strength values of up to 100% would
result in pulses scaled up to the pulse limit.  However, there are two
notable cases:
A.  "Identify" button triggers a 500 ms pulse
B.  Velocity calculation can result in a strength that exceeds 1.0

This should (hopefully) match the Vive Tracker behavior.

NOTE: Velocity calculation currently appears to do almost nothing with
Tundra Trackers unless the multiplier is set to around 50, which then
breaks normal Proximity and Identify-button haptics pulses.

Tested setup:
* 4x pancake vibration motors
   Thinner than LRAs shipped with Tundra IO Boards, fits in stock base

* 4x Tundra Trackers
   Left/right foot, waist, chest

* Default multiplier, default strengths
   Also tested Velocity strength set to 60% - 100%

* Proximity and Velocity set to "Linear" pattern
   "Throb" works too, but feels a bit weak
@digitalf0x digitalf0x changed the title [WIP] [Update] Support Tundra Tracker quirks [Update] Support Tundra Tracker quirks Aug 9, 2024
@digitalf0x digitalf0x marked this pull request as ready for review August 9, 2024 22:05
@Z4urce Z4urce merged commit 456a1ab into Z4urce:main Aug 14, 2024
2 checks passed
@digitalf0x digitalf0x deleted the wip-ft-haptic-tundrakes branch August 14, 2024 21:52
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

Successfully merging this pull request may close these issues.

2 participants