Rigid body motion

A rigid body motion (rigid transformation) preserves distances between all points. In 3D it consists of a rotation and a translation, and the mathematical structures that represent it — SO(3)SO(3) and SE(3)SE(3) — are central to SLAM: a camera pose is an element of SE(3)SE(3).

Rotation Representations

Euler angles. A rotation can be parameterized by three angles (ϕ,θ,ψ)(\phi, \theta, \psi) representing successive rotations about fixed or body axes; the 12 possible conventions (ZYX, XYZ, …) each give different angle sequences. The gimbal lock problem occurs when two rotation axes align, reducing the effective degrees of freedom to 2. Euler angles are intuitive for display but numerically problematic — avoid them for iterative optimization.

Rotation matrices. A rotation matrix satisfies RTR=IR^TR = I and det(R)=+1\det(R) = +1. The set of all such matrices forms the Special Orthogonal Group:

SO(3)={RR3×3RTR=I, det(R)=+1}SO(3) = \{R \in \mathbb{R}^{3\times3} \mid R^TR = I,\ \det(R) = +1\}

Rotation matrices are the preferred representation for computation: matrix multiplication is the composition law, and the inverse is simply the transpose.

Quaternions. A unit quaternion q=w+xi+yj+zkq = w + xi + yj + zk with w2+x2+y2+z2=1w^2+x^2+y^2+z^2 = 1 represents a rotation by angle θ=2arccos(w)\theta = 2\arccos(w) around axis [x,y,z]T/sin(θ/2)[x,y,z]^T/\sin(\theta/2). They are compact (4 numbers vs. 9), have no gimbal lock, and compose via the Hamilton product. Note the double cover: qq and q-q represent the same rotation.

Conversion from quaternion to rotation matrix:

R=[12(y2+z2)2(xywz)2(xz+wy)2(xy+wz)12(x2+z2)2(yzwx)2(xzwy)2(yz+wx)12(x2+y2)]R = \begin{bmatrix} 1 - 2(y^2+z^2) & 2(xy - wz) & 2(xz + wy) \\ 2(xy + wz) & 1 - 2(x^2+z^2) & 2(yz - wx) \\ 2(xz - wy) & 2(yz + wx) & 1 - 2(x^2+y^2) \end{bmatrix}

A quick NumPy sanity check that a matrix is a valid rotation:

import numpy as np
# R is a rotation iff R^T R = I and det(R) = +1
print(np.allclose(R.T @ R, np.eye(3)), np.isclose(np.linalg.det(R), 1.0))

Homogeneous Transformation: TSE(3)T \in SE(3)

A rigid body motion combines rotation RR and translation t\mathbf{t} into one 4×44\times4 matrix acting on homogeneous coordinates:

T=[Rt0T1]SE(3),T[X1]=[RX+t1]T = \begin{bmatrix} R & \mathbf{t} \\ \mathbf{0}^T & 1 \end{bmatrix} \in SE(3), \qquad T\begin{bmatrix}\mathbf{X}\\1\end{bmatrix} = \begin{bmatrix} R\mathbf{X} + \mathbf{t} \\ 1 \end{bmatrix}

Composition is matrix multiplication, with rotation and translation interleaving:

T1T2=[R1R2R1t2+t10T1]T_1 T_2 = \begin{bmatrix} R_1R_2 & R_1\mathbf{t}_2 + \mathbf{t}_1 \\ \mathbf{0}^T & 1 \end{bmatrix}

— note that t2\mathbf{t}_2 gets rotated by R1R_1, which is why translations of chained transforms do not simply add. The inverse has the closed form:

T1=[RTRTt0T1]T^{-1} = \begin{bmatrix} R^T & -R^T\mathbf{t} \\ \mathbf{0}^T & 1 \end{bmatrix}

Homogeneous coordinates come from projective space: appending a 1 (points) or 0 (directions) lets one matrix express rotation and translation together. In projective geometry, parallel 3D lines meet at a vanishing point in the image — a useful cue for rotation estimation in man-made environments and a reminder that image formation is projective, not Euclidean.

Keeping frames straight

The most effective habit is a subscript convention that makes composition self-checking: let TABT_{AB} map coordinates from frame BB to frame AA. Then

TAC=TABTBC,XA=TABXBT_{AC} = T_{AB}\,T_{BC}, \qquad \mathbf{X}_A = T_{AB}\,\mathbf{X}_B

and adjacent subscripts must “cancel” like units. If they don’t, the expression is wrong — this catches a remarkable fraction of pose-arithmetic bugs at a glance. Be explicit about whether a stored “camera pose” means Tworld,camT_{world,cam} (camera-to-world, the camera’s position in the world) or its inverse Tcam,worldT_{cam,world} (the extrinsics used in projection); both conventions are common across codebases.

Common pitfalls

Why it matters for SLAM

Every SLAM system is, at bottom, estimating a trajectory of SE(3)SE(3) elements. Chaining relative motions (Tworld,cam=Tworld,kfTkf,camT_{world,cam} = T_{world,kf}\,T_{kf,cam}), inverting transforms, and converting between quaternions (compact storage, ROS messages) and rotation matrices (computation) are daily operations. Getting frame conventions right — which frame a transform maps from and to — is the most common source of bugs for newcomers, so nail this before moving on.