Gimbal lock and quaternion rotation issue

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
Squirrel
Posts: 4
Joined: Fri Dec 21, 2012 4:32 pm

Gimbal lock and quaternion rotation issue

Post by Squirrel »

Hi all,

I'am new to Irrlicht and i'm trying to solve a node rotation issue for about a week.

I searched through the forum and found explanations about the "gimbal lock" problem and a way to avoid it using quaternions.

so, i wrote the following function which works fine except when a node is previously rotated -90.0 degrees on the Y axis (then, Z axis rotations are locked).
I think I misunderstood something about the gimbal lock and/or the use of quaternions to avoid it... or maybe I just did something wrong with my code.

Code: Select all

 
void QRotate(ISceneNode* node, float angle, vector3df axis)    // Quaternion Rotation
    {
    quaternion quat_rot, quat_old;
     
    quat_rot.fromAngleAxis(angle*DEGTORAD, axis);
    quat_old.set(node->getRotation()*DEGTORAD);   
 
    quat_rot*=quat_old; 
    quat_rot.normalize();
    node->setRotation (quat_rot.getMatrix().getRotationDegrees());
    }
 
Any help will be much appreciate.
Thanks in advance.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Gimbal lock and quaternion rotation issue

Post by smso »

Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Gimbal lock and quaternion rotation issue

Post by Abraxas) »

Code: Select all

core::vector3df heading(0.0f, 1.0f, 0.0f);
        matrix.rotateVect(heading);
 
 
        // rotate node to face the point:
        core::quaternion q;
        q.rotationFromTo(heading, dir);
        
        core::vector3df eulerRadians;
        q.toEuler(eulerRadians);
        
        obj->plane->node->setRotation(eulerRadians * core::RADTODEG);
Squirrel
Posts: 4
Joined: Fri Dec 21, 2012 4:32 pm

Re: Gimbal lock and quaternion rotation issue

Post by Squirrel »

Thank you both!

@smso
I had a matrix function to do objetct's relative rotations but none so far that worked using world space, so this will be very useful. :)

Beyond the usefulness of this one, I really want to understand what's the mistake(s) I made using quartenions.
To multiply two quaternions is supposed to do rotations effectively if I'am not wrong?

I modified my code to use absoluteTransformation functions without success.

Any idea about what I did wrong? I'll continue to search by my side anyway... :wink:

@Abraxas)
Your snippet is very interesting too and as I guess it will be very useful in some situations it points me to admit that I've got some difficulties to vizualize rotations using vectors.
e.g. in your code I don't know how to determine clearly the "heading" and "dir" vectors if I have to apply rotations to an already rotaded node.

Code: Select all

q.rotationFromTo(heading, dir);
I have to work on this too.


Thanks again
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Gimbal lock and quaternion rotation issue

Post by Abraxas) »

heading is your "default" rotation. Every direction vector will be relative to this. So a rotation of (0,0,0) corresponds to a heading of (0,1,0).

dir is your desired facing direction. So if you want to face sideways, you want a heading of (1,0,0) or (0,0,1) or even (1,0,1) or (-1,0,-1) or whatnot. You should normalize this vector after deciding on your heading.

The quaternion:

http://en.wikipedia.org/wiki/Quaternion

http://en.wikipedia.org/wiki/Gimbal_lock

This can be explained intuitively by the fact that a quaternion describes a rotation in one single move ("please turn radians around the axis driven by vector "), while the Euler angles are made of three successive rotations.
---

So therefore the quaternion is a representation of the rotation that would move from heading to direction. You use the toEuler() vector format to do node->setRotation(eulerrotaion * radianstodegrees).
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Gimbal lock and quaternion rotation issue

Post by smso »

I changed 1 line in your code and it should work now:

Code: Select all

void testRotateInLocalSpace(scene::ISceneNode* node, f32 degs, const core::vector3df& axis)
{
    core::quaternion q;
    q.fromAngleAxis(degs*core::DEGTORAD, axis);
    
    core::quaternion q0;
    q0.set(node->getRotation() * core::DEGTORAD);
    
    q = q * q0;
    //q *= q0; //FIXME not working, maybe a bug?
    q.normalize();
    node->setRotation(q.getMatrix().getRotationDegrees());
}
 
Regards,
smso
Squirrel
Posts: 4
Joined: Fri Dec 21, 2012 4:32 pm

Re: Gimbal lock and quaternion rotation issue

Post by Squirrel »

Thank you for your answers!

@ Abraxas)

Code: Select all

So a rotation of (0,0,0) corresponds to a heading of (0,1,0)
This was the missing information!.... where I could expect to go if I hadn't any starting reference?
It's more clear now.

About the wiki pages, i read them many times but even if if think i understood the practical concept of quaternions, explanations are far above my math skills.

Anyway, I just realize i was wrong to always thinking using object's relative rotations, i guess using absolute references is a better way to use quaternions... i've got to make some tests.

@ smso
I tested the modified code and thought first the problem was fixed as the Z axis rotation worked but i noticed (maybe because of the fact that the multiplication of quaternions is not commutative) that the changes lead to swap from absolute to relative rotation. So, now it's the relative X axis which is locked.
Nice try anyway.



Anyways, using your explanations and study your snippets will help me to go further.

Thanks
Mikhail9
Posts: 54
Joined: Mon Jun 29, 2009 8:41 am

Re: Gimbal lock and quaternion rotation issue

Post by Mikhail9 »

Quats can be really hard to visualize. Look at a variety of different tutorials on the web until you start to get a picture of how they work. Don't give up too easily!
Squirrel
Posts: 4
Joined: Fri Dec 21, 2012 4:32 pm

Re: Gimbal lock and quaternion rotation issue

Post by Squirrel »

Just in case of someone else would make the same mistake that I made :

If I understood correctly the math explanations I just read about rotations using quaternions, I think that I made a mistake doing a direct multiplication of the quaternions.
The right way seems to be to use a quaternion to build a rotation matrix then to multiply it with a matrix created from the vector.

This is exactly what smso wrote in the rotateNodeInWorldSpace function http://irrlicht.sourceforge.net/forum/v ... =9&t=47924

Thanks again for your help.
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Gimbal lock and quaternion rotation issue

Post by Abraxas) »

Quats are really easy to understand.

Step 1: Create a plane in 3-d space.

Step 2: rotate the plane.

That's all a quat tells you.
Post Reply