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

Work in Progress: Dead Reckoning - Open for Discussion #160

Closed
ccoenen opened this issue Mar 1, 2015 · 9 comments

Comments

@ccoenen
Copy link
Contributor

commented Mar 1, 2015

I started implementing dead-reckoning, and it is far enough to discuss it with others. It comes with some caveats, though:

  • It only runs on windows (i used windows threads, and windows Sleep(ms), but this can be fixed easily, i think).
  • It frankenstein-patches the example for now (seemed the easiest choice)
  • It drifts HEAVILY
  • It should, at a later point, be cleaned up and probably go into a different file. I put it in psmove.c (for the most part) because, again, it was the easiest place starting out.
  • There's lots of debug output in there and a hardcoded reset, that would not be very good in production use :D

So, here it goes: https://github.com/ccoenen/psmoveapi/tree/dead-reckoning-discuss

I am using a thread with a game-engine like locked framerate. I did this, because many papers on the subject stress how important a constant timer is. Then, i did this series of steps:

As i said, it drifts extremely and is not really usable at the moment. I'm not sure if this can be improved enough to be useful ever.

I'd love to hear everyone's suggestions!

@thp

This comment has been minimized.

Copy link
Owner

commented Mar 1, 2015

Nice! Can you do a pull request, so we can easily commit on it and get it updated and merged eventually? I can help with porting Windows threads to pthreads (OS X / Linux).

@ccoenen

This comment has been minimized.

Copy link
Contributor Author

commented Mar 1, 2015

Yes, sure! I just thought its so raw right now that i'd discuss it first.

@ccoenen

This comment has been minimized.

Copy link
Contributor Author

commented Mar 1, 2015

oh and i should mention that i'm using it with the swapped axes mentioned in #157, but i left this commit out, since it's not actually related to the dead reckoning.

@cboulay

This comment has been minimized.

Copy link
Contributor

commented Mar 2, 2015

I'm excited for this. Some thoughts:

  • If you can, please use pthreads, but only the features that are also supported in pthreads win32.
    • psmoveapi already uses pthreads, and my MSVC-compatible version of psmoveapi substituted in pthreads-win32 without any difficulty.
  • Supposedly Windows' Sleep has terrible temporal resolution. (16 msec by most accounts). There are some higher-resolution alternatives (QueryPerformanceCounter). But it would be great if you could use a cross-platform portable high-resolution timer. Linux and OSX come with high-resolution timers, so it's likely that the Windows version will be wrapped to match their format, rather than vice versa.
  • Instead of sleeping to achieve a specific framerate, can you simply go as fast as possible but use the (high-resolution) measured inter-frame interval in your integration? I'd be interested to know why these papers recommend the constant interval.
  • In your design, allow for positional drift correction using known good values. e.g., a slow-but-accurate camera tracker might run in a separate thread to periodically (e.g., 30 Hz) correct drift.
@ccoenen

This comment has been minimized.

Copy link
Contributor Author

commented Mar 2, 2015

i started out with pthreads (basically, i copied stuff from the LED Thread Code ), but I didn't get it to work. I hope someone with more experience in cross-platform C might step in.

I also didn't bother much, as this was a proof of concept for dead reckoning itself, so quick&dirty was the way to go. It drifts so extremely that i'm not sure if cleaning it up is even worth the hassle. Unless anyone of you believes this can somehow be improved. The more accurate times might help.

(re-)combining it with the camera would probably be ideal, the point behind this was to find out if this could be useful even without a camera.

@cboulay

This comment has been minimized.

Copy link
Contributor

commented Mar 3, 2015

I suppose that depends on your definition of "useful". I doubt these low-cost sensors will ever yield anything that is useful for more than a second. Some applications or games could re-zero often, using some sort of gameplay element, to cut off error accumulation, but I don't think that should go in the API.

I just looked at the code a little closer. You are already using a high-resolution timer to calculate your "diff" value, so that's not the problem. The Sleep call's imprecision will have negative effects if it is truly important to use a locked framerate, though I'm not sure why that is important if you are precisely and accurately measuring the time between loops. I wonder if it's a problem that you calculate the integral using the "diff" value that you measure once at the beginning of the loop, despite having a bunch of code (is fprint slow?) in between its measurement and usage in the integral, and doubly so for its usage in the integral for the second frame.

Even if it is never useful without a camera, it will still be useful with a slow camera, so I think there is value in pursuing this.

Finally, I think your changes to the orientation measures are worthwhile on their own and maybe should be integrated into the API (i.e., not hidden in your dead-reckoning thread). So even if you decide not to pursue dead-reckoning, please consider doing a PR with just those changes. I will use it.

Side thought: I wonder if it is possible to get the magnetometer values off the DK2? This might make it possible to have accurate orientation of the PSMove in the game world without coregistration, and it might also enable accurate position with a single coregistration point (e.g. touch the psmove to the right-middle of the RIFT and press a button)?

@ccoenen

This comment has been minimized.

Copy link
Contributor Author

commented Mar 3, 2015

Regarding the orientation changes, if you're referring to these changes in psmove_orientation.c, i started #157 for that discussion. I wasn't sure if they serve a purpose like that.

As for the orientation / Oculus DK2 question, i'm notifying @cemrich, she's doing amazing work with the DK2, maybe she knows if the raw data is available somewhere.

@cemrich

This comment has been minimized.

Copy link
Contributor

commented Mar 4, 2015

Using the DK2 magnetometer seems like a very good idea. The values are exposed in the oculus-sdk (LibOVR). An older version can be found under https://github.com/benvanik/oculus-sdk/blob/master/LibOVR/Src/OVR_SensorFusion.h

 // Obtain the last magnetometer reading, in Gauss
Vector3f GetMagnetometer() const
{
    Lock::Locker lockScope(Handler.GetHandlerLock());
    return Mag;
}

// Obtain the raw magnetometer reading, in Gauss (uncalibrated!)
Vector3f GetRawMagnetometer() const
{
    Lock::Locker lockScope(Handler.GetHandlerLock());
    return RawMag;
}

However, this seems to be a C++ library. I don't know C and C++ well enough to know if they could (or should) be mixed. As far as I can see, the OVR-CAPI (https://developer.oculus.com/reference/libovr/) does not expose any magnetometer values. But the documentation is not very beginner friendly, so I could have missed something.

@thp

This comment has been minimized.

Copy link
Owner

commented May 25, 2015

Can we move this discussion to #161, so we don't have to places where we talk about this? Much easier to follow if it's done in a single thread :)

@thp thp closed this May 25, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.