30 min

Euler angles and gimbal lock: the map tears, not the territory

Three angles are the most readable way to describe an orientation and the least safe way to compute with one, because the description breaks down at places where the rotation itself is perfectly ordinary.

Where you are. You know that rotations about different axes do not commute, so a sequence of turns has to be read in order. This lesson takes the most popular way of writing such a sequence down, three angles, and shows you where it fails.

Point at something and say where

Stand up if you can. Pick something across the room and point at it with a straight arm.

Now describe that direction out loud with two numbers, the way a compass and a spirit level would: how far round the room you are aimed, and how far above level. “Thirty degrees round from the door, twenty degrees up.” Someone else could reproduce it exactly. Point at a few more things. It works every time, and every direction gets its own pair of numbers.

Now point straight up at the ceiling.

Say how far round the room you are aimed.

There is no answer. Every heading describes the same direction once your arm is vertical. The first number has quietly stopped meaning anything, which is worse than it being missing, because it is still there, still a number, still getting logged and averaged and fed into things.

Now the part that actually hurts. Point a degree or so short of vertical, leaning towards the window. Then swing slowly up through the top and the same small distance past it, so you are leaning towards the opposite wall. Your arm moved a couple of degrees, smoothly, without pausing. Your heading flipped by a hundred and eighty.

Nothing happened to your arm. Something happened to the description of your arm.

The idea in one paragraph

Any orientation can be written as three turns about three axes, taken in a fixed order. Three numbers, human-readable, easy to type into a config file: these are Euler angles, and they are the notation everybody reaches for first. They have two problems. The first is that “three angles” does not say which three axes in which order, and there are twenty-four defensible answers to that question, most of which disagree violently. The second is what your arm just did: at certain orientations the three numbers stop being able to name nearby orientations smoothly, one of them stops carrying information, and a tiny real motion demands a huge jump in the numbers. That is called gimbal lock, and the crucial point is that it is a property of the description, not of rotation. The orientation your arm passed through is entirely ordinary. It is the map that tears there, not the territory.

Three numbers means three rings

The name comes from hardware. Mount a ring so it can spin about a vertical axis. Inside it, mount a second ring on a horizontal axis carried by the first. Inside that, a third. Now whatever you bolt into the innermost ring can be aimed anywhere by setting three angles, one per ring.

three numbers means three rings, each pivoted inside the last 1st axis 2nd axis 3rd axis each ring carries the next one 1st angle · outer ring bolted to the base · turns everything 2nd angle · middle ring pivoted to the outer ring at two points 3rd angle · inner ring turns only what is mounted in it the order is part of the meaning, not a detail the same three numbers on a different ring order describe a different orientation
Three nested rings, each pivoted inside the last on its own axis, so three angles aim whatever is mounted in the innermost ring

Wider than the screen; scroll it sideways.

The order is baked into the metal. The outer ring carries the middle one, so turning the outer ring drags the middle and inner rings along with it; turning the inner ring moves nothing but the payload. That physical asymmetry is the same asymmetry you felt with the phone in lesson 5. Three angles are not three independent facts about an orientation. They are a recipe, and recipes have steps in order.

Twenty-four ways to read three numbers

Count the choices. The first turn can be about x, y or z: three options. The second must be about a different axis than the first: two options. The third must differ from the second, but is allowed to return to the first axis: two options again. That is twelve sequences, six of the xyz kind and six of the zxz kind that come back on themselves.

Then double it, because you still have to say whether each turn is about an axis fixed in the world or an axis carried along by the body. Twenty-four conventions, all in current use, all called “Euler angles”, and several of them called “roll, pitch and yaw” by someone.

This is not a theoretical concern. Take the perfectly innocent triple [30°, 60°, 90°] and read it under all twenty-four conventions:

what you getcount
conventions tried24
genuinely different orientations produced21
pairs of readings compared276
pairs more than 45° apart237
pairs more than 90° apart126
worst pair180° apart

The median disagreement between two randomly chosen readings of the same three numbers is 86°. Guessing the convention is not a small risk you can take under deadline; it is a coin flip on being nearly opposite.

Where it breaks

Now set the middle angle to 90° and look at what the rings are doing.

the same rig, with the middle angle wound round to 90° 2nd axis 1st axis and 3rd axis one line now, not two turning the 1st ring and turning the 3rd ring do the same thing what the rig can still do three angles to turn all three rings still spin freely two directions of motion the third direction has no ring left for real hardware this is a real loss for three numbers on paper it is not
The same three rings with the middle angle at ninety degrees, so the first and third axes have become one line and the first and third angles now do the same job

Wider than the screen; scroll it sideways.

The inner ring has been rotated until its axis is parallel to the outer ring’s axis. Turning the first ring and turning the third ring now do exactly the same thing. All three rings still spin freely, so you still have three angles to set, but you can only aim in two independent directions. The third has no ring left to serve it.

The arithmetic agrees, and it is easy to check. In the xyz extrinsic convention, with the middle angle pinned at 90°, the resulting rotation depends only on the difference of the other two:

from scipy.spatial.transform import Rotation as R
import numpy as np

def M(a, b, c):
    return R.from_euler("xyz", [a, b, c], degrees=True).as_matrix()

np.allclose(M(0, 90, 0),  M(35, 90, 35))   # True
np.allclose(M(70, 90, 20), M(50, 90, 0))   # True

Both pairs have the same first-minus-third, and both give byte-identical rotations. Three numbers going in, two degrees of freedom coming out: the map has folded, and a whole line of triples is being crushed onto one orientation.

The libraries know. Ask scipy to convert that orientation back into angles and it hands you a canonical answer and a warning:

R.from_euler("xyz", [35, 90, 35], degrees=True).as_euler("xyz", degrees=True)
# array([ 0., 90.,  0.])
# UserWarning: Gimbal lock detected. Setting third angle to zero
# since it is not possible to uniquely determine all angles.

You put in 35, 90, 35 and got back 0, 90, 0. Nothing is wrong: those are the same orientation. But any code that round-trips angles through a rotation and compares the numbers before and after has just been handed a false alarm, and any code that stores angles as the source of truth has just lost information it can never recover.

The map tears, not the territory

Here is the distinction the whole lesson turns on.

A physical three-ring gimbal at lock really has lost something. Its payload cannot instantaneously rotate about the missing direction, because there is no ring that produces that motion. That is a mechanical fact about metal, and it is why real hardware treats gimbal lock as an emergency.

Three numbers on paper have lost nothing of the kind. The orientation at pitch 90° is a perfectly ordinary orientation with perfectly ordinary neighbours in every direction. Rotation itself is smooth there; you swung your arm through it without noticing. What broke is the chart you were using to name orientations, in exactly the same way that a flat map of the Earth must distort or tear at the poles while the Earth stays round.

one journey over the top, described two ways straight up pitch = +90° before after the territory one smooth sweep across the top 180° of yaw, no motion at all pitch +90 pitch 0 pitch −90 yaw −180 0 +180 the map the whole red edge is that one direction
The same journey over the top drawn twice: a smooth arc across the pole of a globe, and a track on a flat yaw-pitch chart that hits the top edge and reappears one hundred and eighty degrees away

Wider than the screen; scroll it sideways.

And this is not a defect of one badly chosen convention that a cleverer one would fix. Every three-number scheme has this problem somewhere; the conventions differ only in where they put the tear. The reason is topological, and it fits in a sentence: the space of orientations is closed and bounded, with no edges and nothing running off to infinity, and no patch of ordinary three-number space has that shape. Something must tear or fold when you lay one over the other, exactly as when you try to peel a globe flat. Three numbers will always work beautifully in a neighbourhood and always fail somewhere. Which is the argument for quaternions: four numbers with one constraint, which is a curved space that matches the shape of the problem instead of fighting it.

What the tear costs you in motion

Take a straight, uniform physical motion and watch what happens to the numbers. Pitch upward at a steady one degree per step, straight through vertical, and read the xyz angles at each step:

true pitchangles reportedchange from the previous step
88°0, 88, 00, 1, 0
89°0, 89, 00, 1, 0
90°0, 90, 00, 1, 0
91°180, 89, 180180, −1, 180
92°180, 88, 1800, −1, 0

The step from 89° to 91° is two degrees of real motion; the numbers move by about 255° when you measure the jump across all three. Feed that into anything that differentiates, interpolates, or computes a loss against a target, and you get a violent spike from a motion that was perfectly smooth.

It is not only the crossing. Approaching the tear, the numbers get progressively more hysterical, and there is an exact statement of how fast. The three angle rates map to an actual turn rate through a 3×3 matrix whose determinant is exactly cos(middle angle)\cos(\text{middle angle}). In plain language: as the middle angle approaches 90° that matrix goes flat, so inverting it, which is what you do every time you ask “what angle rates give me the motion I want”, blows up. Worst case, one unit of physical turn rate costs you about 2.7 units of angle rate at a middle angle of 60°, about 81 at 89°, and about 810 at 89.9°. The three angles are describing a mild motion using enormous, nearly cancelling changes, and floating point notices long before you reach the singularity itself.

When three angles are still the right answer

None of this makes Euler angles a mistake. It makes them a presentation format.

They are the best notation in existence for a human reading an orientation off a screen, for typing a camera pose into a scene file by hand, and for arguing about a pose out loud. Nobody has ever debugged a wrist orientation faster by reading four quaternion components. And when the hardware really is a three-ring mount, its three angles are not a representation at all: they are measurements of three physical joints, and their lock is a real one you must plan around.

The rule that follows is worth memorising once and never revisiting:

taskrepresentation
storing an orientationquaternion, or a matrix
composing rotationsquaternion, or a matrix
interpolating between orientationsquaternion, using slerp
computing a loss or an errorquaternion, or the angle of the relative rotation
showing a number to a personEuler angles, with the convention printed next to them
a human typing a pose by handEuler angles, with the convention printed next to them

Convert at the boundary, in one place, with the convention named in the function signature. Never let three angles be the thing your system actually stores.

Interactive: drag the three ring angles and watch the axes. Static fallback: with the middle angle at 90° the first and third rings turn about the same line, so the first and third angles produce identical motion; the assembly still has three angles but only two independent directions of turn, and near that configuration a small motion of the payload demands a huge change in the angles.

Review

Three angles are a recipe, not three facts

Any orientation can be written as three turns about three axes taken in a fixed order, and those are Euler angles. The trouble is that three angles do not say which three axes in which order. Count the choices: three for the first axis, two for the second, two for the third, which is twelve sequences, and then double it, because each turn may be about an axis fixed in the world or an axis carried along by the body. Twenty-four conventions, all in current use, several of them called roll, pitch and yaw by somebody. Read one innocent triple under all twenty-four and you get twenty-one genuinely different orientations, with a median disagreement of eighty-six degrees. Three angles without a stated convention are not data. They are three floats and a hope.

The map tears, not the territory

Set the middle angle to ninety degrees and the first and third axes become one line, so turning the first ring and turning the third ring do the same thing. Three angles still go in, but only two independent directions come out, and a whole line of triples is crushed onto one orientation. That is gimbal lock, and the crucial point is that it is a property of the description, not of rotation. The orientation itself is entirely ordinary and has ordinary neighbours in every direction; you can swing an arm straight through it without noticing. A physical three-ring mount at lock really has lost a degree of freedom in metal. Three numbers on paper have lost only their ability to name nearby orientations uniquely. Same name, one real constraint and one bookkeeping failure.

Why no convention escapes it

This is not a defect of one badly chosen convention that a cleverer one would fix. Every three-number scheme tears somewhere; the conventions differ only in where they put the tear. The reason is topological. The space of orientations is closed and bounded, with no edges and nothing running off to infinity, and no patch of ordinary three-number space has that shape, so something must tear or fold when you lay one over the other, exactly as when you peel a globe flat. Near the tear the cost is measurable: one unit of physical turn rate costs about eighty-one units of angle rate at a middle angle of eighty-nine degrees. Hence the rule. Store and compute in quaternions, convert to angles only at the display boundary, and print the convention every single time.

Check yourself

1. Define gimbal lock in one sentence without using the word “gimbal”, then say what has actually been lost.

At certain orientations, two of the three angles start producing the same motion, so the three numbers can only reach two independent directions of change from there. What is lost is the description’s ability to name nearby orientations uniquely and smoothly. Nothing is lost about the orientation itself, which is ordinary and has ordinary neighbours; and nothing is lost about rotation, which is smooth through that region.

2. Your service stores orientations as three floats. A colleague suggests fixing gimbal lock by switching from the zyx convention to xyz. Respond.

It moves the tear, it does not remove it. Every three-number scheme has singular configurations; the conventions differ only in which orientations are the bad ones. If your payloads happen to cluster near the current tear, switching buys you time, and that is a legitimate short-term move as long as everyone knows it is a workaround. The fix is to store four numbers, a quaternion, and convert to angles only at the display boundary.

