Skip to main content
Up and Coming
March 15, 2015

Working PS Move plugin for UE4; need help coreg with DK2

Update:

The plugin is not done but it's ready for public testing. I made a new thread here.


Hello all,

I recently made a PSMove plugin for UE4 that works in both Windows and OSX. It should work in Linux too with a simple compile of the psmoveapi binaries. The changes I had to make to the psmoveapi and PS3EYEDriver should also help anyone that wants to use the PSMove controllers in Windows or OSX (it's always worked in Linux) outside of UE4.

I need help co-registering the coordinates I get from the psmove (in cm from the camera) with the DK2's coordinate space.

For orientation, the roll and pitch are easy. The PSMove has a magnetometer so it's possible to get its true yaw but to make that useful in game I would also need access the DK2's magnetometer (I've read mixed reports that it even has one). Does anyone have any ideas here? Does it truly have a magnetometer? If so, does anyone know how to access it from within UE4?

If it does not then I'll need to somehow coregister the orientations by relying on the user to somehow point the controller in a specific orientation and pressing a button. I'm not too excited about that option.

For position, I would love it if I could access the DK2's camera's image feed. I could have the users run a quick calibration app that asked them to draw in the air then for each frame I would estimate the PSMove controller's position in 3D space relative to each camera, then create a transformation matrix from PS3Eye coordinates -> DK2 camera coordinates. This matrix could be stored in a data file somewhere (or registry entry) and as long as the cameras don't move relative to each other then it should stay the same. Any ideas on accessing the DK2's images, even outside of a game engine or the SDK?

If I can't access the DK2's camera feed then I'll probably need to touch the PSMove at specific locations on the surface of the DK2 and sample >=4 fiducial locations. I would need accurate dimensions of the DK2 body relative to whatever origin
it uses. Anyone have any experience with this?

Accuracy is important to me. We've all read that accuracy goes a long way to helping with immersion, so I hope that it's important to you too, but it's especially important to me because I'm using the data for research. So I can't really accept calibration methods that simply ask the user to put the controller near where they think it should be in the world and press a button.

    180 replies

    Up and Coming
    June 9, 2015
    Testing a bit more, the lsqr implementation does in fact work, it's just that it's a lot more picky about the number of poses it requires in C# compared to Octave.

    5 poses are enough in Octave to be able to get an identical result to the original matrices, in C# it required at least 20 poses to get something close and 250 poses to get an identical result. I guess it's because Unity is working with float and Octave is working with floating point numbers with a much higher precision.

    Meanwhile, I found out that Math.NET Numerics already has an implementation of the lsqr algorithm, although it isn't called like that, it's simply called Solve() and the results are the same than with the C++ implementation. So I don't need this DLL dependency anymore which is nice.

    3AM here, testing with real data will be for tomorrow.

    And I'll still need to implement the rotation matrix orthogonalization described in the original paper to have something usable in the end.
    Up and Coming
    June 9, 2015
    It works.
    Participant
    June 10, 2015
    "Fredz" wrote:
    It works.


    Congratulations, Fredz! Not sure if it is a breakthrough since there have been setbacks before and I have to admit (again) the math discussion went way over my head, but there are people still reading your updates. ;)

    Now if only we had Unity and UE4 plugins coregistering and easy to use for non-programmers ...
    i7-4790K @4.00 GHz, EVGA GTX 980 SC, 16 GB RAM, Win 8.1 64 Bit
    Up and Coming
    June 10, 2015
    "SputnikKaputtnik" wrote:
    Congratulations, Fredz!

    Thanks. :)

    "SputnikKaputtnik" wrote:
    Not sure if it is a breakthrough since there have been setbacks before and I have to admit (again) the math discussion went way over my head, but there are people still reading your updates. ;)

    What works now is the coregistration of the position of the DK2 and the PS Move, whatever the position and orientation of the PS Eye and DK2 camera. I'll probably post a video shortly to show how it does work.

    To have something usable for both developers and end-users I need to implement the coregistration for the rotation, which I'm not sure yet how it can be done but I've some ideas. Then I'll need to save the transformation matrices that correspond to those registrations and implement a plugin so developers can use it.

    The app I've been working on for the coregistration can mostly be used as-is by non-developers. I just need to add some directives to guide the user and I'll probably add other features like pairing to not have to worry with command-line executables.

    So there is still a bit of work to do, but what looked like the most complex part to me - at least mathematically - is now done.

    "SputnikKaputtnik" wrote:
    Now if only we had Unity and UE4 plugins coregistering and easy to use for non-programmers ...

    I'll continue to concentrate my efforts on Unity, if someone wants some guidance to port that to UE4 feel free to ask.
    bullaleAuthor
    Up and Coming
    June 13, 2015
    Great job Fred :!:

    I'm sorry I've been otherwise occupied. I have a bit of a family medical emergency at the moment.

    If you make a standalone utility that writes the resulting transformations to a simple text file (XML, JSON, or something similar) then I can make my UE4 plugin read that text file.

    Let me know when you have code ready for scrutiny. I'd love to try it out Monday or Tuesday in preparation for an experiment.
    Up and Coming
    June 13, 2015
    Sorry for your family, I hope everything goes fine.

    I'll try to implement rotation registration this week-end, along the lines of what you suggested previously. If I don't get something working I'll push the source for the translation part on Github. If I have time I'll implement saving of an XML file in the .psmoveapi directory containing the transformation matrix.

    Since it should be system wide, instead of using <Drive>:\Users\<Username>\AppData\Roaming\.psmoveapi it should probably be better to use <Drive>:\Users\Default\AppData\Roaming\.psmoveapi or <Drive>:\ProgramData\AppData\Roaming\.psmoveapi. That would also make sense for the other files that are already there, the data is related to the hardware, not the user.

    Also while I was testing my app I remarked that the registration was going bad in two specific cases :
    - when the PS Move had more than a small rotation
    - when the PS Move was at the edge of the camera FOV

    I think the ellipse algorithm is less precise in these cases, probably due to partial occlusion.
    bullaleAuthor
    Up and Coming
    June 13, 2015
    "Fredz" wrote:

    I'll try to implement rotation registration this week-end, along the lines of what you suggested previously. If I don't get something working I'll push the source for the translation part on Github. If I have time I'll implement saving of an XML file in the .psmoveapi directory containing the transformation matrix.

    Do you have any good references as to how to get the true yaw (relative to magnetic north) from the raw sensor values?

    "Fredz" wrote:

    Since it should be system wide, instead of using <Drive>:\Users\<Username>\AppData\Roaming\.psmoveapi it should probably be better to use <Drive>:\Users\Default\AppData\Roaming\.psmoveapi or <Drive>:\ProgramData\AppData\Roaming\.psmoveapi. That would also make sense for the other files that are already there, the data is related to the hardware, not the user.

    I think the reasoning for putting it in the user's directory is that you do not require administrator access to write there, but either works. I think the psmoveapi searches both. The relevant lines of code are around here.

    I realized that I can probably add something to the psmoveapi to read the file and apply the transformation in itself, exposed via something like psmove_getTransformedPose. Is that useful?
    "Fredz" wrote:

    Also while I was testing my app I remarked that the registration was going bad in two specific cases :
    - when the PS Move had more than a small rotation
    - when the PS Move was at the edge of the camera FOV

    I think the ellipse algorithm is less precise in these cases, probably due to partial occlusion.

    Yes, the edge-of-volume issue is a problem with the tracker algorithm not handling the garbage data returned by OpenCV in those cases. I recently (~3 days ago) updated my psmoveapi branch and the psmove-ue4 binaries to simply not update the position if the returned value is NaN; that fixed some errors I was experiencing. I've always intended to implement some error checks in the tracker algorithm but it seemed a bit premature previously. Maybe I should get on that.
    Up and Coming
    June 13, 2015
    "bullale" wrote:
    Do you have any good references as to how to get the true yaw (relative to magnetic north) from the raw sensor values?

    I'm using the corrected sensor values for both the PS Move and the DK2 and I'm doing the sensor fusion in place with the Madgwick algorithm. Looks good for the PS Move (better than the PS Move API implementation even) but the DK2 is quite off. I thought it was because the unit for the gyroscope was not in rad/s but it seems to be the case in the 0.6.0 SDK/runtime.

    Maybe the 0.5.0.1 SDK/runtime I'm using is buggy, the source documentation for this version is obviously wrong, maybe the code is wrong as well (says Gyro acceleration reading in m/s^2 but 0.6.0 says Gyro rotation rate in radians/second).

    Or that could also be related to the lack of magnetometer calibration, no idea if that it's still supported. If not I may have to implement it myself.

    "bullale" wrote:
    I think the reasoning for putting it in the user's directory is that you do not require administrator access to write there, but either works. I think the psmoveapi searches both. The relevant lines of code are around here.

    Thanks, I'll have a look at how to implement this in C#.

    "bullale" wrote:
    I realized that I can probably add something to the psmoveapi to read the file and apply the transformation in itself, exposed via something like psmove_getTransformedPose. Is that useful?

    Yes I guess it's better to do it in the PS Move API so that it can be used from anything. Basically I'll store at least a 4x4 transformation matrix in the XML file. I don't know if the coordinate system handedness needs to be considered and I don't know yet what I will return when/if I handle the rotation.

    "bullale" wrote:
    I recently (~3 days ago) updated my psmoveapi branch and the psmove-ue4 binaries to simply not update the position if the returned value is NaN; that fixed some errors I was experiencing.

    Ah yes I saw that but I didn't understand what it was for. I'm currently using the latest version of your PS Move API fork.
    bullaleAuthor
    Up and Coming
    June 13, 2015
    "Fredz" wrote:

    I thought it was because the unit for the gyroscope was not in rad/s but it seems to be the case in the 0.6.0 SDK/runtime.

    Maybe the 0.5.0.1 SDK/runtime I'm using is buggy, the source documentation for this version is obviously wrong, maybe the code is wrong as well (says Gyro acceleration reading in m/s^2 but 0.6.0 says Gyro rotation rate in radians/second).


    If they truly use different units across SDK versions then that's going to be annoying to support cross-platform. For example, UE4 4.8 uses 0.5.0.1 for Mac and 0.6 for Windows.
    Up and Coming
    June 13, 2015
    I think it was just an error in the comments code. m/s^2 is a unit that should be returned for an accelerometer, not a gyroscope. And for the magnetometer it was specified "rotation rate in rad/s", but it should have been a value in gauss. Most probably the comments were shifted because of a typo somewhere.

    I've modified the initialization parameters for the Madgwick algorithm and now the rotation seems to be correct, but there is a lot of drift. So I think there is no problem with the code and it's only related to the lack of magnetometer calibration.

    Also it seems to me that the returned rotations for the PS Move and the DK2 are not in the same coordinate system, but I don't see how it can be possible using the same algorithm. I'll try to convert them to the Unity coordinate system to be sure, but I still have difficulties to grasp this kind of conversion.