Skip to main content
New Participant
June 24, 2015

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

    Inspiring
    June 24, 2015
    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).
    Titans of Space PLUS for Quest is now available on DrashVR.com
    Inspiring
    June 24, 2015
    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);
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    Inspiring
    June 25, 2015
    "cybereality" wrote:
    You can get the Euler angles like this:


    That only works if the developer includes the deprecated math header.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Inspiring
    June 25, 2015
    "jherico" wrote:
    That only works if the developer includes the deprecated math header.

    Didn't realize that. I'll see about updating my example.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    florethAuthor
    New Participant
    June 30, 2015
    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???
    Up and Coming
    June 30, 2015
    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;
    }
    Inspiring
    June 30, 2015
    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.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    Inspiring
    June 30, 2015
    @matlock: Please use the code tags when pasting in code. Thanks.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    Inspiring
    June 30, 2015
    "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:

    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action