Quaternions

Quaternions are often used to describe rotation between arbitrary coordinate frames. As opposed to Euler angles and other rotation descriptions, quaternions do not suffer from singularities and represent an elegant formulation to approximate local linearizations.

Why is this important? you might ask…

Well, in robotics, we often encounter estimation, planning, or control problems of non-linear systems. These problems can often be solved using iterative algorithms or even non-linear optimization. Quaternions allow us to represent rotations in such optimization problems in a mathematically sound, efficient, and elegant way.

Quaternion Formulation

To derive the math behind these elegant little fellas, lets first define our quaternion $q$ in an application-focus form as vectors:

$$ \boldsymbol{q} = \begin{bmatrix} q_w \\ q_x \\ q_y \\ q_z \end{bmatrix} $$

It consists of 4 scalars, of which $[q_x, q_y, q_z]$ are often referred to as the vector component, and $q_w$ is referred to as scalar component. An alternative representation (which is actually often preferred by mathematicians) is to think of it as a 4-dimensional imaginary number:

$$ \boldsymbol{q} = q_w \cdot 1 + q_x \cdot i + q_y \cdot j + q_z \cdot k $$

where &i&, &j&, &k& are orthogonal (mutually perpendicular) roots of -1 used as the basis.

Confused? Don’t worry, if you wanna get to the meat of it, there is an excellent explanation Martin Baker’s page. Otherwise, just carry on here and get the basics without too much imaginary magic.

Inverse and Conjugate

Conjugate

The conjugate of a quaternion is a quaternion of the same magnitude but with a negative vector (imaginary) part. Therefore, its vector part points in the opposite direction, which will become quite useful when dealing with quaternions as rotations.

$$ \begin{aligned} \boldsymbol{q} &= \begin{bmatrix} q_w \\ q_x \\ q_y \\ q_z \end{bmatrix} & \bar{\boldsymbol{q}} &= \begin{bmatrix} q_w \\ -q_x \\ -q_y \\ -q_z \end{bmatrix} = \begin{bmatrix} 1 & \boldsymbol{0}^{1 \times 3} \\
\boldsymbol{0}^{3 \times 3} & -\boldsymbol{I}^{3 \times 3} \end{bmatrix} \boldsymbol{q} \end{aligned} $$

Inverse

The inverse of a quatenrion is a quaternion that represents the inverse operation. Therefore, it has its vector (imaginary) part conjugated but also it’s magnitude inverted, as $|\boldsymbol{q}^{-1}| = |\boldsymbol{q}|^{-1}$.

$$ \begin{aligned} \boldsymbol{q} &= \begin{bmatrix} q_w \\ q_x \\ q_y \\ q_z \end{bmatrix} & \boldsymbol{q}^{-1} &= \frac{1}{|\boldsymbol{q}|} \bar{\boldsymbol{q}} = \frac{1}{|\boldsymbol{q}|} \begin{bmatrix} q_w \\ -q_x \\ -q_y \\ -q_z \end{bmatrix} \end{aligned} $$

Multiplication

Quaternions are multiplicated like complex numbers. A simple way of thinking about quaternion multiplication is to write convert it into a matrix-vector product. We can write a lefthand-side multiplication as matrix $\boldsymbol{Q}_L$ and a righthand-side multiplication as $\boldsymbol{Q}_R$, as below:

$$ \begin{aligned} \boldsymbol{q}_1 \cdot \boldsymbol{q}_2 &= \mathcal{Q}_L(\boldsymbol{q}_1) \boldsymbol{q}_2 = \mathcal{Q}_R(\boldsymbol{q}_2) \boldsymbol{q}_1 \\
\end{aligned} $$

The two matrices $\boldsymbol{Q}_L$ and $\boldsymbol{Q}_R$ can be composed by

$$ \begin{aligned} \mathcal{Q}_L(q) &= \begin{bmatrix} q_w & -q_x & -q_y & -q_z \\
q_x & q_w & -q_z & q_y \\
q_y & q_z & q_w & -q_x \\
q_z & -q_y & q_x & q_w \end{bmatrix} & &= q_w \boldsymbol{I}^{4 \times 4} + \begin{bmatrix} 0 & - \boldsymbol{q}_{vec}^T \\
\boldsymbol{q}_{vec} & \boldsymbol{q}_{vec}^\wedge \end{bmatrix} \\
\end{aligned} $$

and

