OpenVR-InputEmulator icon indicating copy to clipboard operation
OpenVR-InputEmulator copied to clipboard

Add support for motion cancellation

Open noorbeast opened this issue 8 years ago • 125 comments

Motion and VR compliment each other perfectly and with quality peripherals, transducers and sound are about the ultimate seated experience.

Unfortunately the lack of a generic motion cancellation solution, subtracting the rig movement from the HMD, is the real gap, particularly for large axis movement sims: https://www.xsimulator.net/community/threads/latest-oculus-update-totally-screwed-my-tracking.9917/

It would be easy to mount VR controllers to a motion rig and have instant tracking, as they are not really needed for anything else. But there needs to be a generic way to offset the rig motion from the HMD.

The motion community would be most interested in and really grateful for a motion cancellation solution and extending the OpenVR-InputEmulator project would seem a logical possibility.

You would find plenty of willing testers with VR and 2-6+DOF motion simulators at xsimulator.net.

noorbeast avatar Apr 07 '17 00:04 noorbeast

It's on my to-do list and will be included in the next version.

matzman666 avatar Apr 08 '17 11:04 matzman666

Awesome news...instant hero status with the VR motion sim community!

noorbeast avatar Apr 08 '17 11:04 noorbeast

I am currently implementing that feature. And while doing so some question came up. I suppose motion cancelation should affect both rotation and translation? What is the supposed origin I should use to apply any corrective rotation? How does this usually supposed to work with motion platforms?

matzman666 avatar Apr 27 '17 19:04 matzman666

I am excited to hear that and very much look forward to trying your work out.

SimTools presumes a default for axis/force settings: https://www.xsimulator.net/community/faq/which-way-to-set-simtool-axis-movements.230/

How those are used for actual motion control depends on the simulator design.

A simple 2DOF has a universal joint under the seat which allows movement for roll and pitch, but that is also used for surge, sway and heave by manipulating the settings. Traction loss is a popular addition which allows side ways movement at the rear of 100-200mm each way from center. Actual surge is a bit rarer but allows a similar amount of forward and back movement.

Other designs of 3-6DOF tend to have a higher point for movement around the chest. The amount of movement depends on the actual design but includes pitch, roll, sway, surge, yaw and heave.

360 degree sims are pretty rare but do exist and can include pitch, roll and yaw axis movements.

So yes motion cancellation should affect both rotation and translation.

noorbeast avatar Apr 28 '17 00:04 noorbeast

I released the first version with motion compensation support. It works by attaching a controller/tracker on the motion platform, and then setting the center of the motion platform in the dashboard overlay. It's large untested because I don't have a motion platform, so it may not work at all or be buggy.

matzman666 avatar May 05 '17 21:05 matzman666

I deeply appreciate your efforts.

I have asked for VR motion sim owners with a diverse range of rigs to test and report back here: https://www.xsimulator.net/community/threads/vr-motion-cancellation-time-to-test.10241/

noorbeast avatar May 06 '17 01:05 noorbeast

Hi there matzman666 !!

I have the motion cancellation up and running at seems to work fine when sat on my chair moving the Touch controller around :)
I have now attached the controller to my 6DOF motion platform and when I start a game the motion cancellation stops working, I presume because I am using a CV1 ?

edit: Sorry I didn't even thank you for your awesome work :D I have not been able to use my sim for 2 months because of Oculus stupid runtime updates

SilentChill avatar May 06 '17 19:05 SilentChill

when I start a game the motion cancellation stops working

Does the game your are starting directly use the Oculus SDK, or is it a SteamVR game? Due to the nature of the hack it only works with SteamVR games, not with Oculus SDK games. I tried several SteamVR games (some using the standing universe, some using the seated universe, to cover all cases) and it's basically working in all of them on my system.

I presume because I am using a CV1

As long as you are running SteamVR games it should not matter whether you are using the Vive or the Rift.

matzman666 avatar May 07 '17 13:05 matzman666

