Jump to content
  • Advertisement
Sign in to follow this  
testyturtle

flight sim plane rotation question

This topic is 4081 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone. I'm trying to write a simple flight simulator. I am using quaternions, but the plane does not rotate correctly. If we are looking at a plane flying straight and level from behind, let's say it rolls 90 degrees to the right. If you "pull up" (elevator input) from here, the plane should rotate about the new wing axis. Instead, what happens is the tail goes down onscreen, and the nose goes up. It is as if the plane's local coordinate system did not rotate during the 90 degree roll to the right. It is still aligned with the world coordinate system. Conceptually I can understand this because quaternions apply their rotations "all at once". I'm just not sure how to fix it. Can anyone help? My code to build the airplane rotation matrix looks like this:

double pitch = orientation.x(); // orientation accumulates euler angles
double yaw =   orientation.y();
double roll =  orientation.z();

// build 3 quaternions
// this constructor accepts x,y,z,w

Quaternion qX(sin(pitch/2), 0,           0,      cos(pitch/2));
Quaternion qY(0,            sin(yaw/2),  0,        cos(yaw/2));
Quaternion qZ(0,            0, sin(roll/2),       cos(roll/2));

Quaternion qResult = qX * qY * qZ;

// convert to D3D Quaternion and get rotation matrix
D3DXQUATERNION d3dQuat(qResult.x(), qResult.y(), qResult,z(), qResult.w());
D3DXMatrixRotationQuaternion(&currentRotationMatrix, &d3dQuat);


I know i'm doing a little more work than necessary converting from my Quaternion to Direct3D's, but I wanted to code one out to understand it a little better. Thx if you can help!

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by testyturtle
Conceptually I can understand this because quaternions apply their rotations "all at once".
Just a quick note: quaternions don't apply their rotations any more 'all at once' than matrices do.

In fact, the use of quaternions in your example is completely incidental; what is really determining the behavior here is the use of Euler angles.

I don't know what behavior you're after exactly, but a couple things you could try would be a) changing the Euler-angle order, or b) using incremental rotations instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Just a quick note: quaternions don't apply their rotations any more 'all at once' than matrices do.


Hi jky, thx for the response. I have often read that quaternions perform the rotations "all at once" as a way of explaining how they avoid gimbal lock, but I guess in reality it is just that the 4d sphere allows all 3 rotations to be applied sequentially without losing any one of them.

After thinking about it, I realize my problem is that I always update my rotations in the world coordinate system, regardless of which way the plane is pointing. For example, an aileron force is always applied about the Z-axis, even if the plane is pointing down the X-axis...so it seems I need to transform (rotate) my incremental rotations from the airplane's original, unmodified coordinate system to the local airplane coordinate system before applying them to the model.

How does this idea sound. What if I maintain a quaternion to hold the direction the nose of the aircraft is pointing and do this...

every simulation tick:

1. Calculate incremental rotations (as euler angles) for current timestep in original, unmodified airplane coordinate system (using torque/inertia/etc.)

2. Use heading quaternion to rotate these incremental rotations into aircraft coord system.

3. Form temp quaternion holding incremental rotations (which are now relative to heading quaternion).

4. heading quaternion = temp quaternion * heading quaternion


Does that sound about right? I haven't implemented any vehicle systems before so i'd appreciate any feedback, even if its a smackdown. I understand the quaternions aren't necessary, but this is a flight sim and i'd like a real 6DOF system without having to add 'hacks' to deal with gimbal lock. Thx!







Share this post


Link to post
Share on other sites
ok everyone, I found an extremely detailed document describing rigid body simulation, which turns out to be exactly what I was looking for. It describes, among other things, how to integrate using 4th order runge-kutta instead of traditional euler integration.

If anyone is interested, the .pdf is located here:

http://www.chaney.eclipse.co.uk/rigidbody.zip

Share this post


Link to post
Share on other sites
Quote:
I have often read that quaternions perform the rotations "all at once" as a way of explaining how they avoid gimbal lock, but I guess in reality it is just that the 4d sphere allows all 3 rotations to be applied sequentially without losing any one of them.
No, not really.

First of all, the 'all at once' thing is really kind of misleading. A (rotation) quaternion, (rotation) matrix, or axis-angle pair represents one thing and one thing only: a single axis-angle rotation. There is only one rotation, not multiple rotations that must be performed 'at once'.

You can, however, combine rotations in sequence to yield the aforementioned single rotation. Depending on how these rotations are combined, the end effect may give the appearance that some of the individual rotations have canceled each other out (or whatever), but the final rotation is applied 'all at once', no matter how you cut it.