$$ \begin{aligned} \mathcal{Q}_R(q) &= \begin{bmatrix} q_w & -q_x & -q_y & -q_z \\
q_x & q_w & q_z & -q_y \\
q_y & -q_z & q_w & q_x \\
q_z & q_y & -q_x & q_w \end{bmatrix} & &= q_w \boldsymbol{I}^{4 \times 4} + \begin{bmatrix} 0 & - \boldsymbol{q}_{vec}^T \\
\boldsymbol{q}_{vec} & \boldsymbol{q}_{vec}^{\wedge T} \end{bmatrix} \\
\end{aligned}. $$

Furthermore, the transpose of $\boldsymbol{Q}$ and a quaternions conjugate $\bar{\boldsymbol{q}}$ related to each other by

$$ \begin{aligned} \mathcal{Q}_L(\bar{\boldsymbol{q}}) &= \mathcal{Q}_L^\intercal(\boldsymbol{q}) \\
\mathcal{Q}_R(\bar{\boldsymbol{q}}) &= \mathcal{Q}_R^\intercal(\boldsymbol{q}) \end{aligned}. $$

Quaternion Derivatives

The beauty of this formulation lies in the fact that we can now simply write down the derivatives of these matrix-vector products as the matrix factor.

$$ \begin{aligned} \frac{\delta}{\delta \boldsymbol{q}_1} \mathcal{Q}_L(\boldsymbol{q}_1) \boldsymbol{q}_2 &= \mathcal{Q}_R(\boldsymbol{q}_2) \\
\frac{\delta}{\delta \boldsymbol{q}_2} \mathcal{Q}_L(\boldsymbol{q}_1) \boldsymbol{q}_2 &= \mathcal{Q}_L(\boldsymbol{q}_1) \\
\frac{\delta}{\delta \boldsymbol{q}_1} \mathcal{Q}_R(\boldsymbol{q}_1) \boldsymbol{q}_2 &= \mathcal{Q}_L(\boldsymbol{q}_2) \\
\frac{\delta}{\delta \boldsymbol{q}_2} \mathcal{Q}_R(\boldsymbol{q}_1) \boldsymbol{q}_2 &= \mathcal{Q}_R(\boldsymbol{q}_1) \\
\end{aligned} $$

Furthermore, the derivative of the conjugate can be written by

$$ \begin{aligned} \frac{\delta}{\delta \boldsymbol{q}} \bar{\boldsymbol{q}} &= \frac{\delta}{\delta \boldsymbol{q}} \begin{bmatrix} 1 & \boldsymbol{0}^{1 \times 3} \\
\boldsymbol{0}^{3 \times 3} & -\boldsymbol{I}^{3 \times 3} \end{bmatrix} \boldsymbol{q} = \begin{bmatrix} 1 & \boldsymbol{0}^{1 \times 3} \\
\boldsymbol{0}^{3 \times 3} & -\boldsymbol{I}^{3 \times 3} \end{bmatrix} \end{aligned} $$

Quaternions as Rotation Representations

The most useful application of quaternions is probably its quality to represent orientations and rotations. Since a true rotation does not change the magnitude of a vector, the quaternion must be of unit norm $|\boldsymbol{q}| \overset{!}{=} 1$. Furthermore, a quaternion can be interpreted as rotating a vector around the rotation axis expressed in its vector part $[q_x q_y q_z]$ by an angle corresponding to double its real part $q_w$. The reason for the double angle rotation is that for a rotation, we multiply a vector twice with the quaternion, once from the left and once from the right, but this time by its conjugate.

$$ \begin{aligned} \boldsymbol{q} \otimes \boldsymbol{v} &= \boldsymbol{R}(\boldsymbol{q}) \cdot v \\
&= \boldsymbol{q} \cdot \begin{bmatrix} 0 \\
\boldsymbol{v} \end{bmatrix} \cdot \bar{\boldsymbol{q}} \\
\end{aligned} $$

To represent the inverse rotation $\boldsymbol{R}(\boldsymbol{q})^{-1} = \boldsymbol{R}(\boldsymbol{q})^\intercal = \boldsymbol{R}(\boldsymbol{q}^{-1})$ we can exploit the fact that our rotation quaternion is of unit length and therefore the inverse is the conjugate:

$$ \boldsymbol{q}^{-1} = \bar{\boldsymbol{q}} $$

