Conversion between quaternions and Euler angles: Difference between revisions

Content deleted Content added
m Added ref general conversion
Replaced formulas and algorithm with an equivalent one that has less numerical problems
Line 189:
 
A direct formula for the conversion from a quaternion to Euler angles in any of the 12 possible sequences exists<ref>{{cite journal |last1=Bernardes |first1=Evandro |last2=Viollet |first2=Stéphane |title=Quaternion to Euler angles conversion: A direct, general and computationally efficient method |journal=PLOS ONE |date=10 November 2022 |volume=17 |issue=11 |pages=e0276302 |doi=10.1371/journal.pone.0276302 |url=https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0276302 |language=en |issn=1932-6203}}</ref>. For the rest of this section, the formula for the sequence '''Body 3-2-1''' will be shown.
TheIf the quaternion is properly '''normalized''', the Euler angles can be obtained from the quaternions via the relations:<ref>{{cite journal|last1=Blanco|first1=Jose-Luis|title=A tutorial on se (3) transformation parameterizations and on-manifold optimization|journal=University of Malaga, Tech. Rep|date=2010|citeseerx=10.1.1.468.5407}}</ref>
 
:<math>\begin{bmatrix}
Line 195:
\end{bmatrix} =
\begin{bmatrix}
\mbox{arctan} \fracleft(\dfrac {2(q_0 q_1 + q_2 q_3)} {1 - 2(q_1^2 + q_2^2)} \right)\\
2 \, \mbox{arcsinarctan} (\sqrt{\dfrac {1 + 2(q_0 q_2 - q_1 q_3)} {1 - 2(q_0 q_2 - q_1 q_3))}} - \pi/2 \\
\mbox{arctan} \fracleft(\dfrac {2(q_0 q_3 + q_1 q_2)} {1 - 2(q_2^2 + q_3^2)}\right)
\end{bmatrix} </math>
 
Note, however, that the [[arctan]], [[arcsin]] and [[arcsinarccos]] functions implemented in computer languages only produce results between −π/2 and [[right angle|π/2]], and for three rotations between −π/2 and π/2 one does not obtain all possible orientations. To generate all the orientations one needs to replace the arctan functions in computer code by [[atan2]]:
 
Moreover, typical implementations of [[arcsin]] and [[arccos]], also might have some numerical disadvantages near zero and one. Besides having these problems, some implementations use the equivalent expression<ref>{{cite journal|last1=Blanco|first1=Jose-Luis|title=A tutorial on se (3) transformation parameterizations and on-manifold optimization|journal=University of Malaga, Tech. Rep|date=2010|citeseerx=10.1.1.468.5407}}</ref>:
:<math> \theta = \mbox{arcsin} (2(q_0 q_2 - q_3 q_1)) </math>
 
To safely generate all the orientations one needs to replace the arctan functions in computer code by [[atan2]]:
 
:<math>\begin{bmatrix}
Line 206 ⟶ 211:
\end{bmatrix} =
\begin{bmatrix}
\mbox{atan2} \left(2(q_0 q_1 + q_2 q_3),1 - 2(q_1^2 + q_2^2)\right) \\
2 \, \mbox{asinatan2} \left(\sqrt{1 + 2(q_0 q_2 - q_1 q_3)}, \sqrt{1 - 2(q_0 q_2 - q_1 q_3)}\right) - \pi/2 \\
\mbox{atan2} \left(2(q_0 q_3 + q_1 q_2),1 - 2(q_2^2 + q_3^2)\right)
\end{bmatrix} </math>
 
Line 226 ⟶ 231:
};
 
// this implementation assumes normalized quaternion
EulerAngles ToEulerAngles(Quaternion qq_input) {
EulerAngles angles;
 
Line 235 ⟶ 241:
 
// pitch (y-axis rotation)
double sinp = std::sqrt(1 + 2 * (q.w * q.yx - q.zy * q.xz));
ifdouble cosp = (std::abssqrt(sinp)1 >=- 12 * (q.w * q.x - q.y * q.z));
angles.pitch = 2 * std::copysignatan2(M_PI / 2sinp, sinpcosp); //- useM_PI 90/ degrees if out of range2;
else
angles.pitch = std::asin(sinp);
 
// yaw (z-axis rotation)