quaternion/matrix euler angles confusion

magicchicken
Posts: 11
Joined: Tue Dec 09, 2008 9:42 pm

quaternion/matrix euler angles confusion

Post by magicchicken »

I think there's an error with building a bullet matrix from euler angles

Here's the code I used to test euler angles to matrix to quaternion.

Code: Select all

// build a matrix from euler angles
btMatrix3x3 btMat;
btMat.setEulerYPR( yaw, pitch, roll );

// convert the matrix to a quaternion
btQuaternion btFromMat;
btMat.getRotation( btFromMat );
And here's the code I tested it against, just euler angles to quaternion:

Code: Select all

btQuaternion btQuat;
btQuat.setEuler( yaw, pitch, roll );
They should match up (or at least be close due to numerical issues), but they don't.

Actually, as I'm writing this i look into bullet's code, and maybe I see the issue:

Code: Select all

void btMatrix3x3::setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 
{
    setEulerZYX(roll, pitch, yaw);
}
It says that YAW is about the Y-axis, PITCH is about the X-axis, and ROLL is about the Z-axis. But when it passes it onto setEulerZYX() it puts PITCH in the Y-axis, and YAW in the X-axis. Well that's going by the function name, the parameter names and comments make it slightly more confusing for me...

Code: Select all

	/** @brief Set the matrix from euler angles YPR around ZYX axes
	* @param eulerX Roll about X axis
	* @param eulerY Pitch around Y axis
	* @param eulerZ Yaw aboud Z axis
	* 
	* These angles are used to produce a rotation matrix. The euler
	* angles are applied in ZYX order. I.e a vector is first rotated 
	* about X then Y and then Z
	**/
	void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
magicchicken
Posts: 11
Joined: Tue Dec 09, 2008 9:42 pm

Re: quaternion/matrix euler angles confusion

Post by magicchicken »

No matter the order of parameters I can't get the two to match up.

Euler angles -> Matrix -> Quaternion
Euler angles -> Quaternion

I tried every possible permutation of yaw, pitch, roll, including negative ones (I think that's 56 possibilities ). None of them would give the same result. I'm guess that the math in the two paths

Code: Select all

btMatrix3x3::setEulerZYX()
btMatrix3x3::getRotation()
and

Code: Select all

btQuaternion::setEuler()
just won't ever line up no matter how i swing the inputs :(
magicchicken
Posts: 11
Joined: Tue Dec 09, 2008 9:42 pm

Re: quaternion/matrix euler angles confusion

Post by magicchicken »

Code: Select all

	/**@brief Get the matrix represented as euler angles around ZYX
	* @param yaw Yaw around X axis
	* @param pitch Pitch around Y axis
	* @param roll around X axis
	* @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/	
	void btMatrix3x3::getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
yaw is the X-axis here? why doesn't it match up setEulerZYX()

I get that there's also getEulerYPR(), which does matches up with setEulerYPR(). But otherwise i'm just totally lost as to which axis has which name :(
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: quaternion/matrix euler angles confusion

Post by Flix »

I had already covered this issue in a very old post... http://bulletphysics.org/Bullet/phpBB3/ ... lit=Matrix
I suggest you to carefully read all my entries there.

I described one robust way I can use to go from Euler angles (YPR) to Quaternions/Matricies and back (note that in some cases there can be multiple solutions: in these cases I chose the ones in which the roll is zero).

I used the YXZ order, which should be (according to my tests) compatible with:

Code: Select all

// btQuaternion q(fYAngle,fPAngle,fRAngle);   
// btMatrix3x3 m; m.setRotation(q);

but not with:

Code: Select all

btMatrix3x3::setEulerYPR(fYAngle,fPAngle,fRAngle)
To me it seems the easiest set, even if a lot of other programs (like the default Bullet OpenGL library and Bullet Game Kit if I remember correctly), works with the default setEuler/getEuler methods included with Bullet without any problem (you can check their code if you want to stick to the Bullet methods).