ODE + Irr rotation [codes!]

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
WToma
Posts: 70
Joined: Tue Aug 09, 2005 8:38 am
Location: Szeged, Hungary

ODE + Irr rotation [codes!]

Post by WToma »

Hi

I've been working on it for a long time, but I don't have a working solution: how can I convert ODE rotation matrices to Irr rotation vectors?

I've tried these so far:

(Where it seems that indices 1 and 2 are in the wrong order, it is because ODE's y vector is Irr's z and vv.)

http://www.euclideanspace.com/maths/geo ... /index.htm
To this, I first convert the dMatrix3d to dQuaternion first
The code derived from this:

Code: Select all

	float test=q[0]*q[2]+q[1]*q[3];
	if(test>0.449) {					//singularity @ N pole
		res[2]=2*atan2(q[0],q[3]);
		res[1]=-M_PI/2.0;
		res[0]=0.0;
	} else {
        if(test<-0.449) {				//singularity @ S pole
    		res[2]=-2*atan2(q[0],q[3]);
    		res[1]=M_PI/2.0;
    		res[0]=0.0;

    	} else {						//no singularity

            float sqx=q[0]*q[0];
            float sqy=q[2]*q[2];
            float sqz=q[1]*q[1];

            res[2]=atan2((float)(2*q[2]*q[3]-2*q[0]*q[1]),(float)(1-2*sqy-2*sqz));
            res[1]=asin(2*test);
            res[0]=atan2((float)(2*q[0]*q[3]-2*q[1]*q[2]),(float)(1-2*sqx-2*sqz));
    	}
    }
    res[0]+=M_PI;
	float RD=180.0/M_PI;
	res[0]*=RD;res[1]*=RD;res[2]*=RD;
This produces some intersting results, but not what I want :(
A 'bit' simplified version:

Code: Select all

    float sqx=q[0]*q[0];
    float sqy=q[2]*q[2];
    float sqz=q[1]*q[1];
    
    float test=q[0]*q[2]+q[1]*q[3];

    res[0]=atan2((float)(2*q[2]*q[3]-2*q[0]*q[1]),(float)(1-2*sqy-2*sqz));
    res[1]=atan2((float)(2*q[0]*q[3]-2*q[1]*q[2]),(float)(1-2*sqx-2*sqz));
    res[2]=asin(2*test);

    res[1]+=M_PI;
    float RD=180.0/M_PI;
    res[0]*=RD;res[1]*=RD;res[2]*=RD;
This works well excepted when rotating around Z axis. In this case, the body makes 180° jumps.
This doesn't use quaternions, the algorythm is taken from
http://web.archive.org/web/200410290038 ... t.html#Q37

Code: Select all

    flatd[1]=asin(ode_par[2]);        /* Calculate Y-axis angle */
    float C=cos(flatd[2]);
    flatd[1]=(C/M_PI)*180.0;

    if(fabs(C)>0.005) {	//Gimball lock?
        float tr_x=ode_par[10]/C;           // No, so get X-axis angle
        float tr_y=-ode_par[6]/C;
        flatd[0]=(atan2(tr_y,tr_x)/M_PI)*180.0;
        tr_x=ode_par[0]/C;            // Get Z-axis angle
        tr_y=-ode_par[1]/C;
        flatd[2]=(atan2(tr_y,tr_x)/M_PI)*180.0;
    } else {	// Gimball lock has occurred
        flatd[0]=0;                      // Set X-axis angle to zero
        float tr_x=ode_par[5];                 // And calculate Z-axis angle
        float tr_y=ode_par[4];
        flatd[2]=(atan2(tr_y,tr_x)/M_PI)*180.0;
    }
Bad, too. Rotates without any sense :)
The last thing I tried was to convert ODE quaternions to irr quaternions

Code: Select all

core::vector3df ode_rot_2_v3df(const dReal* ode_par) {
    float RD=180.0/M_PI;
    dQuaternion ode_q;
    dRtoQ(ode_par,ode_q);
    core::quaternion irr_q(ode_q[0]*RD,ode_q[2]*RD,ode_q[1]*RD,ode_q[3]*RD);
    core::vector3df res;
    irr_q.toEuler(res);
    return res;
}
This is the most intresting, it doesn't do anything visible. :D

So: what's the correct way to do this? Or what's wrong with these codes?
Thx

Toma
"This is not a bug, this is a feature!"
WToma
Posts: 70
Joined: Tue Aug 09, 2005 8:38 am
Location: Szeged, Hungary

Post by WToma »

Heh, very intresting what I found.
First, see this: http://thomas.webtracker.ch/jahia/Jahia/pid/481
Guide on using ODE with Irr.
Then.
See the QuaternionToEuler method. Works well. Now, at the very end of the algorythm, change Z and Y values. Makes that intresting 180° jumps I found before.
What the h*ll is this??
Will check it out...

Toma
"This is not a bug, this is a feature!"
WToma
Posts: 70
Joined: Tue Aug 09, 2005 8:38 am
Location: Szeged, Hungary

Post by WToma »

OK. So, I must tell you that I don't know why the rotating body starts to make jumps if I try to change the y-z axes. Really. It seems that it's a bug of every commonly used quaternion-to-euler algorythm (even my own code works if I re-order the axes). Very strange, but I we must live with it. Have a nice coding day ;)
Toma
"This is not a bug, this is a feature!"
Guest

Post by Guest »

Check this:

http://www.lofing.de/simulator/modules/news/

here it seemes to be solved...
Post Reply