Quaternion
A quaternion is a fourpart 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:
 https://docs.ros.org/en/foxy/Tutorials/Intermediate/Tf2/QuaternionFundamentals.html
 Watch this video when you need to by Steven M. Lavalle
 http://www.cs.cmu.edu/afs/cs/academic/class/16741s07/www/lectures/Lecture8.pdf recommended by Raghava
 Also check out this https://eater.net/quaternions, which is an amazing intuitive video
$q=βq_{1}q_{2}q_{3}q_{4}βββR_{4}$
$β£β£qβ£β£=1$
IMPORTANT: Not sure if I completely missed this part in the VSLAM book, but $q=βq$
 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 doublecover 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 $q$ 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:
$q=q_{0}+q_{1}i+q_{2}j+q_{3}k$where $i,j,k$ 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 $i,j,k$ 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: $q=[s,v]_{T},s=q_{0}βR,v=[q_{1},q_{2},q_{3}]_{T}βR_{3}$
 If the imaginary part $v$ is $0$, it is called real quaternion
 Conversely, if its real part $s$ is $0$, it is called imaginary quaternion.
Rotation with Quaternions
To rotate a point $p$ using Rotation Matrix, we know that is $p_{β²}=Rp$. How do we do that with a quaternion?
Let the rotation be specified by a unit quaternion $q$. First, we extend the 3D point to an imaginary quaternion: $p=[0,x,y,z]_{T}=[0,v]_{T}$
We just put the three coordinates into the imaginary part and leave the real part to be zero. Then, the rotated point $p_{β²}$ can be expressed as such a product:
$p_{β²}=qpq_{β1}$
The multiplication here is the quaternion multiplication, and the result is also a quaternion. Finally, we take the imaginary part of $p_{β²}$ 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 $q_{a},q_{b}$, whose vectors are represented as $[s_{a},v_{a}]_{T},[s_{b},v_{b}]_{T}$, or the original quaternion is expressed as: $q_{a}=s_{a}+x_{a}i+y_{a}j+z_{a}k,q_{b}=s_{b}+x_{b}i+y_{b}j+z_{b}k$ Then, their operations can be expressed as follows.

Addition and subtraction $q_{a}Β±q_{b}=[s_{a}Β±s_{b},v_{a}Β±v_{b}]_{T}$

Multiplication. Quaternion multiplication is the multiplication of each item of $q_{a}$ with each item of $q_{b}$
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 $v_{a}$ and $v_{b}$ at $R_{3}$ are parallel, which means the outer product term is zero.
 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 unitlength when multiplied by another unit quaternion:
$β₯q_{a}q_{b}β₯=β₯q_{a}β₯β₯q_{b}β₯$ 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} Scalar Multiplication. Similar to vectors, quaternions can be multiplied by numbers: $kq=[ks,kv]_{T}$
Quaternion as rotations
If you want to combine the effect of two quaternion rotations, you multiply them, not add them.
$q1βq2$
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 $q=[s,v]_{T}$. Then $R=vv_{T}+s_{2}I+2sv_{β§}+(v_{β§})_{2}$
In Eigen
Quaternion to AxisAngle
Derivation at page 66 of Visual SLAM book.
Let $q=βq_{1}q_{2}q_{3}q_{4}βββR_{4}$. Then the conversion formula from quaternion to rotation vector can be written as
${ΞΈ=2arccosq_{0}[n_{x},n_{y},n_{z}]_{T}=[q_{1},q_{2},q_{3}]_{T}/sin2ΞΈββ$
In Eigen
Quaternion to Euler Angles
They donβt show it in the book. In Eigen, first convert to rotation matrix
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
Initialize a quaternion
Rotate a vector