categories: robotics, automation & robotics, mechanics
Part two. Last post was about locating a link in space; this one is about rotating something in 3D without the headaches of Euler angles (gimbal lock, ambiguous orderings, discontinuous jumps). The standard fix is quaternions — a 3D generalization of complex numbers.
Task — rotating a vector with a quaternion
Rotate $$v=[1,0,0]^T$$ by $$\theta=90^\circ$$ about the $$Z$$ axis ($$u=[0,0,1]^T$$), using quaternion algebra instead of a rotation matrix.
Why $$\sin(\theta/2)$$ and not $$\sin\theta$$? A quaternion is the 3D generalization of a complex number — instead of one imaginary unit $$i$$, it has three, $$i,j,k$$. The rotation quaternion comes from generalizing Euler's formula $$e^{i\theta}=\cos\theta+i\sin\theta$$ into 3D, $$e^{\phi u}=\cos\phi+u\sin\phi$$, where $$u$$ is the unit rotation axis. But a quaternion doesn't rotate a vector by simply multiplying it once — it uses a two-sided "sandwich" product $$p'=q\,p\,q^*$$. Multiplying on both sides applies the rotation angle twice, so using the half-angle $$\phi=\theta/2$$ in $$q$$ makes the two applications add up to exactly $$\theta$$ overall: $$q=\left[\cos\tfrac{\theta}{2},\ u_x\sin\tfrac{\theta}{2},\ u_y\sin\tfrac{\theta}{2},\ u_z\sin\tfrac{\theta}{2}\right]$$
Why the conjugate $$q^*$$? Exactly like complex conjugation, where $$z=a+bi \Rightarrow z^*=a-bi$$, a quaternion's conjugate flips the sign of its vector (imaginary) part: $$q=[q_0,\vec{q}] \Rightarrow q^*=[q_0,-\vec{q}]$$. Geometrically $$q^*$$ is the same rotation run backwards, by $$-\theta$$. Sandwiching with $$q$$ on one side and $$q^*$$ on the other is what cancels out the extra scalar terms that a naive single multiplication would introduce, guaranteeing the result $$p'$$ comes back out as a pure vector (zero scalar part) instead of some four-component mess.
Step 1 — build q, the pure-vector quaternion p, and q*: $$q=\left[\cos45^\circ,0,0,\sin45^\circ\right]=\left[\tfrac{\sqrt2}{2},0,0,\tfrac{\sqrt2}{2}\right],\quad p=[0,1,0,0],\quad q^*=\left[\tfrac{\sqrt2}{2},0,0,-\tfrac{\sqrt2}{2}\right]$$
Step 2 — compute $$p'=q\cdot p\cdot q^*$$, using the quaternion product rule $$a\cdot b=[a_0b_0-\vec a\cdot\vec b,\ a_0\vec b+b_0\vec a+\vec a\times\vec b]$$. First $$q\cdot p$$: $$q\cdot p=\left[\tfrac{\sqrt2}{2},0,0,\tfrac{\sqrt2}{2}\right]\cdot[0,1,0,0]=\left[0,\tfrac{\sqrt2}{2},\tfrac{\sqrt2}{2},0\right]$$ then multiply that result by $$q^*$$: $$p'=(q\cdot p)\cdot q^*=\left[0,\tfrac{\sqrt2}{2},\tfrac{\sqrt2}{2},0\right]\cdot\left[\tfrac{\sqrt2}{2},0,0,-\tfrac{\sqrt2}{2}\right]=[0,0,1,0]$$ So $$v'=[0,1,0]^T$$ — the vector originally pointing along $$X$$ now points along $$Y$$, exactly what a 90° rotation about $$Z$$ should do.
Same reason quaternions are worth the extra abstraction over a 3×3 rotation matrix: they interpolate smoothly (no gimbal lock), compose cheaply (quaternion product vs. matrix product), and this exact sandwich formula is what runs under the hood in every robot's orientation/IMU-fusion code. Next post: working backwards from a target position to the joint angles that reach it — inverse kinematics. Thank you for reading!
Read more