Quaternion -> Euler causing erratic behaviour

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Lorian
Posts: 20
Joined: Sat Feb 10, 2007 9:20 am
Location: United Kingdom
Contact:

Quaternion -> Euler causing erratic behaviour

Post by Lorian »

I am trying to use ODE for my physics engine and it is working ok, but there is a problem that keeps cropping up when I try to convert from the ODE quaternion to the Irrlicht Euler rotation.

I have tried with several formulas, including the built-in one in Irrlicht, but it happens with all of them. Here is one:

Code: Select all

irrRotation.X = atan2(2. * (y * z + x * w), (-sqx - sqy + sqz + sqw)) * irr::core::RADTODEG;
irrRotation.Y = asin(-2. * (x * z - y * w)) * irr::core::RADTODEG;
irrRotation.Z = atan2(2. * (x * y + z * w), ( sqx - sqy - sqz + sqw)) * irr::core::RADTODEG;
In my test program it is basically just a bunch of falling boxes colliding into each other. This one has become still, yet the resultant number changes each time. The block just spins randomly and flashes in and out (see the nan in the last one).

Converted Euler: -73.2696 -90 82.7662
ODE Quaternion: 0.70468 0.0585334 -0.70468 0.0585334

113.891 -90 -104.395
0.70468 0.0585334 -0.70468 0.0585334

115.794 -90 -106.298
0.70468 0.0585334 -0.70468 0.0585334

89.6402 -90 -80.1436
0.70468 0.0585334 -0.70468 0.0585334

74.2572 nan -64.7606
0.70468 0.0585334 -0.70468 0.0585334

Does anyone know what could be causing this? And how to fix it?

Cheers.

EDIT: This only happens when the block has become still, when it's moving it is fine, but sometimes when it stops moving, this happens.
Lorian
Posts: 20
Joined: Sat Feb 10, 2007 9:20 am
Location: United Kingdom
Contact:

Post by Lorian »

I have found this on Wikipedia:
One must be aware of singularities in the Euler angle parametrization when the pitch approaches ±90° (north/south pole). These cases must be handled specially.
This is presumably the problem I am experiencing because the pitch is -90°. Thing is, I don't know how I am supposed to handle it... Any ideas?

Cheers.

EDIT: A search on Google has found this:

Code: Select all

inline vector3df quaternion::toEuler() const
{
/* new version after euclideanspace.com by Matthias Meyer
   old version had a problem where the initial quaternion
	 would return -0 for Y value and NaN for rotation of 1.5708
	 around Y-axis when using fromangleaxis() */

	vector3df euler;
	f64 testValue = X * Y + Z * W;
	if(testValue > 0.499f) // north pole singularity
	{
		euler.Y = (f32) (2 * atan2(X,W));
		euler.Z = (f32) (M_PI_HALF);
		euler.X = 0.0f;
		return euler;
	}
	if(testValue < -0.499f) // south pole singularity
	{
		euler.Y = (f32) (-2 * atan2(X,W));
		euler.Z = (f32) (-M_PI_HALF);
		euler.X = 0.0f;
		return euler;
	}
	f64 sqx = X*X;
	f64 sqy = Y*Y;
	f64 sqz = Z*Z;
	f64 sqw = W*W;
	f64 unit = sqx + sqy + sqz + sqw;

	euler.Y = (f32) atan2( 2.0*Y*W - 2.0*X*Z, sqx - sqy - sqz + sqw );
	euler.Z = (f32) asin ( 2.0 * testValue / unit );
	euler.X = (f32) atan2( 2.0*X*W - 2.0*Y*Z, -sqx + sqy - sqz + sqw );

	return euler;
}
It is basically a modified version of the Irrliicht toEuler() function to handle singularities. I'm not home at the moment so I can't try it, but if it works it might be a good patch candidate?
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

I *think* I fixed this in svn a couple of days ago, the NaNs are caused by values >+1 or <-1 being passed to asin so I just put a check in for it.

edit: mm765's version looks much better, so I think we should use it. Also it's probably had a lot more testing than ours as I think LightFeather uses quaternions internally. I'll ask him if it's ok to use it before committing.

Hmm.. I wonder what other changes he's made to the core classes.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Post Reply