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

Passing angular velocity from OSVR into SteamVR #103

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

mdigkin
Copy link

@mdigkin mdigkin commented Jan 7, 2017

This seems to remove the "ticking" orientation judder when moving your head in SteamVR, but only works when not using one of the positional trackers - perhaps the tracking fusion is not passing through the angular velocity well enough currently, but the IMU certainly seems to be giving good enough data.

@godbyk
Copy link
Contributor

godbyk commented Jan 12, 2017

Providing the angular velocity and acceleration allows SteamVR to enable its tracking prediction which should smooth out the tracking.

I'm in favor of this change. I do want to make sure that the values you're polling correspond to the current pose report and not the next pose report (race condition).

@0x1100
Copy link

0x1100 commented Jan 12, 2017

That really makes sense.
Great job finding the source of this problem, that's extremely helpful!

However, I'm a bit unsure about that. The IMU tracker sends the angular velocity in the same reference frame than the orientation. Does Steam need it in with the HMD as the frame of reference instead?

May someone correct me if I'm wrong but it seems that the videoimufusion plugin doesn't send the angular velocity to the application. If that's so, this fix alone could only fix the judder when not using the camera. Could you give us more information on the tests you performed? Did you test with or without the camera? With what json file?

@mdigkin
Copy link
Author

mdigkin commented Jan 13, 2017

Godbyk : Re the polling corresponding to the current pose report vs the next pose report : the timestamps on the (polled) velocity data are always earlier than that of the PoseReport received in the callback, but this seems to be a prediction thing - about 35ms earlier in the case of /me/head=/org_osvr_filter_videoimufusion/HeadFusion/semantic/fused, or 2 to 3 ms in the case of /me/head=osvr_server_config.renderManager.HDKv2.0.direct.json. In practise, pose reports should be along every few ms, so even if we use an adjacent polled VelocityState (i.e. immediately before or after the PoseReport in te callback), I would hope this would have minimal effect.

0x1100 : Yes, SteamVR seems to want HMD frame angular velocity (and that makes sense with it being a 3-Vector) - this was determined by waggling a Vive around watching the numbers. VRPN transforms the original HMD gyro values, which is what SteamVR wants, into tracking space here, so the new code is reversing that transform.

In testing, the JSON config osvr_server_config.renderManager.HDKv2.0.direct.json, which basically uses the raw OSVRHackerDevKit0 IMU tracker data with no positional tracking, gave smoother orientation tracking with the new code to feed through angular velocities.

The positional tracking (ie videoimufusion), as used by osvr_server_config.renderManager.HDKv2.0.direct.json, does pass angular velocities, but when these are passed on to SteamVR in this way, the orientation tracking is very much not smooth. It seems the angular velocity data passed from the fusion plugin is not suitable, although it is saying "angular velocity is valid" in the VelocityState. Maybe if the angular velocity is not suitable for onward processing it would be better to flag it as invalid in the tracking filter. I've added code to check for this and only pass the angular velocity if it's flagged as valid. A temporary more pragmatic solution might be to check for positional tracking and only pass the angular velocity if positional tracking is not detected.

@0x1100
Copy link

0x1100 commented Jan 13, 2017

Nice. Finally fixing the tracking in Steam is a huge win even if, at first, it's only when not using the camera.

About the videoimufusion plugin, what I meant it that it calls osvrDeviceTrackerSendVelocityTimestamped and osvrDeviceTrackerSendPoseTimestamped but doesn't call osvrDeviceTrackerSendAngularVelocityTimestamped so It doesn't forward the angular velocity itself, even though some underlying VRPN component might take care of it (others will know better than me).

@mdigkin
Copy link
Author

mdigkin commented Jan 13, 2017

The OSVR_VelocityState that the videoimufusion plugin is already sending through osvrDeviceTrackerSendVelocityTimestamped contains both linear and angular velocities together (as described here) along with flags indicating their respective validities. Instrumenting the HmdTrackerCallback I see nonzero angular velocities with valid flags, they just don't seems to be good angular velocities for SteamVR's prediction.

double dt = state.dt;
Eigen::Quaterniond poserotation = osvr::util::fromQuat(report->pose.rotation);
Eigen::Quaterniond angvel_incrementalRotation = osvr::util::fromQuat(velocitystate.angularVelocity.incrementalRotation);
angvel_incrementalRotation = poserotation.inverse() * angvel_incrementalRotation * poserotation;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the intention behind this line? Wouldn't the poserotation.inverse() pre-rotation be eliminated by the poserotation post-rotation?

Copy link

@0x1100 0x1100 Jan 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OSVR gives you the angular velocity in the same reference frame than the HMD's orientation. @mdigkin claims, and I'm willing to believe him, that SteamVR wants the angular velocity using the HMD as the reference frame. The intention here is to have the angular velocity in the reference frame SteamVR expects it to be.

They do not cancel each other because rotation composition is not commutative.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rotation composition is not commutative.

I realize that, but it's just strange to see that line without explanation of the intention.

@godbyk
Copy link
Contributor

godbyk commented Jan 25, 2017

@mdigkin I merged your code in with some other in-progress work. Would you mind reviewing the code in the mdigkin-angularvelocity branch to make sure I didn't break anything when I tweaked the style of your code?

I also added a non-zero time offset for the pose. I'm hoping this will also help improve the predictions that SteamVR makes, but if it causes problems, let me know and I'll remove it for now.

Thanks!

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.

4 participants