Unexpected behaviour of getOrientation and/or rotations
Moderator: PPS-Leaders
Unexpected behaviour of getOrientation and/or rotations
So, I'm working on the turret and I ran into some problems. Depending on how the turret gets rotated inside the level file, getOrientation returns different values for yaw, pitch and roll. Here's a beautiful picture to illustrate what happens: http://oi60.tinypic.com/ngsh81.jpg
The values to the left are how they are in the level file, and the picture below how the turret appears in the game. The arrows illustrate, in which direction the turret rotates for the corresponding function. I also let the turret rotate on every axis, and looked at the values for getOrientation, to determine which angle changes (Meas.). ??? means that I couldn't make sense of the output, because all angles seemed to change and/or take on strange values.
As you can see, the coordinate system gets rotated correctly for the rotate functions, but not for the measured angles of getOrientation. I'm not sure where the mistake is here. I took a look throught the functions that get called when the turret gets rotated at the beginning of the level, but didn't find anything obviously wrong. Or am I doing something wrong? I'm pretty clueless at this point...
The values to the left are how they are in the level file, and the picture below how the turret appears in the game. The arrows illustrate, in which direction the turret rotates for the corresponding function. I also let the turret rotate on every axis, and looked at the values for getOrientation, to determine which angle changes (Meas.). ??? means that I couldn't make sense of the output, because all angles seemed to change and/or take on strange values.
As you can see, the coordinate system gets rotated correctly for the rotate functions, but not for the measured angles of getOrientation. I'm not sure where the mistake is here. I took a look throught the functions that get called when the turret gets rotated at the beginning of the level, but didn't find anything obviously wrong. Or am I doing something wrong? I'm pretty clueless at this point...
Re: Unexpected behaviour of getOrientation and/or rotations
This is indeed curious behavior. I would assume that we probably would have found that problem earlier if it's a problem that is deep down somewhere in how Ogre handles rotations. So it's probably up higher somewhere. Is somebody using this getOrientation function already and is a similar behavior observed in those classes?
"I'm Commander Shepard and this is my favorite forum on the internet."
Re: Unexpected behaviour of getOrientation and/or rotations
getOrientation is used quite heavily in all the higher classes (Pawn+), but only deals with the quaternions. I found only two cases that actually use the values for pitch/yaw/roll, but also only very briefly (I think it's the fpsPlayer and the rocket). But I don't think they have the same problem, because they both have no rotation defined in the level file. Could there be a problem with local and global axes? I saw that objects get rotated with respect to their local axes when there's a rotation in the xml. Maybe getOrientation uses the global axes or something like that? I'm mucking around with quaternions right now to somehow recreate the problem without all the game stuff, but no luck so far...
Re: Unexpected behaviour of getOrientation and/or rotations
Yes, I think that might be it. Different coordinates (local instead of global or vice versa) was my first guess when I saw your problem last Thursday. The fact that your measurements without prior rotation are correct adds credence to this cause as well.
Quaternions are a bitch. I worked with them back when I was in the PPS back in old Orxonox. I would advice against using them directly whenever possible. Nevertheless, all you need to do is get the local rotation quaternion and extract roll, pitch and yaw from there to get absolute values for your measurements... I think. However it's possible you can't access that information, if it's not saved or made accessible.
As you probably already know multiplying Quaternions will combine them to one rotation so applying roll, pitch and yaw locally to the global quaternion you just need to multiply it with a local roll/pitch/yaw quaternion.
Quaternions are a bitch. I worked with them back when I was in the PPS back in old Orxonox. I would advice against using them directly whenever possible. Nevertheless, all you need to do is get the local rotation quaternion and extract roll, pitch and yaw from there to get absolute values for your measurements... I think. However it's possible you can't access that information, if it's not saved or made accessible.
As you probably already know multiplying Quaternions will combine them to one rotation so applying roll, pitch and yaw locally to the global quaternion you just need to multiply it with a local roll/pitch/yaw quaternion.
"I'm Commander Shepard and this is my favorite forum on the internet."
Re: Unexpected behaviour of getOrientation and/or rotations
I don't understand your question and I don't understand your picture. But maybe it helps if I explain the basics of rotations.
In 2D space...
In 3D space...
In Orxonox, WorldEntity.getOrientation() returns a quaternion (what else? it defines a rotation). You are not expected to gain any meaningful insights from looking at the 4 values of a quaternion. They are not necessarily equal to rotations around some axis.
If you define a rotation in XML, you can use different possibilities:
In case you don't:
Also, WorldEntity.getOrientation() always returns the local orientation (i.e. relative to the parent object). If you really want the absolute orientation (and usually you won't), you can use WorldEntity.getWorldOrientation().
For position we have the same behaviour if you use WorldEntity.getPosition() or WorldEntity.getWorldPosition(). But remember that using global orientation/position is really bad style in most cases.
Finally one remark about yaw/pitch/roll angles: If you define a rotation in XML by using more than one of these three angles, your object may look in an unexpected direction. This is because the rotations around the three angles are applied in sequential order, so each rotation depends on the previous one (and it's NOT the sequence that you use in XML - it's the sequence which is defined in WorldEntity::XMLPort()).
If you really want to work correctly with yaw/pitch/roll you have to use the Euler angles. This is another way to represent a rotation in 3D space and it is supported by Ogre, but I think we currently don't use it in Orxonox.
So I still don't understand your question, but I guess that you simply looked at the wrong values... or you looked at them with the wrong expectations. But after reading this post you probably realize that rotation in 3D space is really simple stuff.
In 2D space...
- a point can be expressed as vector or an imaginary number (defined by two values, either x/y or radius/angle).
- a rotation can be expressed as an imaginary number with radius = 1
In 3D space...
- a point can be expressed as a vector
- a rotation can be expressed as a quaternion with radius = 1 (a quaternion is something like an imaginary number (in 3 dimensions) with 1 real and 3 imaginary parts)
In Orxonox, WorldEntity.getOrientation() returns a quaternion (what else? it defines a rotation). You are not expected to gain any meaningful insights from looking at the 4 values of a quaternion. They are not necessarily equal to rotations around some axis.
If you define a rotation in XML, you can use different possibilities:
- orientation="w,x,y,z" (this is a quaternion)
- lookat="x,y,z" (this is a point in space)
- direction="x,y,z" (this is a vector)
- yaw="d" (rotate d degrees around the Y axis - "left/right")
- pitch="d" (rotate d degrees around the X axis - "up/down")
- roll="d" (rotate d degrees around the Z axis - turn your screen upside-down)
In case you don't:
Also, WorldEntity.getOrientation() always returns the local orientation (i.e. relative to the parent object). If you really want the absolute orientation (and usually you won't), you can use WorldEntity.getWorldOrientation().
For position we have the same behaviour if you use WorldEntity.getPosition() or WorldEntity.getWorldPosition(). But remember that using global orientation/position is really bad style in most cases.
Finally one remark about yaw/pitch/roll angles: If you define a rotation in XML by using more than one of these three angles, your object may look in an unexpected direction. This is because the rotations around the three angles are applied in sequential order, so each rotation depends on the previous one (and it's NOT the sequence that you use in XML - it's the sequence which is defined in WorldEntity::XMLPort()).
If you really want to work correctly with yaw/pitch/roll you have to use the Euler angles. This is another way to represent a rotation in 3D space and it is supported by Ogre, but I think we currently don't use it in Orxonox.
So I still don't understand your question, but I guess that you simply looked at the wrong values... or you looked at them with the wrong expectations. But after reading this post you probably realize that rotation in 3D space is really simple stuff.
Fabian 'x3n' Landau, Orxonox developer
Re: Unexpected behaviour of getOrientation and/or rotations
The problem originates from the turret. We want to limit the rotation of the moving part of the turret to only look in certain directions. However for some reason, this seems to be harder than expected. I would expect the moving part being attached to the stationary part or both parts are attached to one virtual object node. Of course global orientation is irrelevant, because we want to limit rotation relative to the stationary part.
"I'm Commander Shepard and this is my favorite forum on the internet."
Re: Unexpected behaviour of getOrientation and/or rotations
Okay, so here's a breakdown on what I wanted to do:
- Save the rotation of the turret as soon as the level loaded
- When the turret wants to rotate, check if it's allowed to do so (i.e. keep the pitch/yaw/roll within some arbitrary interval)
- If the current pitch/yaw/roll is too far away from the orientation, don't rotate on that axis (in that direction)
What I checked was basically abs(startOrientation.pitch - currentOrientation.pitch) <= limit, and for the other angles the same. This plan fell through though, because as soon as the turret gets rotated inside the xml, the angles are (seemingly) all out of whack. That is illustrated on my picture; e.g. if I use rotatePitch, the yaw changes. I guess it's a bit hard to know what I mean without seeing it for yourself.
I found an alternative approach in the meantime. If I multiply the current orientation by the inverse of the starting orientation, and get the angles of the resulting quaternion, the angles are just what I expect (kind of like undoing a coordinate transformation, I guess?). This seems to work OK for now, but it's a bit hard to be sure of it...
Isn't there some standard approach to limit the rotation of an object with quaternions? Looks like rotations are easy as long as you don't need to look at and interpret the values...
- Save the rotation of the turret as soon as the level loaded
- When the turret wants to rotate, check if it's allowed to do so (i.e. keep the pitch/yaw/roll within some arbitrary interval)
- If the current pitch/yaw/roll is too far away from the orientation, don't rotate on that axis (in that direction)
What I checked was basically abs(startOrientation.pitch - currentOrientation.pitch) <= limit, and for the other angles the same. This plan fell through though, because as soon as the turret gets rotated inside the xml, the angles are (seemingly) all out of whack. That is illustrated on my picture; e.g. if I use rotatePitch, the yaw changes. I guess it's a bit hard to know what I mean without seeing it for yourself.
I found an alternative approach in the meantime. If I multiply the current orientation by the inverse of the starting orientation, and get the angles of the resulting quaternion, the angles are just what I expect (kind of like undoing a coordinate transformation, I guess?). This seems to work OK for now, but it's a bit hard to be sure of it...
Isn't there some standard approach to limit the rotation of an object with quaternions? Looks like rotations are easy as long as you don't need to look at and interpret the values...
Re: Unexpected behaviour of getOrientation and/or rotations
I understand that the values of getOrientation() are confusing, but they are not the yaw/pitch/roll values.
If you want yaw/pitch/roll values, use Quaternion.getYaw()/getPitch()/getRoll(), but they are not necessarily the same values that used to rotate the object because rotations are not unique.
Ogre's reference of the Quaternion class: http://www.ogre3d.org/docs/api/1.9/clas ... rnion.html
Some details about rotations: http://www.ogre3d.org/tikiwiki/Quaterni ... ion+Primer
Also remember that Ogre is a widely used library, so you will likely find some resources otherwise in the web. Here are some discussions about this topic:
http://www.ogre3d.org/forums/viewtopic.php?f=2&t=75678
http://www.ogre3d.org/forums/viewtopic.php?f=2&t=80494
http://www.ogre3d.org/tikiwiki/tiki-ind ... ight=euler
If you want yaw/pitch/roll values, use Quaternion.getYaw()/getPitch()/getRoll(), but they are not necessarily the same values that used to rotate the object because rotations are not unique.
Ogre's reference of the Quaternion class: http://www.ogre3d.org/docs/api/1.9/clas ... rnion.html
Some details about rotations: http://www.ogre3d.org/tikiwiki/Quaterni ... ion+Primer
Also remember that Ogre is a widely used library, so you will likely find some resources otherwise in the web. Here are some discussions about this topic:
http://www.ogre3d.org/forums/viewtopic.php?f=2&t=75678
http://www.ogre3d.org/forums/viewtopic.php?f=2&t=80494
http://www.ogre3d.org/tikiwiki/tiki-ind ... ight=euler
Fabian 'x3n' Landau, Orxonox developer
Re: Unexpected behaviour of getOrientation and/or rotations
getOrientation returns a quaternion, and on that I use getYaw/Pitch/Roll. I don't use the actual values of the quaternion, if that's what you mean. I read up about quaternions and how they work and whatnot, but in the end I still have to somehow have angles, or something I can compare, to see if the turret rotated too far. And if the angles are not necessarily the ones I expect, how can I do that? To make it even more complex, the actual rotation is done by bullet and not me, so I don't really have full control over that.
Also, the problem with all the stuff on the web is, that most of the questions remain unsolved and/or have different premises. I don't want to end up with a class that works completely different than all the others.
Also, the problem with all the stuff on the web is, that most of the questions remain unsolved and/or have different premises. I don't want to end up with a class that works completely different than all the others.
Re: Unexpected behaviour of getOrientation and/or rotations
There's no general answer to your problem because it depends on how you want to limit the turrets rotation.
Can it freely yaw/pitch/roll as long as it happens in the "upper hemisphere"? => Let D be the original viewing direction of the object, then D*object.getOrientation() is the current viewing direction. The angle between them must be <= 90°
Can it only rotate freely around one axis, but not around others? => again vector math, ensure that the viewing direction remains the same
Can it only use yaw and pitch but no roll? => this is related to the "FPS player problem", see http://www.ogre3d.org/tikiwiki/Quaterni ... _rotations_
The last point (+ link) is especially valuable because it points out the fact that you can rotate a SceneNode in different transform spaces - local, parant, and world. This includes the possibility to calculate (with vector math) how far an object has rotated relative to a parent object.
Can it freely yaw/pitch/roll as long as it happens in the "upper hemisphere"? => Let D be the original viewing direction of the object, then D*object.getOrientation() is the current viewing direction. The angle between them must be <= 90°
Can it only rotate freely around one axis, but not around others? => again vector math, ensure that the viewing direction remains the same
Can it only use yaw and pitch but no roll? => this is related to the "FPS player problem", see http://www.ogre3d.org/tikiwiki/Quaterni ... _rotations_
The last point (+ link) is especially valuable because it points out the fact that you can rotate a SceneNode in different transform spaces - local, parant, and world. This includes the possibility to calculate (with vector math) how far an object has rotated relative to a parent object.
Fabian 'x3n' Landau, Orxonox developer
Re: Unexpected behaviour of getOrientation and/or rotations
Okay, I guess I'll end up doing some vector math, then. I'm still not sure if the turret should be allowed to roll, though. I mean, a 90° rotation of the pitch is the same as 90° roll and then 90° yaw, right? My idea was that it shouldn't rotate around itself (like a gatling gun, if you know what I mean), but this seems like a mistake to me now. I guess I'll have to experiment around a bit. Thanks for the help though.
Who is online
Users browsing this forum: No registered users and 1 guest