- Home ›
- Forum ›
- Troubleshooting ›
- General ›
- Definition of pitch, yaw, roll in jMonkeyEngine

Tagged: definition, pitch, roll, yaw

Hi,

I’m a bit confused by the definition of pitch, yaw and roll in jMonkeyEngine.

In the Quaternion documentation: http://www.jmonkeyengine.com/doc/com/jme/math/Quaternion.html it says that:

yaw rotates around x

roll rotates around y

pitch rotates around z.

However, when I look at the following definition from http://www.flipcode.com/documents/matrfaq.html#Q32 it says the following:

Pitch then becomes rotation in the X-axis, Yaw becomes rotation in the

Y-axis and Roll becomes rotation in the Z-axis.

Why is there a difference between them?

jME uses a right handed coordinate system.

Cheers,

Normen

I think there is an error though in the doc…

In the doc you refer to it’s also a right handed coordinate system

I talk with momoko_fan about this and it’s seems the methods works correctly, but the doc is wrong

pitch should be around x, yaw around y and roll around z

nehon said:

I think there is an error though in the doc…

In the doc you refer to it’s also a right handed coordinate system

I talk with momoko_fan about this and it’s seems the methods works correctly, but the doc is wrong

pitch should be around x, yaw around y and roll around z

So, with the following method:

public Quaternion fromAngles(float yaw, float roll, float pitch)

Is the order correct? Something I did notice though is when I set yaw to be 270 degrees, then convert it to radians as 4.71, when I do the reciprocal method: toAngles, this gives the yaw to be -1.57 radians.

When I was doing some experiments, I was using the following code with yaw incrementing every 90 degrees (1.57, 3.14, 4.71, 0)

rotation.fromAngles(yaw, roll, pitch);

arrowShape.setLocalRotation(rotation);

I noticed that the arrow would rotate towards out of the screen at 90 degrees, then downwards, then into the screen, then upwards. I suppose this is what is meant by rotating along the x-axis.

I am getting more confused by the statement that the documentation is wrong.

Something else that I have noticed is if I do the following:

rotation.fromAngles(0, 0, angle);

arrowShape.setLocalRotation(rotation);

When I use the following code to output the angles, I get some strange output.

float yawrollpitch[] = new float[3];

arrowShape.getLocalRotation().toAngles(yawrollpitch);

System.out.printf (“After set: %.2f %.2f %.2fnn”, yawrollpitch[0],yawrollpitch[1],yawrollpitch[2]);

Now, yawrollpitch gives the following output, where input is the angle that was placed in the code earlier:

Input: 0.00 0.00 4.71

After set: 0.00 -6.28 -1.57

What I am wondering, is why does that happen? It’s only supposed to rotate along one axis.

Wow. Looking at the file history, apparently *I* created this doc in 2007. The content sounds familiar, but I don’t remember publishing it.

“Roll” goes around X axis which goes along the length of the aircraft fuselage — if you look at it from the side.

“Yaw” is always around the Y axis (like shaking you head “no”).

“Pitch” means the nose of the plane goes down (nose dive) — if you look at the plane from the side, that goes around the Z axis.

So I’d say the variables are named wrong… :P The variable are “X = yaw, Y= roll, Z= pitch”… Yaw is never the X axis… not even if you look at the aircraft from the front.

I assume the person who implemented the algorithm used a book with a different convention / different coordinate system.

Question to the developers, do you want to refactor this? It’s “only” variable names, no accessors or constructors will be affected. (On the other hand, it’s a whole lot of variable names…)

Here’s the javadoc — the author obviously used a different convention: because I m pretty sure bank == roll?!

1 2 3 |
/ ** the Euler yaw of rotation (in radians). (aka Bank, often rot around x) * the Euler roll of rotation (in radians). (aka Heading, often rot around y) * the Euler pitch of rotation (in radians). (aka Attitude, often rot around z) **/ |

Weird.

PS: I just tested rotate(x,y,z) with a loaded model.

x is the axis going from left to right. — rot around x is roll/bank

y is the one going from bottom up. — rot around y is yaw

z goes towards to onlooker. — rot around z is pitch

I am looking at this explanation of “pitch, yaw, bank=roll” here

http://ministryoftype.co.uk/words/article/pitch_bank_and_yaw/

Apparently, aircraft call the downward axis Z…? Aaarrrggh.

naddie said:

Something else that I have noticed is if I do the following:rotation.fromAngles(0, 0, angle);

arrowShape.setLocalRotation(rotation);When I use the following code to output the angles, I get some strange output.

float yawrollpitch[] = new float[3];

arrowShape.getLocalRotation().toAngles(yawrollpitch);

System.out.printf (“After set: %.2f %.2f %.2fnn”, yawrollpitch[0],yawrollpitch[1],yawrollpitch[2]);Now, yawrollpitch gives the following output, where input is the angle that was placed in the code earlier:

Input: 0.00 0.00 4.71

After set: 0.00 -6.28 -1.57What I am wondering, is why does that happen? It’s only supposed to rotate along one axis.

Ignore what I wrote there. I noticed a rogue addition in the affected rotation command. How embarrassing.

I am using the fish model that is in the jmetest directory in the svn’s src directory, and I have the following code to test the rotations.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import com.jme.app.SimpleGame; import com.jme.scene.Node; import com.jme.math.Vector3f; import com.jme.math.Quaternion; // For model importing import java.net.URL; import com.jmex.model.ogrexml.MaterialLoader; import com.jmex.model.ogrexml.OgreLoader; import com.jmex.model.ogrexml.anim.MeshAnimationController; public class Rotate extends SimpleGame { Node n; public static void main(String[] args) { Rotate app = new Rotate(); // Create Object // Signal to show properties dialog app.setConfigShowMode(ConfigShowMode.AlwaysShow); app.start(); // Start the program } protected void simpleInitGame() { n = getOgreMesh(“fish.mesh.xml”, “Example.material”); n.setLocalTranslation(0,0,0); n.setLocalScale(0.2f); // that will throw nullpointer-exception if no animation is added!! MeshAnimationController animC = (MeshAnimationController)n.getController(0); // replace Action with the Animationname you want to play animC.setAnimation(“swim”); animC.setActive(true); rootNode.attachChild(n); // Put it in the scene graph } public static Node getOgreMesh(String mesh,String mat) { OgreLoader loader = new OgreLoader(); MaterialLoader matLoader = new MaterialLoader(); try { URL matURL = Rotate.class.getClassLoader().getResource(mat); URL meshURL = Rotate.class.getClassLoader().getResource(mesh); if (matURL != null){ matLoader.load(matURL.openStream()); if (matLoader.getMaterials().size() > 0) loader.setMaterials(matLoader.getMaterials()); } Node model = (Node) loader.loadModel(meshURL); return model; } catch (Exception e) { e.printStackTrace(); return null; } } protected void simpleUpdate() { float yawrollpitch[] = new float[3]; Quaternion rotation = new Quaternion(); rotation.fromAngles(0,1.57f,0); n.setLocalRotation(rotation); n.getLocalRotation().toAngles(yawrollpitch); //System.out.printf (“After set: %.2f %.2f %.2fnn”, yawrollpitch[0],yawrollpitch[1],yawrollpitch[2]); } } |

1 |
rotation.fromAngles(0,1.57f,0); |

1 |
rotation.fromAngles(1.57f,1.57f,0); |

1 |
rotation.fromAngles(0,1.57f,1.57f); |

This one gives the fish looking down.

With regards to the rotation, is it in the order of rotation around (x,y,z), or is it (z,y,x)? My brain is getting fried by this!

Thanks

Sorry to raise a dang ol’ zombie, but the problems in javadoc for the crucial Quaternion object appear to persist into JME3.

Javadoc for Quaternion.fromAngles() currently cites this reference:

http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm

which naturally leads us to this page of definitions:

http://www.euclideanspace.com/maths/standards/index.htm

…in which the author defines his site as adhering to a right-handed cartesian sytem with:

+X to the right

+Y straight up

+Z axis toward viewer

…which matches what the JME3 “for dummies” tutorials say, and what I’ve seen in most math books. So far, so good.

Then, for an airplane **flying towards a destination at X=+infinity**, as shown in the diagram at bottom of page

Heading = rotation about y axis = YAW – applied first

Attitude = rotation about z axis = PITCH – applied second

Bank = rotation about x axis = ROLL – applied third

…which matches how most other sources define these rotations conceptually, although as others have mentioned, the labeling of x,y,z axes is sometimes different.

However, our java method arguments are currently specified as:

fromAngles(float yaw, float roll, float pitch)

which the javadoc *explains* using this textual disaster, which was no doubt written by a sequential committee of well-meaning coders, who was each attempting to correct previous mistakes.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
* <code>fromAngles</code> builds a Quaternion from the Euler rotation * angles (y,r,p). Note that we are applying in order: roll, pitch, yaw but * we’ve ordered them in x, y, and z for convenience. * @see <a href="<a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm</a>" rel="nofollow">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm</a></a>; * * @param yaw * the Euler yaw of rotation (in radians). (aka Bank, often rot * around x) * @param roll * the Euler roll of rotation (in radians). (aka Heading, often * rot around y) * @param pitch * the Euler pitch of rotation (in radians). (aka Attitude, often * rot around z) |

To me (and I think to a large swath of the audience for JMonkeyEngine), this is one of the single most important methods in JME3, and I would like to be able to rely on the documentation. I hope that we can promptly update the docs and argument names here (and in the rest of the methods of Quaternion) so that they agree with each other and what the EuclideanSpace.com explanations say. (And, of course, confirm that the implementation code then matches those argument names and docs, in particular regarding the order of application of the angles). I am happy to help with this effort, though I am not currently a JME3 committer.

I find yaw, roll, pitch confusing each time, why not just use x,y,z? ^^ Anyway, yaw means rotation around Y, pitch means rotating around X and roll means rotating around Z if you take the default jme/opengl settings.

Yeah, the javadoc is still wrong.

The parameters should be: pitch, yaw, roll and the descriptions of those parameters are also wrong. And in a way that is not right except for the very strangest of coordinate systems: “yaw – the Euler yaw of rotation (in radians). (aka Bank, often rot around x)” Even if you use a Z-up coordinate system, that’s not right.

I don’t know why it hasn’t been fixed in all of this time… but I also don’t know why I haven’t fixed it myself. A long time ago, I started thinking about the parameters as xAxis, yAxis, zAxis and never think about the javadocs until it confuses someone else.

The diagram Normen posted sort of implies that direction of travel = out of the screen, which appeals to our intuition that “forward” is colinear with the way we face our screens, which is I think how @pspeed arrived at “pitch,yaw,roll”.

However, if we accept the convention of EuclideanSpace.com that [bold]the airplane is flying towards a destination at X=+infinity[/bold], then the JME3 parameters should be labeled something like:

roll_about_X, yaw_about_Y, pitch_about_Z

meaning -

roll = rotation about X

yaw = rotation about Y

pitch = rotation about Z

@Normen asked:

why not just use x,y,z?

Proposed Solution Part 1 – Change the param names to say “xRot, yRot, zRot”, then specify clearly what order these rotations are actually applied to construct our Quaternion rotation operator (because the rotation operator is non-commutative, as we all know quite well ;) )

THEN, we could simply leave it at that, and put a link to EuclideanSpace.com for people who want to go into airplane terminology. Or, we could continue on to:

Proposed Solution Part 2 – Get the airplane words correctly attached to the JMonkey X,Y,Z axes. The key to doing that is to correctly label (in our minds) the axes in Normen’s airplane diagram above. On the cited EuclideanSpace.com reference page that is currently in the Javadocs, the definition is that the X-Axis = Roll-Axis = Direction of Forward Travel, and the Y Axis = Yaw-Axis = Vertical-up for a level-flying plane (this contradicts Normen’s diagram in that EuclideanSpace.com chooses YAW = “up” rather than “down”, but the author there justifies his reasons and cites references and standards, and it matches the idea in JMonkey that positive-Y = “up”, so, can we just go with that?)

Again, in this labeling, the **Airplane’s destination is at X=+infinity**.

So then, to match up Normen’s airplane diagram with JMonkey’s definition of X=Right, Y=Up, Z=Out-of-screen towards us,

we merely rotate the plane so it is flying on our X-Axis, towards the right of our screens (and label yaw axis as “up”, not “down”), as shown on the diagram I cited at:

http://www.euclideanspace.com/maths/standards/index.htm

Then

JMonkey X axis = Roll-Axis = Bank-Axis

JMonkey Y axis = Yaw-Axis = Heading-Axis

JMonkey Z axis = Pitch-Axis = Attitude-Axis

In my own code, I am currently using

1 |
q.fromAngles(rot_X_bank, rot_Y_heading, rot_Z_attitude); |

to try to drown out the roar of incorrectly labeled yaw,roll.

I have verified that these interpretations are correct using the current JMonkey runtime.

All the above seems pretty unambiguous to me, if we are actually using EuclideanSpace.com as our reference. If we’re not, then let’s just fall back to proposed solution part #1 (xRot, yRot, zRot) – and please say what order they are applied in!

@stub22 said:

Sorry to contradict @pspeed, but I think the JME3 parameters, in airplane lingo, if we accept the convention of EuclideanSpace.com that the airplane is flying towards a destination at X=+infinity, should be:

No, we can’t accept that convention because in JME the camera is looking down the Z axis and Y axis is up.

So, yaw is rotation about the Y axis. Pitch is rotation about the X axis. Roll is rotation about the Z axis.

Since the fromAngles() method takes, essentially xAxis, yAxis, zAxis, that’s the same as pitch, yaw, roll.

You must be logged in to reply to this topic.