0
\$\begingroup\$

I want to convert rotations given as quaternion from sensors to Unity. The sensors (documentation here) axis are the following ones:

sensor axis

Unity is the following one: Unity axis

I don't know how to map axis other than Z is up for the axis. Note that I don't really mind if I have a global rotation offset. I just want the sensors (they are multiple ones) relative orientation to be the same in Unity that in real life

Given this other answer I think the following code should to the transformation:

Quaternion ConvertToUnity(Quaternion input) {
    return new Quaternion(
        -input.y,
        -input.z,
        -input.x,
        input.w
    );
}

Is that correct?

\$\endgroup\$
2
  • \$\begingroup\$ "Is that correct?" Well, when you use that code, do you get the rotation you expect? If not, precisely how does it differ from what you expect? \$\endgroup\$
    – DMGregory
    Commented Apr 30, 2020 at 16:00
  • \$\begingroup\$ Well I cannot test easily. I don't have access to a single sensor to play around with it. They are embedded into a suit and I try to replay data of a person wearing that suit into a humanoid character. There can be other source of errors (I cannot verify how the sensors are mounted into the suit, There are rotations offset to match my 3D model to the suit (different default orientation for body parts, etc..). This is why I want to validate the maths as a first step. \$\endgroup\$
    – codec-abc
    Commented Apr 30, 2020 at 16:06

1 Answer 1

0
\$\begingroup\$

Summarizing the diagram:

Attribute      Unity Coordinates     Sensor Coordinates
-------------------------------------------------------
Right                 +X                   -Y
Up                    +Y                   +Z
Forward               +Z                   +X
Handedness        Left Handed          Right Handed

So to convert to Unity...

  • Unity's x axis should use the sensor's y axis, negated
  • Unity's y axis should use the sensor's z axis
  • Unity's z axis should use the sensor's x axis
  • ...and since we're changing handedness, we need to negate the angle, which means negating all imaginary components of the quaternion and leaving the real part w unchanged.

So you were close, you just missed the double-flip of the sign on the first argument:

Quaternion ConvertToUnity(Quaternion sensorQuaternion) {
    return new Quaternion(
         sensorQuaternion.y, // -1 * (   Right = -Left    )
        -sensorQuaternion.z, // -1 * (      Up =  Up      )
        -sensorQuaternion.x, // -1 * ( Forward =  Forward )
         sensorQuaternion.w
    );
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .