Gimbal lock
What leads to gimbal lock in simple terms
While working out basics of engine I’m working on I had do make the decision that everyone in my position has to make. How to store orientation of objects in a world.
If you do any research on the subject you will definitely stumble upon Euler angles as solution to your problem. I can guarantee that second subject you’ll be researching immediately is “gimbal lock.”
I’ve read and watched every possible source of information on the subject of gimbal locks, trying to understand what, how and why. They range in quality and in difficulty. There are discussions so mathematically heavy that you’ll feel knowing less that before your started. On the other end there are explanations way too simple to give you a feel that you actually know what’s going on.
I’ll try my best to find some middle ground. I’m not a mathematician so I’ll try to keep away from discussions about differences between Euler and Tait-Bryan angles or mapping from 3-torus to real projective spaces. Wikipedia has plenty of that. I’m not going to start with definition of gimbal lock neither. Other sources have “losing degree of freedom” in the first paragraph all too often.
My favorite approach to every problem is bottom-up. Start with small problem, work your way up. Use visual, interactive aids as much as possible. Nothing beats first hand experience.
There’s a great interactive visualizer of everything that I’ll be talking about. Open it in another window and keep at hand. I’m not joking, it’s essential and if by end of this lecture you’re any closer to understanding Euler angles, you can thank creator of that visualizer in the first place.
https://ursinusgraphics.github.io/RollPitchYaw/
1. How can you describe orientation of an object with just 3 angles?
Remember that’s your initial problem. You have an object, maybe a 3D model of an airplane, coming from Blender. You want to put it inside your world. From now on assume that your world is build around right handed coordinate system, with +x-axis pointing to the right, +y-axis going up, and +z-axis piercing through your screen into your direction. The model you created follows the same rules so if you import it into your world it will look and be oriented the same way as in modelling tool.
Take a look at the visualizer I’ve linked. This is exactly what I described. The plane has front pointing in -z direction, +y is up, +x is right.
Euler, XVIII century genius, figured out that you can describe any orientation of a rigid body with just 3 rotations about 3 angles. This is great because if you want to place an object in your world, you would need only 3 variables, super easy. Let’s try to do that. If you do a little research you’ll find out that one flavor of these angles is widely used in aviation and stuff like that. That’s neat, if it’s good for planes must be good for, let’s say, a game.
Those 3 angles are called yaw, pitch and roll. In our case they describe elementary rotations around our world axes. Rotating object around z-axis will be our roll, rotation around x-axis will be called a pitch and rotation of an object around y-axis yaw.
There are two thing worth mentioning here.
First - if you describe orientation as 3 rotations, order of these rotations matters. If you decide to describe an orientation with Euler angles you need to decide around which axes you will be rotating and in what order.
Second - if you describe three consecutive rotations in a row, you can imagine them in two ways.
One way is called intrinsic and that’s how I imagine these rotations in my head when working with Euler angles. What that means that you start with an object in your world aligned with you world coordinate system and go through each rotation from point of view of that object, axes you make each rotation are this object local coordinates. With each rotation object changes place in world but its local coordinates move with it. If you object was a plane, as is with a visualizer, then plane’s right with will always point towards +x in local coordinates.
Extrinsic is the other way to imagine consecutive rotations. Every rotation is around your world coordinates. Your object moves around the world with every rotation but world axes stay in place.
Nice thing about that intrinsic-extrinsic way of thinking is - if you are used to thinking in one of them, as I am with intrinsic rotations, you can easily swap to the other if necessary.
Every 3 intrinsic rotations around local axes are exactly the same as 3 extrinsic rotations around world axes done in reverse about the same angles.
2. What does that all mean for us?
In the visualization with the plane you need to know 2 things.
Rotating object around z-axis will be our roll, rotation around x-axis will be called a pitch and rotation of an object around y-axis yaw.
Intrinsically, order of rotations will be: yaw -> pitch -> roll. Extrinsically: roll -> pitch -> yaw.
The result will be the same because they are equivalent but the way you visualize them when planning every movement is different.
Now you should have basic feeling what’s going on in the visualizer. You have a view of a world, a plane at the origin of that world and 3 sliders for yaw, pitch and roll, where you can set rotations around axes. Remember that it doesn’t matter in what order you set those values and if you thing of setting these angles intrinsically or extrinsically, the describe exactly the same orientation.
You can play with those sliders, setting different values. You can achieve every possible orientation of your plane that you imagine without issues. Just start with all zeroes, and go on step by step yaw->pitch->roll or roll->pitch->yaw and nothing bad will ever happen.
It’s worth reminding, with those 3 Euler angles you can describe every possible orientation of our plane in our world. Every. Single. One.
3. What’s the issue then?
At this point you can think to yourself that these Euler angles are pretty awesome. You pluck an object into your world, easily visualize final orientation in your head, set 3 variables, one for each rotation and you’re done.
Let’s do that. Let’s assume that visualizer is a game you want to give to some player.
Can it be a game? It has a world, it has an object representing player and it has three controls, each for angle. Replace each slider with two keys, maybe A to yaw left, D to yaw right, W and S to increase/decrease pitch angle, and Q/R to change roll angle. Sound like a plan, 3 variables, 6 buttons to manipulate them. Perfectly reasonable game with reasonable controls.
What it doesn’t have, yet, is an objective.
Objective will be pretty simple. You want your player to point the plane straight to upper left corner of the screen, so the plane is visible from the top. Let’s pretend there’s some enemy hiding there and we wan’t to aim at him. In world coordinates it means that if our world origin is at (0, 0, 0) then our enemy is somewhere along the vector (-1, 1, 0), at 45 degree angle above and to the left of the plane.
Just remember one thing, you’re storing the plane position. You can drag the sliders all you want as your player would do to control the plane. You wouldn’t reset you player position out of nowhere in the middle of the movement back to origin. That would be a bug.
If you’re careful and/or lucky you’ll get there without any hiccups. Yaw by 90 degree, pitch 45 degree, roll 90 degree and you’re ready to fire at the enemy. The plane points exactly at 45 degree angle to upper left, with top down view of the plane.
It looks fine, your game works, player is happy. Until.
Until your player figures out that there are 3 movements to get him into the proper attacking position, Yaw(90) -> Pitch(45) -> Roll(90), but there’s a simpler way. Pitch(90) first to point straight up and it’s just one 45 degree rotation to target the enemy.
Do it as your player would try to do. Reset all controls. Pitch up by 90 degree and target your enemy from this position. I’ll wait. If you get tired, read on.
4. How’s that the issue?
Remember that “losing degree of freedom” stuff? That’s it. It happened to you. You (and your player) were one yaw away from getting the enemy but nope. Couldn’t do it. There is now yaw. Gimbal lock. That doesn’t mean that there was no way to position the plane correctly. It was done at first attempt so it’s not the fault of your method of storing orientation that failed. You didn’t run out of angles to describe what you wanted. Something else happened.
Euler angles are fine for storing orientation. You can carefully plan how your object in game will be oriented and it’s done.
What they aren’t great for is storing information about changes in orientation. It’s the constraint on second rotation that you imposed on your movement - keep pitch intact, that rendered movement into wanted position impossible. You can express starting position, you can express final position, you can also express every single position in between. There is just no simple way to describe simple, smooth, gradual movement from starting to final position with controls that you have.
Nothing prevents you, or the player, from changing the pitch, maybe even leveling plane back and working their way through angles to get back at desired orientation. Just not with that 90 degree pitch in place.
5. Why’s that the issue?
Problem you just experienced is built-in into the method of storing orientation as three rotations around world axes.
World axes? You might think that if you’re imagining positioning of your plane in intrinsic fashion you are safe then? Nope.
Remember that intrinsic/extrinsic way of describing consecutive operations? Intrinsic being kind of reverse extrinsic? It’s important now. Their result is finally the same so it doesn’t matter how you personally think about them. You have 3 angles? You’re in danger. You make a bunch of movements and your plane ends up pointing straight up? Yup, you pitched by 90 degrees and you’re stuck.
You can change order of rotations, you can change axes to rotate around, you can build more complicated ways of expressing movement than simply a slider per angle.
It won’t matter, merciless math behind going from Euler angles to orientation that other parts of graphical pipeline need just works like that. Nothing can be done about it.
If you get back to the visualizer, you can make couple of experiments to get an intuition with gimbal locking.
This time forget about intrinsic operations, don’t think about yaw->pitch->roll, try doing some extrinsic operations. Remember to think how you would rotate you plane around world Z axis, then pitch around world X and finally yaw around world Y axis. Forget about plane local coordinates, observe where your plane end with each movement.
Roll your plane by 45 degrees. Remember that you roll around world Z axis. Then pitch by 90 degrees. Remember, you pitch around world X axis.
Look at that position. If you now tried to do any yaw (remember yaw is around world Y axis), how would it really be different from your previous roll? Not really, would it? If plane is pitched vertically, yaw and roll rotate plane around world Y axis in different directions, but this doesn’t change much. Without changing pick you yaw and roll around the same axis.
You can reset controls and star again this time skip any rolling, go straight to pitch by 90 degrees. Then try changing yaw, you rotate around Y axis. Is it any different from previous experiment where you rolled a plane? Not in any meaningful way, you can try changing roll now and it still result in plane rotating around the same axis that your plane it pitched about.
This effect that you’re observing is logical consequence if you think about it.
If you want to orient your object in world you start at angles 0, 0, 0 - every time. In a computer game it would mean every single frame.
You roll, then pitch and it looks exactly the same as other movement where you pitch first and then yaw. If you know how to go from Euler angles to final orientation and you know that your engine has to go through the same steps you can go step by step through these motions. You can just observe with your own eyes that if your second extrinsic rotation positions your object exactly along the same axis you will be doing your third rotation - either first or last rotation is kind of pointless. You thought you were doing some rolling first? If your second move is 90 degree pitch it’s pointless. You might skip that first rotation and just yaw. Or roll to the position you want and forget about any yaw after you pitch. If you ever hear about losing degree of freedom in gimbal lock - that’s what people have in mind. You are given 3 sliders but 2 of them do effectively the same thing.
This is intuition but there’s math behind these observations.
6. How to prove that intuition is correct?
Take a closer look at that visualizer, there are 4 matrices next to the world viewport.
I assume that you know what rotation matrices are, there are tons of resources explaining how a rotation matrix around given axis looks like. The same goes for matrix multiplication. What sometimes isn’t explained well, is the intuition of what’s happening so I’ll focus on that.
You have those three sliders, for yaw, pitch and roll.
You have also established that the order in which you apply your rotations intrinsically will be yaw -> pitch -> roll. The first one is around local to our model plane axis y, which at the beginning is exactly the same as world Y. Second intrinsic rotation is done by local axis x. It’s not obvious what that axis of rotation would be. The same goes for third rotation, around local axis z. If you wanted to make calculations this way, you’d need to track what your local axes look like and rotate model around them. That’s a lot of hard work.
Thankfully, it is proven in other sources by people smarter than me that intrinsic rotations around local axes are exactly the same as extrinsic rotations done about the same angles around global axes in reverse order. So what you can do is imagine your movement in intrinsic terms as local y, local x, local z but then simply roll around global Z, then pitch around global X and finally yaw around global Y and get the same result. Rotating around static axes is relatively easy and well defined.
You just combine them into a single rotation matrix by multiplying those elementary rotation matrices in proper order. That’s why in the visualizer you have multiplications of three matrices, from right to left, you get Rz(roll), Rx(pitch), Ry(yaw). These are three rotation matrices around global axes Z, X and Y. Exactly as in extrinsic order that was established earlier.
On the right there’s the final rotation matrix that combines all 3 previous operations into one. That’s the matrix that you later combine with translation or scale matrices and get full blown transformation matrix. The one you can apply to every vertex of your model and calculate its position in the world. If your rotation matrix is busted, then transformation is busted, and your object in world behaves strange.
Why gimbal lock manifests in such a way and why it will always happen with this method of storing orientation will be clear if you make that multiplication of rotations around axes. Not on any numbers yet, just get definition of each rotation and multiply them on symbols.
Do it by hand, or find someone who did it already. If you don’t find multiplying bunch of matrices just to prove something very amusing, you’re not alone. Jump to wikipedia: https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
You’re interested in the table with premultiplied all of Tait-Bryan angles. You’re interested in the one with YXZ order.
If you have that final rotation matrix noted, you can recreate situation from our game in math. Put Beta=90 degrees into that matrix and see what happens. If you did everything properly you’re ready to make two final key observations to understand why gimbal lock happened and why it manifests the way it manifests.
By simply substituting pitch with 90 degrees you will always get rotation matrix with one column independent from any angles and two other columns depending on combination of yaw and roll. That’s exactly what happened in our “game”. We applied changes to yaw and roll while leaving pitch at 90 degrees.
In our case it was third column that remained always the same, [0, -1, 0]. Visualizer confirms that, with pitch 90 degree, no matter how are yaw and roll set, third column is [0, -1, 0]. That means our plane’s local coordinates z ended up pointing down along world -Y axis. Plane tail down. Local coordinates x and y changed will spin around local z as long as pitch remains 90 degrees.
Only if you change pitch, you will be able to “unlock” that third column and apply meaningful yaw.
7. What now?
You should have a decent idea what it means to store orientation as Euler angles. For good or for bad. Bad being mainly dreaded “gimbal lock”.
You can plan very carefully, make limitations about range of motions of your objects and you will never end up in that difficult situation.
Or you can store orientation in other ways.
I store orientations of every object in my engine in full 3x3 rotation matrix. It eliminates problem with gimbal lock completely. You don’t go through any extra steps to know how your object is oriented, rotation matrix just is. You can still rotate your objects around world axes but it’s fine because you make a rotation, object ends up in different place but next rotation will be independent from previous one and with no relation to any of world axes. I might describe how to do it in another entry.
You can also turn to quaternions. You might want to be careful there, you can still use them the same way you use Euler angles and end up exactly with the same problem you wanted to avoid.
Remember that problem here is not simply that you used something called Euler angles but you used something to store object orientation as 3 angles in relation to world coordinates. And then you use those angles to calculate your rotation matrix. You can’t to avoid it, it’s just a flaw of you have to consider doing things that way. No matter what you use, if you transform it back to those 3 angles, and the back to rotation matrix, you might end up in a gimbal lock situation. Every time you end up calculating rotation matrix from some angles - be sure that’s what you want to be doing.
That’s it. I hope it was of any help. There’s a lot of mind bending problems when talking about Euler angles, or transformations in general, so you might want to read it once, or twice, go back to other source and return here.
One day it will just click.
GAMEENGINEDEV
euler angles gimbal lock computer graphics