3. A round-trip test asserts that converting angles to a rotation and back returns the original angles. It passes for months, then fails on one input with no code change. What happened?

The input reached, or came very close to, the singular configuration, where many triples name one orientation and the library must pick a canonical representative. Feeding it 35, 90, 35 gets 0, 90, 0 back. The rotation is identical; the numbers are not. The test was asserting the wrong invariant. Compare orientations by the angle of the relative rotation, not by comparing angle triples componentwise.

4. A wrist controller runs smoothly except when the tool points nearly straight up, where the commanded joint rates spike and the arm shudders. The pose error was never large. Diagnose it.

Something in the loop is parameterised by three angles, and the tool’s vertical pose sits at that parameterisation’s singularity. As the middle angle approaches 90°, the angle rates needed to produce a given physical turn rate blow up like one over its cosine: roughly 81 times at 89° and 810 times at 89.9°. The physical motion being asked for is mild; the numbers describing it are not. Fix the representation rather than tuning the gains, or the same shudder returns at a different pose.

5. Why does the Apollo platform’s gimbal lock differ in kind from the gimbal lock in your orientation code?

Apollo’s was mechanical. With the middle gimbal near 90°, no combination of ring motions produced rotation about the missing direction, so the platform genuinely could not track the spacecraft’s attitude and had to be realigned against the stars. That is a real loss of a degree of freedom in metal. In software, nothing is lost but the coordinates: the orientation exists, its neighbours exist, and switching representation restores everything immediately. Same name, one real constraint and one bookkeeping failure.

6. Give a case where storing an orientation as three angles is the correct engineering decision.

When the three angles are the physical joints. A pan-tilt-roll camera mount has three real axes, and its three angles are measurements, not a representation choice; you would store them, control them, and honour their limits. Its lock is real and belongs in your motion planning. The mistake is the inverse: taking an orientation that has no three-axis mechanism behind it and choosing to write it down as three angles anyway.

Do this

No new code file; twenty minutes at a REPL and on paper.

1. Measure the convention chaos yourself. In a Python session, take one triple and read it every way:

import itertools, numpy as np
from scipy.spatial.transform import Rotation as R

seqs = [a+b+c for a, b, c in itertools.product("xyz", repeat=3) if a != b and b != c]
rots = {s: R.from_euler(s, [30, 60, 90], degrees=True) for s in seqs + [s.upper() for s in seqs]}

Then, for every pair, compute the angle of the relative rotation with np.degrees(np.linalg.norm((r1 * r2.inv()).as_rotvec())). Confirm the numbers in the table above: 24 conventions, 21 distinct orientations, and 237 of the 276 pairs more than 45° apart. That relative-rotation angle is the same “how far apart are two orientations” tool you built in lesson 5, and it is the right way to compare orientations for the rest of your career.

2. Find the fold. Fix the middle angle at 90° and vary the other two, checking as_matrix() for equality. Work out from the results which combination of the first and third angles the orientation actually depends on, then confirm it with two triples you choose yourself. You will have derived the collapse rather than read it.

3. Watch the numbers jump while the motion does not. Sweep the middle angle from 80° to 100° in one-degree steps, converting each rotation back with as_euler("xyz", degrees=True), and print the change at each step. Then compute the true angle between consecutive orientations with the relative-rotation formula. One column stays at 1° the whole way; the other detonates once. Sit with those two columns side by side, because that pair of behaviours is the lesson.

4. On paper, audit one interface you own. Find somewhere in a system you work on where an orientation, a heading, an angle or a rotation crosses a boundary between two components. Write down what convention each side assumes, and how you know. If you cannot answer for either side, you have found the same bug this lesson is about, before it found you.

What you can now do

You can write down an orientation as three angles and state the convention that makes them mean anything, including whether the axes are fixed or carried along. You can recognise gimbal lock from its symptoms: a round-trip test that suddenly fails, a stored angle that stops carrying information, joint rates that spike near one pose, a 180° jump in a log during a smooth motion. You can say exactly what is lost, which is the coordinates and not the rotation, and explain why no three-number scheme escapes it. And you know the rule that follows: compute in quaternions, display in angles, and name the convention every single time.

What you can now do

You can name the convention behind any triple of angles, recognise gimbal lock from the symptoms, and say precisely what is lost and what is not.