|  | 
| 0 degrees from up vector. Good. yaw 0, pitch 0, roll 0 | 
2:24 PM
One of the hardest things to do is to keep going each day when you're feeling doubt and time pressures.
I tried comparing the angle between two quaternions and no luck. Quaternions could work differently to vectors in this way.
Nope. I think, I'm messing up defining an up quaternion.
4:28 PM
I hate quaternions. So much.
5:10 PM
Calculating the angle between an up vector and a direction vector only works in when I rotate in some directions.
5:30 PM
I can rotate objects as much as I like but I can't get the current rotation level back to check whether an object has rotated too far.
6:17 PM
Looking at the direction vector doesn't help. Perhaps, I can look
6:26 PM
GOT IT!
1) Create two up vectors (0, 1, 0). Call them Alpha and Bravo.
2) Rotate Bravo by the robot's orientation.
3) Calculate the angle between Alpha and Bravo.
|  | 
| 45 degrees from up vector. Good. yaw 0, pitch -45, roll 0 | 
|  | 
| 45 degrees from up vector. Good. yaw -45, pitch -90, roll 90 | 
|  | 
| 45 degrees from up vector. Good. yaw 0, pitch, 135, roll -180 | 
|  | 
| 45 degrees from up vector. Good. yaw 45, -90, 90 | 
|  | 
| 45 degrees from up vector. Good. yaw 0, pitch 45, roll 0 | 
YES! YES! YES!
I don't know why this doesn't work when Bravo is (0, 0, -1) and I don't know how to do this with quaternions.
More screen shots to illustrate why using pitch and yaw to detect the extent of tipping over was difficult.
|  | |
| 45 degrees from up vector. Good yaw 0, pitch 0, roll -45 | 
Up till now we could use the rule that a robot has tipped too far when either absolute pitch or absolute roll has exceeded 45 degrees.
|  | 
| 46 degrees from up vector. Good. yaw -34, pitch -18, roll -34 | 
However, there are situations like this which makes using such a rule difficult.
Some code fragments to illustrate what I'm doing.
void Robot::Rotate( const Direction& dir ) {
    const float increment = 5.0f;
    float yaw = 0.0f;
    float pitch = 0.0f;
    float roll = 0.0f;
    switch( dir ) {
        case ROTATE_DOWN:
            pitch = Ogre::Degree( -increment ).valueRadians();
            break;
        case ROTATE_UP:
            pitch = Ogre::Degree( increment ).valueRadians();
            break;
        case ROTATE_LEFT:
            yaw = Ogre::Degree( increment ).valueRadians();
            break;
        case ROTATE_RIGHT:
            yaw = Ogre::Degree( -increment ).valueRadians();
            break;
        case ROLL_LEFT:
            roll = Ogre::Degree( -increment ).valueRadians();
            break;
        case ROLL_RIGHT:
            roll = Ogre::Degree( increment ).valueRadians();
            break;
        default:
            break;
    }
    // get transform
    btTransform transform;
    transform.setIdentity();
    transform = rigidBody->getCenterOfMassTransform();
    // modify transform
    btMatrix3x3 matrix3x3;
    matrix3x3.setEulerYPR( roll, yaw, pitch );
    transform.getBasis() *= matrix3x3;
    // apply transform    
    rigidBody->setCenterOfMassTransform( transform );  
    // debug
    transform.getBasis().getEulerYPR( roll, yaw, pitch );
    cout << "yaw : " << nint( Ogre::Radian( yaw ).valueDegrees() ) 
         << endl;     
    cout << "pitch : "  << nint( Ogre::Radian( pitch ).valueDegrees() ) 
         << endl;     
    cout << "roll : "  << nint( Ogre::Radian( roll ).valueDegrees() )
         << endl;         
    // WORKS!
    const btVector3 upVec( 0.0f, 1.0f, 0.0f );
    const btQuaternion rotQua = transform.getRotation();    
    btVector3 rotVec( 0.0f, 1.0f, 0.0f );
    rotVec = transform.getBasis() * rotVec;
    const float angle = upVec.angle( rotVec );
    // ARGH!
    //const btQuaternion upQua( btVector3( 1.0f, 0.0f, 0.0f ), 90.0f ); // up
    //const btQuaternion upQua( btVector3( 0.0f, 0.0f, 1.0f ), 0.0f ); // up
    //const btQuaternion upQua( btVector3( 0.0f, 1.0f, 0.0f ), 0.0f ); // up
    //btQuaternion rotQua( upQua );
    //rotQua = rotQua * transform.getRotation();
    //const float angle = upQua.angle( rotQua );
    
    cout << "angle: " << Ogre::Radian( angle ).valueDegrees() << endl;   
}
Pomodoros
1 1 1 1
1 1 1 1
1
RELATED
 
Hmm. What set of values is OGRE using to render the orientation of your object?
ReplyDeleteHi Anonymous,
ReplyDeleteI took a vector representing position and a quaternion representing orientation from Bullet and then used them in Ogre. I'll post up the actual pitch, yaw, and roll values for each of the screen-shots in a few hours.
Hi Anonymous,
ReplyDeleteI've added a few screen shots, yaw, pitch, and roll values, and some code to clarify the difficulties I had and the approach that I found.
The function allows me to manually rotate a robot depending on the input direction.
Line 36 and 43 where I call setEulerYPR() and getEulerYPR() look a bit funny because either they don't work as they should so I had to modify how I used them or I'm way off.
The key part of this is Bullet code with a few convenience fragments from Ogre.