Reading and display settings

Appearance

System follows your operating system and keeps following it, even if you change it later. The header's sun, moon and monitor cycle the same three options.

Text size (%) 100%

Default. Scales every text size on the site, equations and tables included.

Reading width 70ch

How much text runs across one line of prose. Narrower is easier to track; wider fits more on screen.

Line spacing 1.6

The leading on body text. Taller leading helps a tired eye stay on the line.

Density

Padding and gaps around controls, cards, and tables — how much breathing room the layout leaves itself.

Motion

System follows your operating system. Reduced removes every transition on this site. Full keeps them on unless your system asks for less.

1

Euler angles and gimbal lock

Three readable numbers, one fatal pose

🎯 Goal: drive a yaw–pitch–roll gimbal into lock, see two of its three axes line up, and measure the lost degree of freedom as a singular matrix.

The aerospace convention writes $R = R_z(\psi)\,R_y(\theta)\,R_x(\phi)$: yaw about the world vertical, then pitch about the new $y$ axis, then roll about the newest $x$ axis. Each angle has a physical meaning, which is why Euler angles are the right choice for displaying an attitude to a person. The trouble is the map from angle rates to body angular velocity:

$$ \omega_b = E(\theta,\phi)\begin{bmatrix}\dot\psi\\ \dot\theta\\ \dot\phi\end{bmatrix}, \qquad E = \begin{bmatrix} -\sin\theta & 0 & 1\\ \cos\theta\sin\phi & \cos\phi & 0\\ \cos\theta\cos\phi & -\sin\phi & 0\end{bmatrix}, \qquad \det E = -\cos\theta. $$

At pitch $\theta = \pm 90^\circ$ the determinant vanishes: the yaw axis and the roll axis point the same way, and the three angle rates can only produce two independent body rotations. That is gimbal lock. Nothing is wrong with the body, which can rotate any way it likes; the coordinates have lost a direction. Near lock, a small, ordinary body rotation needs enormous angle rates, and any filter that integrates Euler angles blows up. Slide pitch toward $90^\circ$ and watch the yaw and roll circles merge while the required rates explode.

yaw axis and circle pitch axis roll axis
2

The rotation vector, revisited

Minimal, nearly singularity-free, and not closed under addition

The rotation vector $\omega = \theta k$ from Part 5 is the Lie-algebra coordinate itself. It has three numbers and is smooth everywhere inside the ball $\lVert\omega\rVert < \pi$. Its one seam is the antipodal gluing at $\lVert\omega\rVert = \pi$. Its weakness is composition: $\operatorname{Exp}(a)\operatorname{Exp}(b) \ne \operatorname{Exp}(a+b)$, and the correction is the BCH series. It is the ideal coordinate for a small quantity, such as an update step, an error, a covariance or a velocity, and a poor one for storing a large orientation that will be composed many times. That split, a large state kept in the group plus a small error kept as a rotation vector, is exactly how modern estimators work (Parts 10–12).

3

Quaternions and the double cover

Four numbers, no singularity, every rotation twice

🎯 Goal: see a unit quaternion as the "half-angle" encoding of a rotation, check that $q$ and $-q$ give the same rotation, and watch a quaternion need $720^\circ$ to return to where it started.

A unit quaternion $q = (w, x, y, z)$ with $w^2+x^2+y^2+z^2 = 1$ is a point on the 3-sphere $S^3$. Rotation by $\theta$ about $k$ is encoded with half the angle:

$$ q = \Bigl(\cos\tfrac\theta2,\ \sin\tfrac\theta2\,k\Bigr), \qquad v' = q\,v\,q^{*}, \qquad q_{AC} = q_{AB}\,q_{BC}. $$

Quaternions are a Lie group in their own right. $S^3$ with the quaternion product is $SU(2)$, the group of $2\times2$ unitary matrices, and its Lie algebra is the same $\mathbb{R}^3$ as $\mathfrak{so}(3)$. The exponential is $\operatorname{Exp}(\omega) = (\cos\tfrac{\lVert\omega\rVert}2, \sin\tfrac{\lVert\omega\rVert}2\tfrac{\omega}{\lVert\omega\rVert})$. The map $q \mapsto R(q)$ is two-to-one, because the half-angle means $q$ and $-q$ produce the same rotation. So $S^3$ double-covers $SO(3)$. That doubling is exactly what removes the seam: $S^3$ has no antipodal gluing, so quaternions can be interpolated, integrated and differentiated with no special cases anywhere.

The demo spins a body steadily about a fixed axis. At $360^\circ$ the body is back where it began, but the quaternion is at $-q_0$; only at $720^\circ$ does it return to $q_0$. The ribbon connecting the body to a fixed base is the classic belt trick. After one turn it holds a twist that no sliding can remove; after two turns the twist can be undone completely. That is the topological fact that loops in $SO(3)$ come in two kinds, and the quaternion keeps track of which.

Left: the body and its ribbon to a fixed base; each slice of the ribbon is oriented along the shortest quaternion path from the base. Right: the four quaternion components over two full turns, with the current angle marked.

4

Interpolating between two orientations

slerp, nlerp and Euler lerp

🎯 Goal: compare three ways of blending two orientations and see which ones follow the geodesic and which move at constant speed.

Blending orientations is needed everywhere: animation keyframes, trajectory smoothing, and timestamp alignment between a camera and an IMU. There are three common recipes:

$$ \text{slerp: } q_0\,(q_0^{*}q_1)^{t}, \qquad \text{nlerp: } \frac{(1-t)q_0 + t q_1}{\lVert\cdot\rVert}, \qquad \text{Euler lerp: } (1-t)\,\mathbf{e}_0 + t\,\mathbf{e}_1. $$

Slerp (spherical linear interpolation) is the geodesic $R_0\operatorname{Exp}(t\operatorname{Log}(R_0^\top R_1))$ written in quaternions. It follows the shortest path at constant angular speed. nlerp follows the same path, because the normalized chord projects onto the same great circle, but it speeds up in the middle. It is cheaper and fine for small gaps. Euler lerp takes a different path entirely, and it can swing wildly when the endpoints are near lock. The traces show where each one sends the body's nose (its $x$ axis), and the plot shows the angular speed along each.

slerp nlerp Euler lerp
5

Quaternion pitfalls: signs, order and drift

What goes wrong in real code

🎯 Goal: see how the $\pm q$ ambiguity silently breaks averaging, and learn the conventions to check when two libraries disagree.

Because $q$ and $-q$ are the same rotation, any operation that treats quaternions as 4-vectors has to be told which sign to use. Averaging is the classic trap. Five noisy measurements of one orientation, where a couple happen to be stored as $-q$, average component-wise to nearly nothing. Aligning signs first (flip any $q_i$ with $q_i\cdot q_1 < 0$) fixes it. The robust method used in attitude estimation (Markley et al.) avoids the problem entirely: the average is the dominant eigenvector of $\sum_i q_iq_i^\top$, and $q q^\top$ is the same for both signs.

Three more conventions to check before trusting a quaternion from someone else's code:

Storage order
Eigen and ROS messages store $(x,y,z,w)$; Sophus, Ceres and most papers write $(w,x,y,z)$. Swapping them gives a valid-looking, wrong rotation.
Hamilton vs JPL
Hamilton's product ($ij = k$) is the default almost everywhere. The JPL convention ($ij = -k$) appears in some aerospace and VIO literature (Trawny & Roumeliotis). Mixing them reverses the order of composition.
Active vs passive
Does $q$ rotate the vector, or the frame the vector is written in? The two differ by a conjugate. Frame subscripts (Part 2) settle it.
Drift
Repeated products slowly leave $\lVert q\rVert = 1$. Renormalize after every composition; unlike re-orthonormalizing a matrix, it costs four multiplications.
6

Choosing a representation

Rotation matrixUnit quaternionRotation vectorEuler angles
Numbers stored9433
Constraint$R^\top R=I$, $\det R=1$$\lVert q\rVert = 1$none (wrap at $\pi$)none (wrap, lock)
Singularitiesnonenone (double cover)at $\lVert\omega\rVert=\pi$gimbal lock at $\theta=\pm90^\circ$
Composematrix product (27 mult.)quaternion product (16 mult.)via BCH / Exp–Logvia matrices
Rotate a vector9 mult.~15–18 mult. (or convert)Rodriguesvia matrices
Interpolatevia Log/Expslerponly when smallpoor
RenormalizeSVD or Gram–Schmidtdivide by the norm——
Best fortransforming many points; claritystate storage, integration, interpolationerrors, steps, covariancesdisplay and human input only

The Lie-group view resolves what could look like a contest. Store the state as a group element (matrix or quaternion, whichever is convenient). Express every small quantity, meaning steps, errors, noise and velocities, as a rotation vector in the tangent space. Move between the two only with Exp and Log. Use Euler angles only at the human interface.

7

Check your understanding

0/5 answered