To concatenate multiple orientations, we can simply multiply the quaternions together. Imagine a rotation from a frame $\mathcal{A}$ into $\mathcal{B}$ as $\boldsymbol{q}_{\mathcal{AB}}$, and a second rotation from frame $\mathcal{B}$ into $\mathcal{C}$ as $\boldsymbol{q}_{\mathcal{BC}}$. The combined rotation $\boldsymbol{q}_{\mathcal{AC}}$ is simply the quaternion product:

$$ \boldsymbol{q}_{\mathcal{AC}} = \boldsymbol{q}_{\mathcal{AB}} \cdot \boldsymbol{q}_{\mathcal{BC}} $$

Transformation into Rotation Matrices

We can also assemble the rotation matrix $\boldsymbol{R}(\boldsymbol{q})$ as

$$ \begin{aligned} \begin{bmatrix} 1 & 0 \\
0 & \boldsymbol{R}(\boldsymbol{q}) \end{bmatrix} &= \mathcal{Q}_L(\boldsymbol{q}) \mathcal{Q}_R(\bar{\boldsymbol{q}}) \\
&= \mathcal{Q}_L(\boldsymbol{q}) \mathcal{Q}_R^\intercal(\boldsymbol{q}) \\
&= \begin{bmatrix} 1 & 0 & 0 & 0 \\
0 & 1 - 2 q_y^2 - 2 q_z^2 & 2 (q_x q_y - q_w q_z) & 2 ( q_w q_y + q_x q_z ) \\
0 & 2 (q_w q_z + q_x q_y) & 1 - 2 q_x^2 - 2 q_z^2 & 2 ( q_y q_z - q_w q_x ) \\
0 & 2 (q_x q_z - q_w q_y) & 2 (q_w q_x + q_y q_z) & 1 - 2 q_x^2 - 2 q_y^2 \\
\end{bmatrix} \\
\end{aligned} $$

Quaternion Rotation Derivative

Additionally, when representing orientations in optimization problems, filters, or even just a robots dynamic equations, one is often interested in it’s derivative, which we will derive in the following section:

$$ \begin{aligned} \frac{\delta}{\delta \boldsymbol{q}} \begin{bmatrix} 1 & 0 \\
0 & \boldsymbol{R}(\boldsymbol{q}) \end{bmatrix} \begin{bmatrix} 0 \\ \boldsymbol{v} \end{bmatrix} &= \frac{\delta}{\delta \boldsymbol{q}} \left( \mathcal{Q}_L(\boldsymbol{q}) \mathcal{Q}_R(\bar{\boldsymbol{q}}) \right) \begin{bmatrix} 0 \\ \boldsymbol{v} \end{bmatrix} \\
&= \frac{\delta}{\delta \boldsymbol{q}} \mathcal{Q}_L(\boldsymbol{q}) \cdot \mathcal{Q}_R(\bar{\boldsymbol{q}}) \begin{bmatrix} 0 \\ \boldsymbol{v} \end{bmatrix} + \mathcal{Q}_L(\boldsymbol{q}) \cdot \frac{\delta}{\delta \boldsymbol{q}} \mathcal{Q}_R(\bar{\boldsymbol{q}}) \begin{bmatrix} 0 \\ \boldsymbol{v} \end{bmatrix} \\
&= \mathcal{Q}_R \left( \mathcal{Q}_R^\intercal(\boldsymbol{q}) \begin{bmatrix} 0 \\
\boldsymbol{v} \end{bmatrix} \right) + q_x \mathcal{Q}_L(\boldsymbol{q}) \cdot \mathcal{Q}_L \left( \begin{bmatrix} 0 \\
\boldsymbol{v} \end{bmatrix} \right) \cdot \begin{bmatrix} 1 & \boldsymbol{0}^{1 \times 3} \\
\boldsymbol{0}^{3 \times 3} & -\boldsymbol{I}^{3 \times 3} \end{bmatrix} \\
\end{aligned} $$

Conclusion

Using the derived formulation, we are now capable of writing, combining, and inverting any rotations by using quaternions. Furthermore, we can take derivatives of quaternion operations and their rotation representations. This proves extremely useful not only when formulating problems in robotics and deriving new concepts, but also when implementing such formulations in code. All operations can be abstracted in matrix-vector products and can easily be implemented with libraries such as Eigen.

Don’t be scare of the imaginary magic… in the end, quaternions will always be the simpler solution.

Next