MichaelJW / DorsalVR

VR interface for PC games
66 stars 7 forks source link

Investigate IMU drifting #7

Closed MichaelJW closed 3 years ago

MichaelJW commented 3 years ago

On more than one occasion (and for more than one user - see #5 and #4) the virtual controller drifts to the side in Dolphin, as if the physical controller is being constantly pulled/turned to the side.

I have only seen this happen once, personally, and I don't know what causes it to be able to reproduce it.

It may be similar to the previous Dolphin issue with D-Pad and analog stick input drift, which was fixed here: https://github.com/dolphin-emu/dolphin/pull/9771

Make sure inputs start from their resting pose instead of 0

First step is to figure out how to reproduce this. Then, work out whether the issue is with the reported XRController movement, the way that's interpreted within DorsalVR (e.g. the IMU code that translates position/rotation to accel/gyro), what gets sent to Dolphin, or the way that Dolphin interprets it.

Jaitsu commented 3 years ago

This seems to happen to me a lot, as much as 1/3-1/2 the time, though I still haven't quite been able to track down a definitive cause; it could be whether the controller is tracking the base stations or not, or if I'm moving the controller at all at the moment DorsalVR or Dolphin launches, etc.

Unless DorsalVR is reinitializing something on its end when Dolphin's Wiimote binding UI is opened, however, I still have a hunch that this has to do with how Dolphin is interpreting the input it gets, as the drift is affected by doing so. Last time it happened, actually, opening that page didn't stop the issue, but it did change the direction and speed of the drift. I actually just found a thread on Dolphin's forums referencing a similar issue, and mentioning the 'Calibration Period' and 'Dead Zone' settings on the Motion Input tab of the Wiimote binding window. Perhaps Dolphin is calibrating at the moment it's launched and recalibrating when that UI is opened? I can do some more testing later to see if changing those settings does anything.

Maybe this could be as simple as feeding Dolphin several seconds of steady/zero gyro readings after it launches, just to make sure it doesn't pick up any movement during that calibration phase? It'd probably be invisible to the user as games take some time after that to launch.

(I promise I'm not stalking this repo, I just happened to check in 6 minutes after you posted this issue)

catcallofcthulhu commented 3 years ago

Would it be possible to use the VR software's built in pointer and send it to dolphin as mouse input?

MichaelJW commented 3 years ago

@Jaitsu Ah, I'm sorry to hear it's so common. I still can't reliably reproduce it here.

Good call re the calibration period - sounds likely. I just published a new release that more or less does what you suggested - please take a look and let me know if it helps: https://github.com/MichaelJW/DorsalVR/releases/tag/v2.0.3

This commit also includes the input debugger but only loads it if there's a debug node in the YAML. It might be worth adding something like this in to see what inputs are being read, if the problem persists.

debug:
  bindings:
    - RH_IMU/accelerometer/x
    - RH_IMU/accelerometer/y
    - RH_IMU/accelerometer/z
    - RH_IMU/gyroscope/x
    - RH_IMU/gyroscope/y
    - RH_IMU/gyroscope/z

@catcallofcthulhu

Would it be possible to use the VR software's built in pointer and send it to dolphin as mouse input?

Good question. It is possible - an earlier version of DorsalVR did use this - but there are complications here too. In particular, if the mouse-style input is enabled, then the tilt of the emulated Wii remote (i.e. motion as if you're turning the remote like a key in a lock) doesn't get used, which is fine in some cases but a real problem in others.

To solve that you need to simulate the tilt separately too, and pretty soon you end up simulating all these different aspects of motion separately rather than just passing the actual motion through, which is messy.

Having said that, I do think it's worth adding this mouse-style input as a separate option, so I'll make another Issue for it :)

catcallofcthulhu commented 3 years ago

@MichaelJW Hmm, this seems like something that should be fairly simple to fix on the dolphin side. I'll look into it.

MichaelJW commented 3 years ago

Hmm, this seems like something that should be fairly simple to fix on the dolphin side. I'll look into it.

I made a hacky proof-of-concept for this a while ago that added IR camera simulation to Dolphin. (Currently Dolphin simulates how the IR camera on the Wii remote "sees" the sensor bar based on how the motion input data says the Wii remote is moving; there's no way to override this, probably because none of the motion controllers that Dolphin's motion support was designed for could actually make use of it. By simulating the IR camera data directly we could improve the accuracy of pointer input without needing to use the Point bindings.)

Here's the PR: https://github.com/dolphin-emu/dolphin/pull/9617. I don't think that build would be compatible with DorsalVR now because it doesn't use the DSU improvements committed to Dolphin since then that DorsalVR now relies on. But as you can see from the discussion, jordan-woyak has a better solution in mind already; once that's implemented in Dolphin I'll support it in DorsalVR. In the meantime I will add support for the Point bindings, though.

MichaelJW commented 3 years ago

Good (?) news - I figured out how to replicate the drifting on my setup. Bad news - this means the latest release didn't fix it! But at least I can investigate it better now and hopefully figure out how to prevent it.

Jaitsu commented 3 years ago

Sorry for the slower responses, been a bit of a busy week - but was going to say, no dice I'm afraid, still getting the drift, and just as unpredictably. First time I tried the new build, the pointer was zooming off to the right, second time it was fine. The input binding screen thing still fixes it. And naturally, now that I'm trying to test for it, I can't make it happen again reliably enough to tell what effect if any changing the deadzone/calibration options has. What was your repro method?

Also, what are you looking for from the debug outputs, by the way? With the controllers at rest, gyroscope is always 0, but the accelerometers have a little bit of jitter - <0.01 or so, but otherwise at rest the values seem consistent with the controller resting in a given position.

Also, should the controller lose tracking, it appears to freeze the readings.

MichaelJW commented 3 years ago

@Jaitsu I took a look at how Dolphin's calibration works today, after you mentioned it, and I think simply setting the calibration period to zero might fix this. I'll give that a go when I'm back at my computer.

MichaelJW commented 3 years ago

Whoops, didn't mean to close this with that commit.

The new release here sets Dolphin's motion input calibration period to 0 seconds. Let's see if this fixes it!

Reasoning: When Dolphin calibrates the gyroscope inputs, it looks at the inputs it's receiving from them and uses those as the "static" input (i.e. it subtracts them from any other inputs received). So, if the controller is rolling to the left when calibration occurs, then holding it completely still (i.e. reporting a roll of zero) after this calibration will result in Dolphin interpreting the input as rolling to the right.

From reading Dolphin's code, I believe there are two points when it calibrates the input:

  1. When the input is steady for more than X seconds (where X is the "calibration period" setting).
  2. When a new motion input is detected.

My guess is that 2 happens when DorsalVR launches Dolphin and - for whatever reason - it's sending an input with slight motion to Dolphin, which causes the drift. When you open the input binding options, maybe it triggers the calibration again automatically, or maybe you tend to hold the controller still for (the default) three second period to trigger calibration directly, which would explain why the drifting stops.

Setting the calibration period to zero disables both calibration triggers, I think, so in theory this should fix the drift. But let's see if it works in practice...

Jaitsu commented 3 years ago

I think that's done the trick! Been testing it a few times (with the controller at rest, and shaking it all over the place through the whole launch from DorsalVR.exe to the game's splash screen) and haven't been able to cause the drift again.

MichaelJW commented 3 years ago

Fantastic! I'll close this issue now and we can always reopen it if it happens again. Thanks again for all your help with this :)