Spatial Algebra

Quaternion

A quaternion is a four-part hypercomplex number used to describe 3D rotations and orientations.

Quaternions are used everywhere. To use this data for localization, you can capture it using a quaternion object, perform mathematical operations on it, or convert it to other rotation formats, such as Euler Angles and Rotation Matrix.

Fundamentals:

IMPORTANT: Not sure if I completely missed this part in the VSLAM book, but

  • important detail because I thought that the orientation was unique

Double Cover Property (Singularity)

Was trying to remind myself why quaternions are better.

Quaternions have singularities in the context of representing orientation, known as the double-cover property. This means that two quaternions can represent the same orientation. Specifically, a quaternion (q) and its negation (-q) represent the same spatial orientation.

So then why are quaternions better if they also have singularities? Because

Notes from Visual SLAM book

Notes start at page 45 (chapter 2.4). A quaternion has a real part and three imaginary parts. We write the real part in the front (and there are also some books where the real part is in the last), like this:

where are three imaginary parts of the quaternion. These three imaginary parts satisfy the following relationship:

\begin{equation} \begin{cases} \begin{array}{l} {i^2} = {j^2} = {k^2} = - 1\\ ij = k, ji = - k \\ jk = i,kj = - i\\ ki = j, ik = - j \end{array} \end{cases} \end{equation}

If we look at as three axes, they look the same as complex numbers when multiplying with themselves. And look the same as the outer product when multiplying with the others.

We can also use a scalar and a vector to express quaternions:

  • If the imaginary part is , it is called real quaternion
  • Conversely, if its real part is , it is called imaginary quaternion.

Rotation with Quaternions

To rotate a point using Rotation Matrix, we know that is . How do we do that with a quaternion?

Let the rotation be specified by a unit quaternion . First, we extend the 3D point to an imaginary quaternion:

We just put the three coordinates into the imaginary part and leave the real part to be zero. Then, the rotated point can be expressed as such a product:

The multiplication here is the quaternion multiplication, and the result is also a quaternion. Finally, we take the imaginary part of and get the coordinates of the point after the rotation.

It can be easily verified (we leave as an exercise here) that the real part of the calculation is 0, so it is a pure imaginary quaternion.

Properties of Quaternions

Quaternions are very similar to complex numbers, and a series of quaternion operations can be performed.

Assume there are two quaternions , whose vectors are represented as , or the original quaternion is expressed as: Then, their operations can be expressed as follows.

  1. Addition and subtraction

  2. Multiplication. Quaternion multiplication is the multiplication of each item of with each item of

The scalar form is a little complicated, but the vector form is more concise:

Note that the product of two real quaternions is still real, which is also consistent with the real number multiplication. NOTE: quaternion multiplication is usually NOT commutative unless and at are parallel, which means the outer product term is zero.

  1. Length. The length of a quaternion is defined as:

It can be verified that the length of the product is the product of the lengths. This makes the unit quaternion keep unit-length when multiplied by another unit quaternion:

  1. Conjugate. The conjugate of a quaternion is to take the imaginary part as the opposite:

We get a real quaternion if the quaternion is multiplied by its conjugate. The real part is the square of its length:

\end{equation}$$ 5. **Inverse**. The inverse of a quaternion is: $$\begin{equation} \mathbf{q} ^ { - 1 } = \mathbf{q} ^ * / \| \mathbf{q} \| ^ 2 \end{equation}$$ According to this definition, the product of the quaternion and its inverse is the real quaternion $\mathbf{1}$ : $$\mathbf{q} \mathbf{q}^{-1} = \mathbf{q}^{-1} \mathbf{q} = \mathbf{1}$$ If $\mathbf{q}$ is a unit quaternion, its inverse and conjugate are the same. So the inverse of the product has properties similar to matrices: $$\begin{equation} \left( \mathbf{q}_a \mathbf{q}_b \right)^{-1} = \mathbf{q}_b^{-1} \mathbf{q}_a^{-1}. \end{equation}
  1. Scalar Multiplication. Similar to vectors, quaternions can be multiplied by numbers:

Quaternion as rotations

If you want to combine the effect of two quaternion rotations, you multiply them, not add them.

Conversion to other Rotation Representations

The math behind this starts getting quite hefty.

Quaternion to Rotation Matrix

Derivation at page 65 of Visual SLAM book.

Let . Then

In Eigen

q.toRotationMatrix();

Quaternion to Axis-Angle

Derivation at page 66 of Visual SLAM book.

Let . Then the conversion formula from quaternion to rotation vector can be written as

In Eigen

Eigen::Vector3d axis = quaternion.axis(); 
double angle = quaternion.angle();
 
AngleAxisd rotation_vector(angle, axis);

Quaternion to Euler Angles

They don’t show it in the book. In Eigen, first convert to rotation matrix

q.toRotationMatrix().eulerAngles(0,1,2);
  • q.eulerAngles(0,1,2) is not a valid function :(

No big deal though, Euler angles are rarely used apart to make it understandable for humans.

Quaternions in Eigen

AngleAxisd rotation_vector(M_PI/4, Vector3d(0,0,1));
Matrix3d rotation_matrix = Matrix3d::Identity();

Initialize a quaternion

// Quaternion (3 different ways)
Quaterniond q(rotation_matrix);  // using a 3x3 rotation matrix
Quaterniond q(rotation_vector); // using euler angles
Quaterniond q(w,x,y,z);  // raw values, where w,x,y,z are doubles

Rotate a vector

Vector3d v(1, 0, 0);
v_rotated =  q * v; // under the hood, it's qvq^{-1}
 
// equal to
v_rotated = q * Quaterniond(0, 1, 0, 0) βˆ— q.inverse()).coeffs().transpose()