Quaternions are no better or worse at performing multiple rotations 'at once' than are matrices or axis-angle pairs. Furthermore, the fact that the orientations map to a 4-d unit hypersphere has nothing to do with the fundamental behavior of quaternions with respect to rotations (although it does offer a few practical advantages, such as efficient and elegant interpolation between orientations).
Quote:
What if I maintain a quaternion to hold the direction the nose of the aircraft is pointing and do this...
If you only needed to store the direction the aircraft was pointing, you would simply store a vector. A quaternion (or rotation matrix) stores more information than this: it fully represents an orientation.
Quote:
I understand the quaternions aren't necessary, but this is a flight sim and i'd like a real 6DOF system without having to add 'hacks' to deal with gimbal lock.
Overcoming gimbal lock doesn't require any 'hacks'. It simply requires that you not use Euler angles in a certain, specific way (i.e. building up an orientation 'from scratch' using a series of Euler-angle rotations). A 6DOF system built using vectors or matrices is no 'less 6DOF' nor 'more hacky' than one using quaternions.

Personally, I would recommend that you forget about quaternions for now. Everything you think you need quaternions for can be done just as effectively with matrices. Convince yourself of this first (in the process, you'll most likely develop a better understanding of rotations in general). Then later, if you want, you can switch to quaternions.

Share this post


Link to post
Share on other sites
Quote:
Original post by testyturtle
ok everyone, I found an extremely detailed document describing rigid body simulation, which turns out to be exactly what I was looking for. It describes, among other things, how to integrate using 4th order runge-kutta instead of traditional euler integration.
Just to be clear, the 'Euler integration' under discussion here is completely different from the 'Euler angles' we were discussing earlier. (You may already know this, but I'm just mentioning it in the hopes of heading off any further confusion.)

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Just to be clear, the 'Euler integration' under discussion here is completely different from the 'Euler angles' we were discussing earlier. (You may already know this, but I'm just mentioning it in the hopes of heading off any further confusion.)


Yes I suppose I should have made it more clear I was talking about numerical integration as opposed to the rotation discussion above.

From what you are saying then jyk, would you recommend any particular representation for the rotations, given what I am trying to accomplish? Or are you just pointing out that euler angles/axis+angle/matrices/quaternions can all get the job done, and you think quaternions are overkill?






Share this post


Link to post
Share on other sites
Quote:
Original post by testyturtle
From what you are saying then jyk, would you recommend any particular representation for the rotations, given what I am trying to accomplish? Or are you just pointing out that euler angles/axis+angle/matrices/quaternions can all get the job done, and you think quaternions are overkill?


My advice is to use matrices because they are much easier to work with. The three columns of a rotation matrix represent the three axes of the transformed coordinate system, making it easy to visualise the rotation. When you use a matrix to represent the orientation of a plane the three columns represent the axes around which you will be applying your roll/pitch/yaw torques.

The main advantages quaternions have over matrices are:

1. use less memory
2. normalisation is easier/faster
3. chaining transformations together is faster
4. interpolation (slerp) is faster/easier

However, applying a transformation to a vector is faster (fewer adds/multiplies) with a matrix than a quaternion. If this is the most frequent thing that your simulator does (and it probably is), using matrices may be faster than quaternions.

Share this post


Link to post
Share on other sites
Quote:
Original post by testyturtle
From what you are saying then jyk, would you recommend any particular representation for the rotations, given what I am trying to accomplish? Or are you just pointing out that euler angles/axis+angle/matrices/quaternions can all get the job done, and you think quaternions are overkill?
Don't have time to go into too much detail here, but the rotation representations you mention are not all equivalent to each other.

The axis-angle form is really the 'fundamental' form. In one sense or another, all rotations in 3D boil down to this form.

However, the axis-angle representation isn't particularly convenient for the types of operations we usually wish to perform. A 3x3 matrix, on the other hand, is very convenient. The matrix form can be considered the 'go to' representation for rotations (or any other transform, really).

Quaternions are functionally equivalent to 3x3 rotation matrices, while having a few minor advantages and disadvantages in comparison. In short, if you don't know why you need quaternions, it's usually best to just forget about them until you get a better handle on 3D math in general.

Euler angles are a different story. An Euler-angle sequence is simply a series of rotations about a series of axes. The rotations themselves can be represented using any of the other forms mentioned (axis-angle pair, matrix, quaternion). It doesn't matter which of these representations is used; as long as the rotations are being performed in sequence using Euler angles, the rotations will be subject to gimbal lock and other idiosynchrocies of the Euler angle form.

Gotta run, but in summary I'll echo MrRowl's suggestion: use matrices (unless and until you have a compelling reason to do otherwise). To that I'll add that you can still use Euler angles (in conjunction with matrices, that is), if you find that that's the behavior you want. However, if it's 6DOF motion you're after, you will not want to use Euler angles (at least not as presented in your example).

Share this post


Link to post
Share on other sites
Thx jyk and MrRowl!

I spent several hours reading yesterday, and redid the whole thing with a matrix for the rotation (not euler angles). Now it is working correctly!

In case anybody else has a similar problem simulating rotational dynamics, my main problem was using the inertia tensor I for updating angular velocity (w), like this:

w = I * angularMomentum;

instead of:

rotatedI = R * Iinverse * Rtranspose; // similarity transform
w = rotatedI * angularMomentum;

where R is the accumulated, orthonormalized rotation matrix representing the aircraft's current orientation. That little gem results in all your rotational forces (aileron, rudder, elevator) being applied correctly no matter which way the aircraft is facing.




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!