Results 1 to 4 of 4

Thread: Gimbal lock with Quaternions

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5

    Gimbal lock with Quaternions

    I have a 3d object in the scene and I'm trying do pitch, yaw and roll. To avoid Gimbal lock, quaternions are used. It looks like I'm missing something fundamental about the implementation. I'm still getting Gimbal lock. Ideally, there should be an axis around which I should be doing the rotation, but I am not sure how to update the object's orientation/axis.

    Code :
     
    glm::quat rotP = glm::angleAxis(glm::radians(doPitch), glm::vec3(1.0f, 0.0f, 0.0f)); //i believe the glm::vec3 should be updated with the new orientation, but not sure how
     
    glm::quat rotY = glm::angleAxis(glm::radians(doYaw), glm::vec3(0.0f, 1.0f, 0.0f));
     
    glm::quat rotR = glm::angleAxis(glm::radians(doRoll), glm::vec3(0.0f, 0.0f, 1.0f));
     
     
    model = glm::mat4_cast(rotR) * glm::mat4_cast(rotY) * glm::mat4_cast(rotP) ;

    doPitch, doYaw and doRoll are updated incrementally using keyboard.

    I need to find a way to update the orientation after i do pitch, yaw or roll. Could someone help please?

  2. #2
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674
    I have a 3d object in the scene and I'm trying do pitch, yaw and roll. To avoid Gimbal lock, quaternions are used.
    The long version can be found here. This is the TL;DR version:

    Quaternions are not a magical salve that can be applied to make Gimbal lock go away.

    The problem with Euler angles is that, when you compute the matrices, each angle is relative to the rotation of the matrix that came before it. What you want is to take an object's current *orientation*, and apply a rotation along some axis, producing a new orientation.

    You can't do that with Euler angles. You can with matrices, and you can with quaternions (as they're just the rotation part of a matrix). But you can't do it by pretending they are Euler angles.

    This is done by not storing angles at *all*. Instead, you just have a quaternion which represents the current orientation of the object. When you decide to apply a rotation to it (of some angle by some axis), you construct a quaternion that represents that rotation by an angle around that axis. Then you right-multiply that quaternion with the current orientation quaternion, producing a new current orientation.

    When you render the object, you use the current orientation as... the orientation.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,103
    Quote Originally Posted by codebeatz View Post
    doPitch, doYaw and doRoll are updated incrementally using keyboard.
    And therein lies your problem.

    Assuming the usual order of application (yaw, pitch, roll), if the pitch is 90, then yaw and roll do the same thing. Modifying either of them will rotate about the world's vertical axis. This is the essence of gimbal lock. Changing the order of application just changes which flavour of gimbal lock you get. If the middle rotation is 90, then the first and last rotations rotate about the same axis.

    To avoid this, you need to replace those three variables with either a quaternion or a rotation matrix holding the current orientation. Instead of updating one of three variables using the keyboard, you apply an incremental rotation about one of the three axes to the current orientation. If you use current=current*incremental (post-multiply) the rotation is in the object's (local) coordinate system, while current=incremental*current (pre-multiply) uses the world's (global) coordinate system.

  4. #4
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5
    Quote Originally Posted by GClements View Post
    And therein lies your problem.

    Assuming the usual order of application (yaw, pitch, roll), if the pitch is 90, then yaw and roll do the same thing. Modifying either of them will rotate about the world's vertical axis. This is the essence of gimbal lock. Changing the order of application just changes which flavour of gimbal lock you get. If the middle rotation is 90, then the first and last rotations rotate about the same axis.

    To avoid this, you need to replace those three variables with either a quaternion or a rotation matrix holding the current orientation. Instead of updating one of three variables using the keyboard, you apply an incremental rotation about one of the three axes to the current orientation. If you use current=current*incremental (post-multiply) the rotation is in the object's (local) coordinate system, while current=incremental*current (pre-multiply) uses the world's (global) coordinate system.
    That's spot on. I wasn't holding the current orientation. Thanks!! It works now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean