Skip to content

Conversation

@M1DNYT3
Copy link

@M1DNYT3 M1DNYT3 commented Jan 2, 2026

Natural Locomotion (NaLo) has been able to enumerate and identify SlimeVR trackers via SteamVR for quite some time.
The primary reason SlimeVR trackers were not usable by NaLo was that the OpenVR driver explicitly reported zero velocity and acceleration for all trackers.

Newly added code derives velocity and acceleration from per-frame positional deltas and reports these values to SteamVR using the expected OpenVR kinematic fields.
Switched to server-side calculation, the new driver-side code adds a new definition to ProtobufMessages (Velocity Vector3: vx, vy, vz), and sends this data to SteamVR Virtual Trackers in the same package with Position and Rotation. This adds new functionality while keeping the code architecture and code style the same. Velocity is optional, and if not received, will always report 0 to SteamVR Trackers, basically, falling back to the current behaviour.

This change does not affect positional tracking, as the derived kinematic data is only consumed by SteamVR addons and is not used for pose estimation.
This does affect SteamVR's pose prediction. Cannot be fixed by design. Proposed solution: Make feature toggleable and customizable to allow users decide how they want to use this feature.
I managed to locate the perfect source of positional data on the server and provide velocity updates with a matching polling rate. This has significantly reduced the jitter that was previously caused by overprediction. Currently, the jitter is either small or non-existent.
However, the feature will still be toggleable and allow for some additional customization to improve compatibility.

Doing so allows NaLo to receive the data that was missing, while the only dependency is the position data we receive from the tracker. Because the implementation relies solely on positional data already provided by the tracker, the change is cross-hardware compatible and does not depend on IMU-specific data.

The additional computation is trivial for modern CPUs and is not expected to introduce measurable performance or latency impact. Observed per-frame processing time is on the order of a few milliseconds.

The implementation includes velocity clamping to suppress unrealistic spikes (e.g., sustained speeds above 6 m/s), as well as a delta-time guard to handle stale or invalid frame intervals and avoid division-by-zero or incorrect updates.
Removed due to server-side data being more stable and filtered.

Directional movement (e.g., strafing with the head facing forward) is handled correctly by SteamVR based on the reported kinematic data, requiring no additional logic in the OpenVR driver.

Related to the issue:
SlimeVR/SlimeVR-Server#25

@M1DNYT3
Copy link
Author

M1DNYT3 commented Jan 5, 2026

Found issue:
SteamVR uses Velocity for pose prediction. The nature of SlimeVR Trackers differs from that of Vive Trackers, so the data we calculate is not as accurate as that from Vive. With that in mind, titles that use Prediction from SteamVR (BeatSaber, VRChat) tend to overshoot and cause extra jitter in body movement.

Resolution:
There's no way to make the velocity as accurate as Vive's, but dropping the velocity will never allow us to support Natural Locomotion (unless they stop relying on Velocity). The solution: Power to the User. The Velocity will become a toggleable setting in the GUI with its own customizable settings, alongside all the necessary warnings and tooltips. This should allow all users to find the right spot for their use case of interest.

Server-side logic and GUI change will be added in a separate PR to the server repo (will reference it when it is created).

This PR will also be modified, as the driver-side logic will now simply take Velocity from ProtobufMessage and deliver it to SteamVR as is. This implementation will also be cleaner and follow the current architecture of both the server and the driver.

@M1DNYT3 M1DNYT3 changed the title Added support for Natural Locomotion App. Added optional Velocity fields to Protobuf Position Message (Natural Locomotion Support) Jan 5, 2026
@M1DNYT3 M1DNYT3 force-pushed the nalo-velocity-support branch from da988e3 to 41663fb Compare January 6, 2026 08:25
@M1DNYT3
Copy link
Author

M1DNYT3 commented Jan 12, 2026

A little update regarding the issue with overprediction.

While working on the server's code, I changed the source of positional data and implemented velocity calculation based on the final position written in the trackers, instead of taking a position used for the ProtobufMessage. This ultimately created a much more accurate velocity calculation with the polling rate as high as for position updates. Jitter has been reduced significantly to a point where it's not that obvious if you're not specifically looking for it.

No change in code required on the driver's end. However, the ability to toggle and configure velocity settings will still be present in the server app in case velocity may cause other issues.

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.

1 participant