Ahh I only tried Dirt Rally and although its through steam it uses the OculusSDK as does Assetto Corsa :( , I will give pCars a try and see if that works.

Is there anyway you can port it into the Oculus side of it ? I have no idea how it works or even if you could

SilentChill avatar May 07 '17 17:05 SilentChill

I have tried running pCars from steam in SteamVR and once the starts the motion cancellation stops and when I exit the game the motion cancellation starts working again.

Is there something I should be doing because I'm using the CV1 seems its just cancelling it out ?

SilentChill avatar May 07 '17 19:05 SilentChill

I suppose Project Cars uses the Oculus SDK on your System. Does the SteamVR dashboard show up when you are in Project Cars and press the Home button? I had a look at the start options that pop up when you right click on Project Cars in Steam, and apparently there is no noticeable difference between the SteamVR and Oculus SDK start option, both start the game with the same parameters. They seem to have no purpose.

On my system motion compensation is working in Project Cars, but I'm using it with a Vive so it has no other option as to run with SteamVR.

Is there anyway you can port it into the Oculus side of it ?

Not possible for several reasons: (1) I don't own a Rift, (2) there is no documentation so I would need to reengineer the runtime, and (3) the Oculus terms of service do not allow it.

matzman666 avatar May 07 '17 20:05 matzman666

No steam dashboard whilst in game unfortunately :(

Looks like Oculus is a no go then, bit of a downer as it does it work really well in the dashboard. Those Vive users are gonna be happy though

Thanks again for your efforts.

SilentChill avatar May 08 '17 08:05 SilentChill

You could try Revive. It maps all Oculus SDK calls to SteamVR calls regardless of what headset is used, so theoretically it should also work with the Rift.

matzman666 avatar May 08 '17 09:05 matzman666

Hi, I've been following the discussion regarding motion cancellation and am working on my own motion rig. If this project is successful I will be using my Vive system. THANK YOU for doing this. Without this driver the VR motion rig would not be workable. Now to my question: When determining the offset to use why not grab the coordinates of the headset and determine the offset? Basically have the driver in the seated position, facing forward, and calibrate the offset based on the distance between the headset and the rig mounted controller. This is much like what games use now to calibrate the seating position. This method should also allow the controller to be mounted anywhere on the rig.

imagebuff avatar May 08 '17 17:05 imagebuff

Using the distance from the headset to the mounted controller/tracker to calculate the offset used for motion compensation is not a good idea . The headset does not represent the center point around which the motion platform rotates (is center point actually the right name, or is pivot point a better term, if anyone knows please tell me, would be good to know so that I get the terminology right in the documentation), therefore any calculated offsets would be wrong most of the time.

It's better to use the center point (or pivot point), which is exactly what I am doing (you need to enter it in the dashboard overlay). You can already mount the controller/tracker wherever you want on the motion platform, and it should (theoretically) calculate the correct offset. However, due to not owning a motion platform I wasn't able to verify whether my calculations do what they are supposed to do. That's why I need people with motion platforms to test it for me.

It may also be a good idea that I document the math used behind my motion compensation solution somewhere public so that other people can check it for errors or come up with optimizations. Will do that in the next days.

matzman666 avatar May 09 '17 14:05 matzman666

This is the beauty of using the separate tracker as opposed to making calculations based on a pivot point. You don’t need to know anything about the rig when you have a tracker. In fact using a pivot point as part of your calculations is a really bad idea as some motion rigs don’t have a single pivot point (the one I’m buying included). As long as you know the initial x,y,z position in space of the rig tracker, it's initial roll,pitch,yaw angle and the initial x,y,z position in space of the headset you can calculate the offset needed to reposition the headset to compensate for the rig movement. All you need to know is the distance and 3D vector to the HMD when you calibrate. The only reason to know the pivot point is if your NOT using a tracker but compensating based on known rig movement. This is exactly how the software for the next level racing rig works... you have to input the measurement between your head and the ball joint under the seat ... no tracker.

imagebuff avatar May 09 '17 16:05 imagebuff

Lol, you are absolutely right. Here I am solving complicated equations, while the real solution is simple and beautiful. Sigh, sometimes I just cannot see the obvious.

And you don't even need the initial position of the headset. You just need the rotation offset of the tracker relative to its initial orientation and the distance vector from the current tracker position to the current headset position, then you can rotate the distance vector to compensate the rotation offset and you add the compensated distance vector to the initial tracker position, and voilà you have the compensated headset position. Simple and beautiful.

It's not that my solution produces a wrong result (assuming a single rotation center), but it's unnecessarily complicated and requires more a-priori knowledge than your solution.

matzman666 avatar May 09 '17 16:05 matzman666

Haha... yeah I do that kind of stuff all the time. You will definitely need the initial distance to the headset during calibration and use that for your offset. You can't use the "current" distance between the tracker and HMD for the compensation or you will cancel out the actual headset movement of the user as well as the rig movement. You only want to compensate using the initial distance.

imagebuff avatar May 09 '17 17:05 imagebuff

Ok got it working in revive and initial test is frikkin good !!!!

Just need to secure my controller better as it keeps moving and throwing the screen off a little.

Report back in a bit, with a video as well hopefully

SilentChill avatar May 09 '17 17:05 SilentChill

Ok got it working in revive and initial test is frikkin good !!!!

That's good to hear!

You will definitely need the initial distance to the headset during calibration and use that for your offset.

What am I missing here?

We know the current tracker position T and its orientation QT, the current headset position H and its orientation QH, and the initial tracker position T0 and its orientation QT0. And what we want to get is the motion compensated headset position H' and its orientation Q'H.

motionplatform svg

To get H' I just need to rotate the distance vector between T and H by the difference QT0 - QT, and then add the resulting vector to T0. Then I should be exactly at H'. And to get the motion compensated headset orientation Q'H, I just need to rotate QH by the difference QT0 - QT.

I don't understand where I need the initial headset position here?

matzman666 avatar May 09 '17 20:05 matzman666

Hi back again it works brilliantly dude :) No tracking jumps, judder or anything and I was getting thrown around quite a bit.

Only little observation that was a bit off putting is the sides of the screens flickering where the compensation is a bit too much and the edges of the screen come into view, I presume that's because I have not got the Touch Controller attached exactly where my head is, its attached behind my head at the same level as the rift on my face.

Is there a way to lower the compensation to stop that happening ? Or do I put a offset in from the controller to my rift ?

Looky here https://youtu.be/G46rTN69IVM

SilentChill avatar May 09 '17 20:05 SilentChill

ah hah! Eureka... yes I believe I understand. Thanks very much for the diagram. Your right you shouldn't need any calibration as long as it always holds true that there is never a need to compensate for the distance between T and H (the tracker and HMD). Now that I think further about it I can't come up with a reason this distance would need to be compensated. Perfect, simple, and elegant. Let me know when your able to code it up this way and I can run some tests on the Vive even though I don't have a true motion rig yet. It is on wheels so I can do some "manual" testing. So I'm curious how your accomplishing this generically. Your wedging yourself between the incoming sensor stream and the application? Thanks again!

Chris

imagebuff avatar May 09 '17 21:05 imagebuff

Hi again,

So I got the coordinates of where my HMD is and I have added an offset from where the HMD is to my controller to the "DriverfromHead" offset is this correct or am I getting it all wrong ? Should I be setting an offset for "DriverOffset" this is just to compensate for the extra movement that the controller is getting because its further back so it pitches slightly more and it yaw's slightly more. Surge and Sway seem spot on

SilentChill avatar May 10 '17 06:05 SilentChill

@SilentChill

Looky here https://youtu.be/G46rTN69IVM

Wow, that's quite a beast of a motion platform. What are the G-forces it can generate?

Only little observation that was a bit off putting is the sides of the screens flickering where the compensation is a bit too much

The motion compensation algorithm is not perfect yet, there's still room for improvements. E.g. I currently only adjust the headset position, but not the reported velocities and accelerations. This can mess up the pose prediction algorithm in the OpenVR runtime. The next step would be to also adjust velocity and acceleration, and see whether this fixes the problem.

I presume that's because I have not got the Touch Controller attached exactly where my head is

The placement of the controller should not matter at all, it should work nonetheless.

So I got the coordinates of where my HMD is and I have added an offset from where the HMD is to my controller to the "DriverfromHead" offset is this correct or am I getting it all wrong ?

The "device offsets" have nothing to do with motion compensation, you should not set any of them. And there is also no need to enter any coordinates, the "motion compensation settings" do nothing at all, they are there because of a logical fallacy and will be removed in the next version.

@imagebuff

Let me know when your able to code it up this way.

I will try to release a small update later today or tomorrow with the simpler motion compensation algorithm, and over the weekend I will work on also applying motion compensation to the velocities and acceleration values.

So I'm curious how your accomplishing this generically. Your wedging yourself between the incoming sensor stream and the application?

I intercept the pose updates coming from the driver before they reach the OpenVR runtime. I'm basically wedging between the device drivers and the OpenVR runtime.

matzman666 avatar May 10 '17 16:05 matzman666

Thanks for everything matzman666. I look forward to the update.

imagebuff avatar May 10 '17 16:05 imagebuff

Just reading through this to understand the mechanics of it all. @SilentChill i think the edge flickering you are experiencing might be due to the Revive performance, not this input emulator. What you are referring to sounds like the Oculus SDK timewarp/spacewarp reprojection. Use a performance monitor and see if you are ending up at 45fps with reprojection instead of 90fps. This might help to do that: https://www.reddit.com/r/oculus/comments/4ovn8t/psa_how_to_see_fps_counter_in_cv1_and_other/

SmartCarrion avatar May 10 '17 18:05 SmartCarrion

I released a small update with the improved motion compensation algorithm

matzman666 avatar May 10 '17 20:05 matzman666

@matzman666

Wow, that's quite a beast of a motion platform. What are the G-forces it can generate?

Enough to give me whiplash twice lol, the video really doesn't do it justice as you feel so much and it does fling you side to side.

The placement of the controller should not matter at all, it should work nonetheless.

It does work but the touch will be travelling a greater distance than what my head will be, but if you say its all good I go with you because its all black magic to me haha

Good to know about the offsets I'll stop messing with them. I'll install the update tomorrow and let you know how it is.

@SmartCarrion

Just reading through this to understand the mechanics of it all. @SilentChill i think the edge flickering you are experiencing might be due to the Revive performance, not this input emulator. What you are referring to sounds like the Oculus SDK timewarp/spacewarp reprojection. Use a performance monitor and see if you are ending up at 45fps with reprojection instead of 90fps. This might help to do that: https://www.reddit.com/r/oculus/comments/4ovn8t/psa_how_to_see_fps_counter_in_cv1_and_other/

It doesn't do it all the time only when my rig is making the big movements or stuck at a big angle. I will try what you say though just to be sure, thanks

SilentChill avatar May 10 '17 21:05 SilentChill

I'd also like to express my appreciation for this code! Simply fantastic.

Although just using a controller to work out the offset is a good solution I (and I suspect others) would also appreciate a method for using a simple gyroscope with a pivot point we can set on the simulator. This allows both hands in VR games (oculus doesn't have a tracking puck remember) and is cheaper than a puck or third controller. This only works for 2/3DOF sims, but these are the most common since not everyone is as lucky as SilentChill :)

Also I would appreciate if you could add the ability to change the offsets via the commandline. My sim tilts the user backwards about 30 degrees into the seat as the 'zero position', but it would be great to slowly increase the offset so the user doesn't notice this as much... this can be automated if it works via the CLI

traveltrousers avatar May 14 '17 16:05 traveltrousers

I just released version 1.0.3 with velocity/acceleration compensation modes. They are largely untested due to me not owning a motion platform.

@SilentChill

Enough to give me whiplash twice lol

It doesn't do it all the time only when my rig is making the big movements or stuck at a big angle.

This could be related. Please try the velocity/acceleration compensation modes to see if they fix the problem.

@traveltrousers

I (and I suspect others) would also appreciate a method for using a simple gyroscope with a pivot point we can set on the simulator.

The problem is how to get the gyroscope data into the driver. For me this makes only sense when there is a standardized interface I can use to get the gyroscope data.

Also I would appreciate if you could add the ability to change the offsets via the commandline.

Device offsets are currently not applied to the motion compensation reference tracker/controller, but it is trivial to add. I read your post after releasing v1.0.3, so I can only add it in the next version. However, correctly adding offsets is not that simple. E.g. when the reference controller/tracker is not mounted at the pivot point, any rotation also causes a translation of the reference, which you need to correctly calculate to get the desired effect.

matzman666 avatar May 15 '17 13:05 matzman666