This is a quick post to better understand the concept of quaternions and its
relation to robotics. The catalyst for this particular post was the use of
`tf::Quaternion`

in a recent ROS implementation, and a self directed question
inquiring whether or not I truly understood and remember the concept of a quaternion. The
answer was no, and is still no, but I can definitely say that I remember more now
than I did the day before.

### Advantages of Quaternions

Quaternions are used to represent rotations and is an alternative to the often referenced Euler angles. Despite the elevated complexity with respect to the learning curve, the benefits warrant the effort. Some benefits cited included: [1]

- Dont have to worry about Gimbal lock a property specific to Euler angles.
- Greater efficiency in terms of memory foot print and computation relative to matrix and angle/axis representation.
- Depends on the use case, but quaternions only contain a rotation as opposed to a translation and scaling.

### What is a Quaternion

Mathematically, a quaternion is represented by a scalar and a vector, \((a_0. \textbf{a})\), and in the expanded form as a linear combination: \[ a = a_0 + a_1i + a_2j + a_3k \]

The scalar component represents the magnitude of the rotation, while the vector component represents the axis of rotation.

### Using Quaternions and related Properties

The quaternion under consideration represents a rotation in 3 dimensions. A property of a rotation in 3 dimensions is that any combination of rotations can be represented by a rotation along a given axis. Thus if we are given two rotations represented by quaternions,\(r\), and \(s\), that are applied to a particular axis represented by \(\textbf{v_1}\), we can get the new representation, \(\textbf{v_2}\) , by considering the following equation: \[\textbf{v_2} = (rs) (0 \ \textbf{v_1})^T(rs)^{-1}\]

Before moving forward, at this point we need to review a few properties related to quaternions to understand what operations are taking place.

- The inverse of a quaternion, \(r^{-1}\) is not as simple as just taking the inverse, but is actually the representations conjugate, which simply means that the vector elements of the quaternion are negated. Thus the quaternion inverse of \((r_0, \textbf{r})\) is equivalent to \(r_0, -\textbf{r})\).
- Multiplication when considering quaternions, is again, not particularly straightforward, in the common sense. Multiplication represents the composition of two rotations, thus \(rs\), actually is representing one rotation followed by another rotation.
- Rotations are not communicative. This means that \(rs \neq sr\), and in words, the order of rotations matters. This can be quickly confirmed using your right hand and applying two rotations in different order.

### Quaternion Multiplication

Now back to the equation \[\textbf{v_2} = (rs) (0 \ \textbf{v_1})^T(rs)^{-1}\]. Obtaining the inverse is somewhat self explained, thus will focus on quaternion multiplication.

If we expand, \(r\), and represent the rotation as a linear combination, we get \[r = r_0 + r_1i + r_2j + r_3k\] and likewise for \(s\) we get \[s = s_0 + s_1i + s_2j + s_3k\]

Before we proceed lets consider the fundamental formula of quaternion algebra discovered by William Rowan Hamilton . For some context this formula just happened to occur to Mr. Hamilton as he was walking along some river. [2] Impressive to say the least. \[ i^2 = j^2 = k^2 = ijk = -1\]

From the fundamental formula we can further derive a few other identies, specifically: \[ i^2 = j^2 = k^2 = -1\] \[ ij = -ji = k\] \[ jk = -kj = i\] \[ ki = -ik = j\]

which can be used along side the associated multiplication table[2]:

Using the identities and the multiplication we can compute the result of \(rs\) as \(n = r \times s = n_0 + n_1i + n_2j + n_3k\) where \[n_0=(r_0s_0−r_1s_1−r_2s_2−r_3s_3)\] \[n_1=(r_0s_1+r_1s_0−r_2s_3+r_3s_2)\] \[n_2=(r_0s_2+r_1s_3+r_2s_0−r_3s_1)\] \[n_3=(r_0s_3−r_1s_2+r_2s_1+r_3s_0)\]

I will refrain from writing out all the computations but the calculations is really as simple as aligning the first rotation along the y-axis of the multiplication table and the second rotation along the x-axis of the multiplication table and applying the identities to simplify.

### Result

Now that we have the inverse and multiplication results in hand, we can simply relay on plain matrix multiplication to compute the new axis, given the original from and two rotations.

### References

- http://stackoverflow.com/questions/1840314/when-do-i-need-to-use-quaternions
- http://mathworld.wolfram.com/Quaternion.html
- https://www.mathworks.com/help/aerotbx/ug/quatmultiply.html