Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
floreth's avatar
floreth
Honored Guest
11 years ago

Orientation Problem: Roll / Pitch Axis are mixed! Pls help

Im building a system, where i need to extract the Orientation of the Oculus via C++. My code is very simple an mostly out of the Guide.

The Problem is, that then i test it the Axis Z and X are mixed together.
e.g. If i roll ( z- axis ) the Oculus the Pitch ( x- axis ) parameter is changing too and vice versa.

=> turning the Oculus by ~30° (z - axis) changes the values of:
x~0.00 to x~0.08
and
z~ 0 to z~ -0.15

How can i seperate them?
i need x,z,y parameters, which are independ, so i can extrat the angles, to make my system work.

is there another way to get the orientation angles?



ovr_Initialize();

if(!HMD){
HMD = ovrHmd_Create(0);

if(!HMD){
cout<<"Oculus Rift not detected!"<<endl;
}
if(HMD->ProductName[0] == '\0'){
cout<<"Oculus Rift detected,display not enabled"<<endl;
}
}


ovrHmd_ConfigureTracking(HMD, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0);
Sleep(500); //Wait on VR-to respond
ovrTrackingState ts = ovrHmd_GetTrackingState(HMD, ovr_GetTimeInSeconds());
ovrPosef pose;
if(ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)){
while(1){
ts = ovrHmd_GetTrackingState(HMD, ovr_GetTimeInSeconds());
pose = ts.HeadPose.ThePose;
cout << "X:" << pose.Orientation.x ;
cout << "Y:" << pose.Orientation.y ;
cout << "Z:" << pose.Orientation.z ;
}

9 Replies

  • drash's avatar
    drash
    Heroic Explorer
    TrackingState.HeadPose.ThePose is actually a Quaternion (which has x,y,z,w components that do NOT correspond to rotations around each axis), so you'll either need to change your approach to use Quaternion operations, or you'll need to first convert it to a set of Euler angles (which are x,y,z rotations around each axis).
  • You can get the Euler angles like this:

    Posef pose = hmdState.HeadPose.ThePose;
    float yaw, pitch, roll;
    pose.Rotation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll);
  • "cybereality" wrote:
    You can get the Euler angles like this:


    That only works if the developer includes the deprecated math header.
  • "jherico" wrote:
    That only works if the developer includes the deprecated math header.

    Didn't realize that. I'll see about updating my example.
  • floreth's avatar
    floreth
    Honored Guest
    Thanks for the help


    Posef pose = hmdState.HeadPose.ThePose;
    float yaw, pitch, roll;
    pose.Rotation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll);


    i tried these, but it didnt worked. Guess i have to identify the header.

    Bump for more help

    Is there a way to get the Euler angles without the old math header, without too much effort???
  • Matlock's avatar
    Matlock
    Honored Guest
    I don't know if this will help, because I am going to assume that your goal is to use the euler angles to create a view matrix... If that is the case, don't use euler at all.


    Matrix4f ViewHMD;
    if(RenderingLeft)
    {
    ViewHMD = CalculateViewFromPose(EyeRenderPose[0].Orientation,EyeRenderPose[0].Position);
    }
    else
    {
    ViewHMD = CalculateViewFromPose(EyeRenderPose[1].Orientation,EyeRenderPose[1].Position);
    }

    :geek:


    EDIT : It looks like I modified this function :

    Matrix4f CalculateViewFromPose(ovrQuatf Rotation, ovrVector3f Position)
    {
    const Vector3f RightVector(1.0f, 0.0f, 0.0f);
    const Vector3f UpVector(0.0f, 1.0f, 0.0f);
    const Vector3f ForwardVector(0.0f, 0.0f, -1.0f); // -1 because HMD looks along -Z at identity orientation

    OVR::Quat<float> QRotation;

    QRotation.x = Rotation.x;
    QRotation.y = Rotation.y;
    QRotation.z = Rotation.z;
    QRotation.w = Rotation.w;

    Vector3f up = QRotation.Rotate(UpVector);
    Vector3f forward = QRotation.Rotate(ForwardVector);

    // Transform the position of the center eye in the real world (i.e. sitting in your chair)
    // into the frame of the player's virtual body.

    Vector3f viewPos(Position.x,Position.y,Position.z);//ForceZeroHeadMovement ? ThePlayer.BodyPos : worldPose.Translation;

    Matrix4f view = Matrix4f::LookAtRH(viewPos, viewPos + forward, up);


    //Matrix4f view = Matrix4f(worldPose.Rotation);
    return view;
    }
  • OVR_Math.h is still there in 0.6.0.1, and you can include it like this.

    #include "Extras\OVR_Math.h"


    I realize that OVR.h says it will be deprecated, but whenever that happens I assume there will be a replacement.

    So it's probably safe to use for the time being.

    Here is a full C++ sample that I compiled with 0.6.0.1 and can confirm is working.

    #include "OVR_CAPI.h"
    #include "Extras\OVR_Math.h"
    #include <iostream>
    #include <conio.h>
    #include <windows.h>

    using namespace std;
    using namespace OVR;

    int main()
    {
    ovr_Initialize(nullptr);

    ovrHmd HMD;

    ovrHmd_Create(0, &HMD);

    ovrHmd_ConfigureTracking(HMD, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0);

    while(true){
    ovrFrameTiming ftiming = ovrHmd_GetFrameTiming(HMD, 0);
    ovrTrackingState hmdState = ovrHmd_GetTrackingState(HMD, ftiming.DisplayMidpointSeconds);

    if (hmdState.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) {
    Posef pose = hmdState.HeadPose.ThePose;
    float yaw, pitch, roll;
    pose.Rotation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll);

    cout << "yaw: " << RadToDegree(yaw) << ", pitch: " << RadToDegree(pitch) << ", roll: " << RadToDegree(roll) << endl;

    Sleep(75);
    }

    if (_kbhit()) break;
    }

    ovrHmd_Destroy(HMD);

    ovr_Shutdown();
    }


    Hope that helps.
  • "floreth" wrote:

    Is there a way to get the Euler angles without the old math header, without too much effort???


    If you have or can use GLM, they have an easy method for converting a quaternion into euler angles.


    ovrQuatf oq;
    glm::quat q(oq.x, oq.y, oq.z, oq.w);
    glm::vec3 euler = glm::eulerAngles(q);


    Failing that, you'll probably end up falling back on the actual implementation: