Converting quaternion to euler without losing information.

631 Views Asked by At

I have a 6DOF sensor outputting a quaternion and I need to convert the quaternion into euler angles. The problem is that when I use the following equations:

$$ \begin{bmatrix} \phi \\ \theta \\ \psi \end{bmatrix} = \begin{bmatrix} Y \\ P \\ R \end{bmatrix} = \begin{bmatrix} \mathrm{atan2}\left( -2q_1q_2 + 2q_0q_3,\; q_0^2 + q_1^2 - q_3^2 - q_2^2 \right) \\ \mathrm{asin}\left( 2q_1q_3 + 2q_0q_2 \right) \\ \mathrm{atan2}\left( -2q_2q_3 + 2q_0q_1,\; q_3^2 - q_2^2 - q_1^2 + q_0^2 \right) \end{bmatrix} $$

The output is limited to +-90 degrees because of the inverse trigonometric functions.

What set of equations should I use to convert quaternion to euler without losing information.

1

There are 1 best solutions below

0
On

Slightly askew-topic, if not off-topic, but let me just give you the comment section of my code for the function whose input is a quaternion and whose output is the corresponding $3\times3$ rotation matrix. The "Notes:" section explains the requisite algebra.

/* ==========================================================================
 * Function:    qmatrix ( QUAT q )
 * Purpose:     returns 3x3 rotation matrix corresponding to quaternion q
 *              ( can just be called as qmatrix(qrotate(axis,theta))
 *                for rotation matrix around axis through theta )
 * --------------------------------------------------------------------------
 * Arguments:   q (I)           QUAT q for which a rotation matrix
 *                              is to be constructed
 * --------------------------------------------------------------------------
 * Returns:     ( double * )    3x3 rotation matrix, stored row-wise
 * --------------------------------------------------------------------------
 * Notes:     o The matrix constructed from input q = q0+q1*i+q2*j+q3*k is:
 *                    (q0²+q1²-q2²-q3²)    2(q1q2-q0q3)     2(q1q3+q0q2)
 *                Q  =   2(q2q1+q0q3)   (q0²-q1²+q2²-q3²)   2(q2q3-q0q1)
 *                       2(q3q1-q0q2)      2(q3q2+q0q1)  (q0²-q1²-q2²+q3²)
 *            o The returned matrix is stored row-wise, i.e., explicitly
 *                --------- first row ----------
 *                qmatrix[0] = (q0²+q1²-q2²-q3²)
 *                       [1] =    2(q1q2-q0q3)
 *                       [2] =    2(q1q3+q0q2)
 *                --------- second row ---------
 *                       [3] =    2(q2q1+q0q3)
 *                       [4] = (q0²-q1²+q2²-q3²)
 *                       [5] =    2(q2q3-q0q1)
 *                --------- third row ----------
 *                       [6] =    2(q3q1-q0q2)
 *                       [7] =    2(q3q2+q0q1)
 *                       [8] = (q0²-q1²-q2²+q3²)
 *            o qmatrix maintains a static buffer of 128 3x3 matrices
 *              returned to the caller one at a time. So you may issue
 *              128 qmatrix() calls and continue using all returned matrices.
 *              The 129th call re-uses the memory used by the 1st call, etc.
 * ======================================================================= */