Yaw, Pitch, and Roll?
|
Pedro Pendragon
Registered User
Join date: 15 Jan 2004
Posts: 77
|
11-18-2004 17:36
I'm trying to devise a way to see the pitch and roll of an aircraft. I would like these to stay the same no matter which direction the aircraft is facing, if that makes sense -- I'm not sure that I'm being clear, so I'll try to illustrate with an example. rotation a=llEuler2Rot(<0, 20, 0> * DEG_TO_RAD); rotation b=llEuler2Rot(<0, 0, 45> * DEG_TO_RAD); rotation r=a * b; llSay(0, (string)(llRot2Euler(r) * RAD_TO_DEG));
returns: <-14.43276, 13.99545, 46.78083> Though my 'pitch' angle has remained 20 degrees from horizontal, I can't figure out how to determine that from the end result. (I know in this case i could divide by b, but I'm interested in a more general case where b would be unknown) Things become even more cumbersome if I try to add x (roll) movement too. Any ideas would be appreciated.
|
Apotheus Silverman
I write code.
Join date: 17 Nov 2003
Posts: 416
|
11-19-2004 09:39
You will find it easiest to work with rotation axes (llRot2Fwd(), llRot2Up(), llRot2Left()) instead of euler angles to find the rotations specific to each local axis.
I've done what you are seeking minus the roll component in most of my recent airplane scripts for their HUDs, but I'm at work right now so I can't paste examples.
|
Pedro Pendragon
Registered User
Join date: 15 Jan 2004
Posts: 77
|
11-19-2004 19:50
If you don't mind sharing, that'd be cool.
I've been trying to puzzle this out on my own for a few days, but I haven't quite made the breakthrough.
|
Pedro Pendragon
Registered User
Join date: 15 Jan 2004
Posts: 77
|
11-20-2004 07:53
Well, I've figured part of it out: vector v=llRot2Fwd(llGetRot()); float run=llSqrt(v.x * v.x + v.y * v.y); float pitch = -llAtan2(v.z, run); float heading = llAtan2(v.y, v.x); llSay(0, "Pitch = " + (string)(pitch * RAD_TO_DEG)); llSay(0, "Heading = " + (string)(heading * RAD_TO_DEG));
That gets me a good y and z value! Now I'm trying to puzzle out how to get an x value, too.
|
Apotheus Silverman
I write code.
Join date: 17 Nov 2003
Posts: 416
|
11-20-2004 09:18
// Local rotation functions rotation Inverse(rotation r) { r.x = -r.x; r.y = -r.y; r.z = -r.z; return r; }
// Returns the rotation of the root prim rotation GetParentRot() { return Inverse(llGetLocalRot()) * llGetRot(); }
// Returns the angle of the given xy component. // The hypotenuse of the right triangle formed with sides x and y must be 1. float GetAngle(float x, float y) { // Calculate the angle float targetAngle = llAsin(y) * RAD_TO_DEG; // Adjust values for quadrants 2 and 3 if (x < 0.0) { if (y < 0.0) { targetAngle = -180.0 - targetAngle; } else { targetAngle = 180 - targetAngle; } } return targetAngle; } // Angle of Attack vector xAxis = llRot2Fwd(GetParentRot()); integer aoa = (integer)llFabs(GetAngle(0.9, xAxis.z) + 0.5);
// Heading integer heading = (integer)(GetAngle(xAxis.y, xAxis.x) + 0.5); The GetAngle() function is where the magic is done. It is my own implementation / alteration of atan2() without as much possibility for the dreaded "Math error". Note that the axis to put into the xAxis variable depends on the rotation of the object, as do the values you should pass to the GetAngle() function. In this particular case, the object's axes are oriented with the world's axes. I haven't tested this, but to get the roll component you should be able to do something like this (I may have the wrong axis plugged in...): // Roll angle vector yAxis = llRot2Left(GetParentRot()); integer rollAngle = (integer)llFabs(GetAngle(0.9, yAxis.z) + 0.5); I hope someone makes good use of this information. A number of months ago when I came up with it, I had to relearn trig to do it. 
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
11-20-2004 09:32
There is now a function for gettign the root prims rotation.
llGetRootRotation()
also for a better inverse function you should use...
rotation Inverse(rotation r) { return <0,0,0,1>/r; }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Pedro Pendragon
Registered User
Join date: 15 Jan 2004
Posts: 77
|
11-20-2004 16:29
Apotheus, looks like your code and mine perform almost the exact same function, except yours adds in parent rotation checking. There shouldn't be any math errors with llAtan2(), though -- since it accepts the x and y parameters separately and checks internally for divide by zero. I tested this just to make sure. This is what I finally came up with to get all 3 rotations in the order that i wanted ( roll * pitch * heading): vector getRollPitchHeading(rotation test) { vector v=llRot2Fwd(test); float heading = llAtan2(v.y, v.x);
float run=llSqrt(v.x * v.x + v.y * v.y); float pitch = -llAtan2(v.z, run);
rotation y=llEuler2Rot(<0, pitch, 0>); rotation z=llEuler2Rot(<0, 0, heading>); rotation x=test / z / y; vector tmp=llRot2Euler(x); float roll=tmp.x;
return <roll, pitch, heading>; }
It could maybe be optimized a bit -- there may be a better way of calculating the roll component , but I know for sure it works this way.
|
Caoimhe Armitage
Script Witch
Join date: 7 Sep 2004
Posts: 117
|
Undoing the roll angle
11-22-2004 14:35
From: Apotheus Silverman I haven't tested this, but to get the roll component you should be able to do something like this (I may have the wrong axis plugged in...): // Roll angle vector yAxis = llRot2Left(GetParentRot()); integer rollAngle = (integer)llFabs(GetAngle(0.9, yAxis.z) + 0.5); I hope someone makes good use of this information. A number of months ago when I came up with it, I had to relearn trig to do it.  well, I've been beavering away on some creature behavior where I need to regularly correct the roll angle of the object so that the local Y stays perpendicular to the global Z. Does anyone know a straightforward way to do this in pure rotations without dropping back to vector math. This has all been a lovely rememberance exercise of why I was not a math major (no spatial intuition at all). I'll take any suggestions, really. I've even heard a rumor of an llSetPrimParam() which prevents roll around a given axis. Can anyone give me a good steer?
|
Cross Lament
Loose-brained Vixen
Join date: 20 Mar 2004
Posts: 1,115
|
11-22-2004 15:14
Do you mean this one: llSetStatus( STATUS_ROTATE_X, FALSE ) ; (prevents rotation around the x-axis)? Obviously, there's also STATUS_ROTATE_Y and STATUS_ROTATE_Z... you can even | them together if you like. 
_____________________
- Making everyone's day just a little more surreal -
Teeple Linden: "OK, where did the tentacled thing go while I was playing with my face?"
|
Caoimhe Armitage
Script Witch
Join date: 7 Sep 2004
Posts: 117
|
11-22-2004 23:52
From: Cross Lament Do you mean this one:
llSetStatus( STATUS_ROTATE_X, FALSE ) ; (prevents rotation around the x-axis)?
Yep, but it doesn't seem to constrain things under llSetRot  I'd like to align the object in its target direction using only rotations around Y & Z, thereby preventing roll; however, I've found that most of the solutions I've tried become unstable over time. - C
|
Apotheus Silverman
I write code.
Join date: 17 Nov 2003
Posts: 416
|
11-23-2004 05:25
From: Caoimhe Armitage Yep, but it doesn't seem to constrain things under llSetRot  I'd like to align the object in its target direction using only rotations around Y & Z, thereby preventing roll; however, I've found that most of the solutions I've tried become unstable over time. - C Perhaps llLookAt() would work for you.
|