3
\$\begingroup\$

I have a quaternion from an IMU that id like to represent in unity. The issue is that the sensor uses a right handed coordinate system while unity uses a left handed coordinate system. In order to have the rotations of the IMU reflect in unity correctly, I would need to remap the axis. How can I do this by altering the quaternion components?

Specifically, I would need to map

         sensor   unity
forward  x        z
up       z        y
right    -y       x

I have seen multiple questions regarding this question especially this one.

Convert quaternion to a different coordinate system

However, it only explains a specific case where its a right hand to right hand remapping.

If possible, include an explanation without mathematics equations of how you would map any coordinate system to any other coordinate system.

\$\endgroup\$
0

1 Answer 1

7
\$\begingroup\$

A quaternion can be thought of as an angle-axis representation:

quaternion.xyz = sin(angle/2) * axis.xyz
quaternion.w = cos(angle/2)

So, converting them between two coordinate systems can be broken down into two steps:

  1. Map the axis into the new coordinate system.

  2. If changing between left & right hand coordinates (i.e. if there's an odd number of axis negations or axis exchanges between the two), negate the angle.

    Since cos(-angle) = cos(angle) and sin(-angle) = -sin(angle) this is the same as flipping the axis of rotation, negating the x, y, and z parts.

Taking your specific example:

         sensor   unity
forward    x        z
up         z        y
right     -y        x

To map between these, we need to swap pairs of axes twice (x swaps with z, then y swaps with z) and negate once on y, so that's an odd number of flips, meaning we've changed handedness and will need to negate our angle.

Another way to see this is that if you can take your right hand and point your thumb forward (x), your index finger left (-y), and your middle finger up (z), so this sensor coordinate system is right-handed. To do that with Unity, we'd need to use our left hand to point the thumb right (x), index up (y), and middle forward (z).

We can combine axis remapping and negation steps into:

Quaternion ConvertToUnity(Quaternion input) {
    return new Quaternion(
         input.y,   // -(  right = -left  )
        -input.z,   // -(     up =  up     )
        -input.x,   // -(forward =  forward)
         input.w
    );
}
\$\endgroup\$
2
  • \$\begingroup\$ So to simplify, remapping the axis is basically remapping the xyz components and inverting them if changing between system. Am I to say that with the property of cos, the w component will never change regardless of what you are remapping to? \$\endgroup\$
    – DarkDestry
    Apr 28, 2018 at 15:15
  • \$\begingroup\$ Yes, that's exactly right. \$\endgroup\$
    – DMGregory
    Apr 28, 2018 at 15:16

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