Home › Forum › Troubleshooting › General › Definition of pitch, yaw, roll in jMonkeyEngine
This topic contains 22 replies, has 6 voices, and was last updated by stub22 2 years, 7 months ago.

AuthorPosts

September 29, 2010 at 09:25 #16818
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 Xaxis, Yaw becomes rotation in the
Yaxis and Roll becomes rotation in the Zaxis.Why is there a difference between them?
September 29, 2010 at 12:36 #114390jME uses a right handed coordinate system.
Cheers,
NormenSeptember 30, 2010 at 10:26 #114391Thanks for the info. That explains why there seemed to be differences in definitions.
September 30, 2010 at 12:15 #114392I 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 zOctober 2, 2010 at 10:47 #114393nehon 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 zSo, 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 xaxis.
I am getting more confused by the statement that the documentation is wrong.
October 2, 2010 at 11:27 #114394Something 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.
October 2, 2010 at 18:04 #114395Wow. 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?!
Java123/ ** 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.
October 2, 2010 at 19:00 #114396PS: 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 pitchI 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.
October 3, 2010 at 12:09 #114397naddie 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.
October 3, 2010 at 15:36 #114398I 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.
Java1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162import com.jme.app.SimpleGame;import com.jme.scene.Node;import com.jme.math.Vector3f;import com.jme.math.Quaternion;// For model importingimport 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 dialogapp.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 nullpointerexception if no animation is added!!MeshAnimationController animC = (MeshAnimationController)n.getController(0);// replace Action with the Animationname you want to playanimC.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]);}}Java1rotation.fromAngles(0,1.57f,0);Java1rotation.fromAngles(1.57f,1.57f,0);Java1rotation.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
March 15, 2012 at 09:58 #114399Sorry 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 righthanded 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 wellmeaning coders, who was each attempting to correct previous mistakes.
Java1234567891011121314* <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.March 15, 2012 at 11:01 #114400I 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.
March 15, 2012 at 14:51 #114401Yeah, 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 Zup 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.
March 17, 2012 at 07:45 #114402The 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 noncommutative, 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 XAxis = RollAxis = Direction of Forward Travel, and the Y Axis = YawAxis = Verticalup for a levelflying 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 positiveY = “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=Outofscreen towards us,
we merely rotate the plane so it is flying on our XAxis, 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 = RollAxis = BankAxis
JMonkey Y axis = YawAxis = HeadingAxis
JMonkey Z axis = PitchAxis = AttitudeAxisIn my own code, I am currently using
Java1q.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!
March 17, 2012 at 07:48 #114403@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.

AuthorPosts
You must be logged in to reply to this topic.