# Can I use quaternions to control an helicopter?

I'm trying to make a simplified helicopter (for the moment, it's a cube) simulation in 3D and I'm having some problems with rotation. An helicopter can rotate along the three axes :

• rotate on itself using the rear propeller : y axis rotation
• tilt left and right to go left or right : z axis rotation
• tilt up and down to go backward or forward : x axis rotation

I need to be able to control each axis individually. So far I've tried using euler angles, but whatever the order of rotation I use, either I run into a gimbal lock or some axes "switch places".

I seems that I need to use quaternions, but I don't know how to control each individual axis, since quaternions uses a direction and an angle. Should I create three quaternions and multiply them together? Wouldn't I end up with the same problems?

The weird thing is, if I use my finger to represent the three axes of my helicopter (thumb up = y, index = z, middle = x), I don't seems to run into those problems. Why?

• If you have access to a scene-graph, a viable alternative would be to have nested containers for each axis which you then rotate individually. – bummzack Jul 6 '11 at 16:32
• @bummzack, yes, I've thought about this. However, isn't it the same as concatenating three matrices of rotation in a particular order? – subb Jul 6 '11 at 16:47
• You're right @Subb, try not to store rotations for each axis separately, it will have the same problems as Euler Angles, no matter what you use for that, also Matrices and Quaternions will suffer from Gimbal Lock then. – Maik Semder Jul 6 '11 at 17:31
• @Maik Semder, then how can I provide control to the pitch/yaw/roll of my helicopter? – subb Jul 6 '11 at 17:42
• @Subb @Flip's and my answer basically told you how to do it. – Maik Semder Jul 6 '11 at 17:47

## 3 Answers

You should be able to use either a matrix or a quaternion to store the current orientation of your helicopter. The problem you're running into is how you apply change in pitch/yaw/roll to the helicopter.

I think you want to apply pitch/yaw/roll to the helicopter in local space each frame. You can do this by taking the change in pitch/yaw/roll for that frame and constructing a rotation matrix (you can do this with euler angles). Then you rotate the helicopter's previous orientation by this matrix (with the previous orientation represented either as a matrix or as a quaternion). It will give you the orientation for the new frame.

Representing the helicopter's orientation as a quaternion has the advantage that interpolating between quaternions is much easier than interpolating between matrices. So if in the future you have a current orientation and you want to figure out the per-frame rotation that will bring you to a new orientation at a desired time, the quaternion representation may be more friendly to you.

• That's how I've done it, apply incremental updates to the matrix that represents the local -> world transform. Remember to normalize the matrix, after a few hundred frames it will show rounding artifacts if you don't. – Patrick Hughes Jul 6 '11 at 17:23
• Also, to answer the final question of why the gimbal lock problem isn't seen using your hand to represent x/y/z axes, it's because you're probably applying the pitch, yaw, and roll values to the hand's local frame of reference. Constructing a rotation matrix with euler angles starts by rotating around the world's x, then by the resulting y, and then by the resulting z (actual order of x/y/z can differ in order). Try applying the rotations in this way and you may start to see how the gimbal lock appears. – Flip Jul 6 '11 at 17:24

Basically you can use every other representation of rotations, but Euler Angles. Matrices, Quaternions even Axis Angles will do what you want.

Should I create three quaternions and multiply them together? Wouldn't I end up with the same problems?


You are right, you would end up with the same problems. The key is to store the current orientation (matrix, quaternion) of your object and apply only a delta when changing the orientation.

When you want to turn 10 degrees around y, just create a delta matrix/quaternion for that and post multiply it with your current orientation (if you use post multiplication for matrices). If you multiply it the other way around, it will rotate the system around world's y-axis rather than around object's y-axis.

I find this resource very useful, it also comes with source code and explains the theory very well.

The trouble I think you might be seeing is a difference in axis rotation and velocity vectors (and also that you're missing a direction). When a helicopter tilts forward to move forward, the propulsion of the helicopter blades pushes air both down and backwards at a perpendicular angle to what you've labeled the X axis.

You have a fourth degree of freedom that you've missed: the speed of the blades controls the volume of air being pushed, which also controls the amount of lift the helicopter generates.

But even so, your "tilt left and right" and "tilt up and down" generally control the helicopter on a given plane. That is to say, a helicopter shouldn't fly downward when it tilts forward, backward, or to the side - but the lift amount might have to change and the speed will be controlled by the "opposite" side of the right triangle formed by connecting the helicopter to the ground with a straight line down (gravity), and the hypotenuse (lift). That should give your velocity vector to use.

You should be able to use quaternions to do this, but don't base your quaternion values on the tilt of the helicopter itself - try using the forces of motion the helicopter generates instead.

• That's not really answering the question though. Just adding more food for thought. – bummzack Jul 6 '11 at 16:33
• Currently, I'm using the rotation of the helicopter to transform the lift force vector, which is pointed upward in helicopter space. Do you mean that I should do the reverse, i.e. modify the vector directly and then rotate the helicopter in consequence? – subb Jul 6 '11 at 16:40
• I think you should do both, what your doing now, then make any RESULTING changes in rotation to the helicopter based on the normal of the blades. Ie you have 2 rotations; one applied to the blades and a second representing the actual rotation of the helicopter. Obviously all stored in Quaternions. – deceleratedcaviar Jul 12 '11 at 12:09