# Lesson 9: A spinning object: updating q from the turn rate

Source: https://quaternion.steppeschool.com/quaternion-angular-velocity-integration/ (part of "Quaternions, Visually" by Steppeschool, free)

We know how fast an object turns: from a gyroscope, a physics simulation or a game controller. Every few milliseconds we turn q by that small amount. With quaternions, this update is four short lines with no sin, no cos and no gimbal lock, plus one square root to keep the length at 1.

## 9.1 The equation

The turn rate, or angular velocity, is $\boldsymbol\omega = (\omega_x, \omega_y, \omega_z)$, measured about the object’s own axes. Its direction is the axis the object spins about right now, and its length is the speed in radians per second.

**Where does the update come from?** In a short time Δt the object makes a small turn: the angle is $|\boldsymbol\omega|\,\Delta t$, about the axis along ω. From lesson 4, that small turn is the quaternion

$$\Delta q = \Big[\cos\tfrac{|\boldsymbol\omega|\Delta t}{2},\ \ \tfrac{\boldsymbol\omega}{|\boldsymbol\omega|}\sin\tfrac{|\boldsymbol\omega|\Delta t}{2}\Big] \ \approx\ \Big[\,1,\ \ \tfrac{\Delta t}{2}\,\boldsymbol\omega\,\Big]$$

For a very small angle a: cos a ≈ 1 and sin a ≈ a. That is the only approximation we make.

It is a turn about the object’s own axes, so from lesson 7 we multiply it on the right:

$$q_{new} = q \otimes \Delta q = q \otimes [1, \mathbf 0] + q \otimes \big[0,\ \tfrac{\Delta t}{2}\boldsymbol\omega\big] = q + \tfrac12\, q \otimes [0,\ \boldsymbol\omega]\ \Delta t$$

We split [1, a] into [1, 0] + [0, a]. Multiplying by [1, 0, 0, 0], no turn, leaves q as it is.

So in each step, q changes by $\tfrac12\, q \otimes [0, \boldsymbol\omega]\,\Delta t$. Divide by Δt and we get the speed of change of q, which is how books write it:

$$\dot q = \tfrac12\, q \otimes [\,0,\ \omega_x,\ \omega_y,\ \omega_z\,]$$

ω on the right, because these are turns about the object’s own axes (lesson 7).

In code we take one small step every time step Δt, and then normalise:

$$q_{k+1} = \text{normalise}\Big(q_k + \tfrac12\, q_k \otimes [0, \boldsymbol\omega]\ \Delta t\Big)$$

> **Interactive visual: One small step, and why we normalise.** **Try it:** the grey circle holds all quaternions of length 1. One step moves q along a straight line (orange), so it lands a little outside the circle. Normalising pulls it back (green). The purple ring is the exact answer. Make the step small: all three meet.

Written out with the four product lines from lesson 5:

$$\begin{aligned}
w &\mathrel{+}= \tfrac{\Delta t}{2}(-x\,\omega_x - y\,\omega_y - z\,\omega_z) &\qquad x &\mathrel{+}= \tfrac{\Delta t}{2}(w\,\omega_x + y\,\omega_z - z\,\omega_y)\\
y &\mathrel{+}= \tfrac{\Delta t}{2}(w\,\omega_y - x\,\omega_z + z\,\omega_x) &\qquad z &\mathrel{+}= \tfrac{\Delta t}{2}(w\,\omega_z + x\,\omega_y - y\,\omega_x)
\end{aligned}$$

Use the old w, x, y, z on the right side. Compute all four, then assign.

**Check with numbers.** Start at q = [1, 0, 0, 0] and spin at 90°/s about z, which is 1.571 rad/s. With Δt = 0.01 s, only the z line changes: z = 0 + 0.005 × 1 × 1.571 = 0.00785. The exact answer is a turn of 0.9°, so z = sin 0.45° = 0.00785. It matches.

> **Interactive visual: Press Step: the four lines at work.** **Try it:** press **Step** a few times and read the two lines that change. The outline is the exact answer. Then choose a bigger Δt and see the solid object fall behind.

> **Interactive visual: Many steps: step size, normalising and drift.** **Try it:** set some turn rates and watch the solid object follow the outline. Then try three things. Turn off **normalise** and watch |q| grow. Set Δt to **250 ms** and watch the error grow. Add a small **error in the measured rate** and watch the object drift away and never come back.

## 9.2 What the lab shows

- **Normalise every step.** Normalising means dividing q by its length, so the length is 1 again. Each small step makes the length of q slightly bigger than 1. Without normalising, the length keeps growing and the orientation gets distorted.

- **Use a short time step.** The step is a straight line, but the true motion is a curve. A short Δt (5 ms, 200 steps per second) keeps the error tiny. The lab starts at 20 ms. A long one makes it big.

- **Errors add up.** Adding up many small steps is called integration. If the turn rate is slightly wrong, it adds the error up forever. Half a degree per second is 30° per minute. This is called drift.

**In real devices:** In a simulation or a game, the rate is exact and there is no drift. With a real gyroscope there always is. That’s why phones, drones and VR headsets add a second reference, such as gravity or a camera, and gently pull q toward it. The tool for that gentle pull is in the next lesson.

**Trap:** The equation needs radians per second. Many sensors and tools give degrees per second, so multiply by π/180 first. If the object turns 57 times too fast, this is the bug.

## ✓ Check yourself

**Q: Does this update have a gimbal-lock angle?**

No. The update has no tan θ and no division by cos θ, so there is no special angle at all.

**Q: The real object does not move, but your q slowly turns about z. What is wrong?**

The measured z rate is not exactly zero, and the small error adds up. That’s drift. Subtract the constant error if you know it, and correct the rest with a second reference.

## Sources and further reading

- J. Solà, "Quaternion kinematics for the error-state Kalman filter", 2017 <https://arxiv.org/abs/1711.02508>: chapter 4: the time derivative of q and how to integrate it
