Quaternion::getYaw() returns NaN (not defined)

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Quaternion::getYaw() returns NaN (not defined)

Post by Beauty »

I found out that the function Quaternion::getYaw() returns a NaN (not defined) value for some special cases.

The special cases are:

Yaw = +/- 90 degree (positive 90 or negative 90)
Pitch = random
Roll = 0 degree


The result I got from a test code written in C#.
node is a SceneNode.
The Euler Angles are referenced by the variables yaw, pitch, roll.

Code: Select all

// create quaternion and apply rotations
node.Orientation = new Quaternion(new Degree(yaw), Vector3.UNIT_Y);
node.Pitch(new Degree(pitch), Node.TransformSpace.TS_LOCAL);
node.Roll(new Degree(roll), Node.TransformSpace.TS_LOCAL);

quat = node.Orientation; // get quaternion

result = quat.Yaw.ValueDegrees;  // get yaw value
Questions:
Is the return of a NaN (not defined) value a bug?
If not, what's the reason?

I think it's very bad, when Quaternion::getYaw() returns an undefined value in some special cases.
This behaviour was the reason of infrequently application crashes. It tooks some time to find out the reason. Similar problems could happen to other developers. So we should avoid NaN return if possible.

Note:
I use Ogre (Mogre) 1.6.5.
Maybe the bug is still fixed in newer version.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7154
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 525

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Kojack »

Does Mogre use Ogre's math code for quaternions? I think it used it's own vector math instead of wrapping ogre's for performance.
If so, it might not have the same protection.
getYaw does an asin operation. This MUST be given a value between -1 to 1. Outside of that range will cause a nan. Even slight floating point errors like 1.000001 will fail. Ogre provides Math::ASin, which protects asin from being called with bad values. The Ogre getYaw function calls Math::ASin, but maybe the Mogre getYaw is doing asin directly.
That's the only operation in there that could cause a nan, assuming that the quaternion didn't contain a nan to start with.

There are problems with the getYaw and related functions though. I was testing them a few days ago (while making a new version of my Euler class) and I found that the returned values are wrong in many cases. Not just the usual thing where several different combination of eulers result in the same quaternion, this was giving results that were mirrored along the x or y axes. Converting the quaternion to a matrix3, then calling one of the toeuler methods gave the correct results.

I haven't had time to look into it more yet.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Beauty »

Thanks for your answer.
You got a good idea. I will look to the Mogre source code.

Also thanks for the hint to use the rotation matrix for better results.
Did you publish your Euler Angle class?
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7154
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 525

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Kojack »

The euler class is on the wiki, but I'm rewriting it to be better. Work's been pretty heavy though, I haven't had much time for ogre coding (except when it's directly for work).
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Beauty »

Ok, I found it (and added some wiki tags):
http://www.ogre3d.org/tikiwiki/Euler+Angle+Class
Kojack wrote:I'm rewriting it to be better

Did you rewrite it in the last 3 months?
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Beauty »

Kojack wrote:Does Mogre use Ogre's math code for quaternions? [...]
Ogre provides Math::ASin, which protects asin from being called with bad values. The Ogre getYaw function calls Math::ASin, but maybe the Mogre getYaw is doing asin directly.
That's the only operation in there that could cause a nan [...]
Today I looked to the Mogre source code.
Your suggestion was a good point. :D
Radian Quaternion::Yaw::get()
{
return Radian(System::Math::Asin(-2*(x*z - w*y)));
}
I will post it in the Mogre forum.
Either we use the (wrapped) Ogre function instead or use it's improved code.

Thanks !!

Kojack wrote:I found that the returned values are wrong in many cases.
What do you think about integration of your improved Euler Class to the official Ogre code?
This would prevent headache of other users, too.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7154
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 525

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Kojack »

What do you think about integration of your improved Euler Class to the official Ogre code?
I wouldn't mind having it added in.
But it needs some repairs first. It's angles are opposite direction compared to ogre (there were reasons for that, but I don't believe them any more).

I tend to get distracted thinking about ways to make it configurable (set each axis to wrapping, limited, etc) but fast, which usually ends up as a mess of template parameters.
I'm on holidays soon, I'll try fixing it up then.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Beauty »

A configurable class would be fine.
I confirm that performance should be an important point.

Perhaps your class doesn't become "default".
But as optional class it could be useful.

It could be used as "converter" class, where each instance is responsible only for one quaternion (or a SceneNode).
The constructor could receive a reference to the quaternion or SceneNode. (Instead of creating a copy.)
Then you can apply optional configuration settings.
As result you just query values from this class instance.

For usage of multiple quaterions/SceneNodes you could offer a related update method.

Here is a code example

Code: Select all

// setup
EulerConverter ec = new EulerConverter(mySceneNode.Orientation);
ec.WrapXAxis = true;
ec.AngleUnit = Ogre.Math.AngleUnit.AU_DEGREE;
// query
Single myYaw = ec.getYaw();
// change usage to other quaternion
ec.relatedQuaternion(otherNode.Orientation);
Well, this is just an idea.
For now enjoy your holidays. :D
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Re: Quaternion::getYaw() returns NaN (not defined)

Post by CABAListic »

Is it necessary to add it to Ogre? Ogre doesn't need it, and if you want to use it, you can just add it to your project; from the looks of it the class is functioning on its own.
Just saying, the general consensus was to make Ogre leaner and more modular, so I'm not sure that adding additional utility classes is advisable.
User avatar
Beauty
OGRE Community Helper
OGRE Community Helper
Posts: 767
Joined: Wed Oct 10, 2007 2:36 pm
Location: Germany
x 39
Contact:

Re: Quaternion::getYaw() returns NaN (not defined)

Post by Beauty »

Kojack wrote:
What do you think about integration of your improved Euler Class to the official Ogre code?
I wouldn't mind having it added in. [...]
I tend to get distracted thinking about ways to make it configurable.
Well, my suggested solution also can be used as external class.
It was just an idea how a flexible query could be implemented.

Sometimes it's a good thing to add useful things to the Ogre core, although there is no absolutely need.
On the other hand you are right, that the core shouldn't be unnecessarily blowed up.
Help to add information to the wiki. Also tiny edits will let it grow ... :idea:
Add your country to your profile ... it's interesting to know from where of the world you are.
eddy
Gnoblar
Posts: 4
Joined: Sat Aug 06, 2011 2:00 pm

Re: Quaternion::getYaw() returns NaN (not defined)

Post by eddy »

So, how is this getting along? I have implemented some Roll and Pitch joints, and so far I didn't get a NaN result. Now I am torn between using the inbuilt system vs making an own function.

And, can we expect the YAW co-domain return values to be fixed to give results like ROLL and PITCH?
Post Reply