I'm building a DIY 2DOF Flight Simulator with full motion 360° pitch and roll movements like this one https://www.techeblog.com/full-motion-flight-simulator-vr/. It's very simple to get the bank and pitch angles from DCS World by a LUA Script, but this data from DCS is not the exact thing that I need, because this data have gimbal lock problems and others... I'm trying to calculate Roll and Pitch movement from the plane angular velocities (gx,gy,gz in the below code) and using quaternion and after that, converting to Euler angles. I get this code (C#) from https://x-io.co.uk/, and modified some things.
public void Rotation_Update()
{
if (Initial) Main_Vector = Quaternion.CreateFromYawPitchRoll(0, 0, 0);
Initial = false;
float q1 = Main_Vector.W, q2 = Main_Vector.X, q3 = Main_Vector.Y, q4 = Main_Vector.Z;
// Main_Vector is the Quaternion
// Compute rate of change of quaternion
//gx, gy, gz are the angular velocity from DCS
qDot1 = 0.5f * (-q2 * gx - q3 * gy - q4 * gz);
qDot2 = 0.5f * (q1 * gx + q3 * gz - q4 * gy);
qDot3 = 0.5f * (q1 * gy - q2 * gz + q4 * gx);
qDot4 = 0.5f * (q1 * gz + q2 * gy - q3 * gx);
q1 += qDot1 * dt;
q2 += qDot2 * dt;
q3 += qDot3 * dt;
q4 += qDot4 * dt;
// normalise quaternion
norm = 1f/ (float)Math.Sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4);
Main_Vector.W = q1 * norm;
Main_Vector.X = q2 * norm;
Main_Vector.Y = q3 * norm;
Main_Vector.Z = q4 * norm;
}
public float ConvertToEulerAnglesX() //Roll Angle
{
float radians = (float)Math.Atan2(-2f * (Main_Vector.Y * Main_Vector.Z - Main_Vector.W * Main_Vector.X), 2f * Main_Vector.W * Main_Vector.W - 1f + 2f * Main_Vector.Z * Main_Vector.Z);
return Rad2Deg(radians);
}
public float ConvertToEulerAnglesY() //Yaw Angle
{
float radians = (float)(0.0 - Math.Atan(2.0 * (double)(Main_Vector.X * Main_Vector.Z + Main_Vector.W * Main_Vector.Y) / Math.Sqrt(1.0 - Math.Pow(2.0 * (double)Main_Vector.X * (double)Main_Vector.Z + 2.0 * (double)Main_Vector.W * (double)Main_Vector.Y, 2.0))));
return Rad2Deg(radians);
}
public float ConvertToEulerAnglesZ() //Pitch Angle
{
float radians = (float)Math.Atan2(2f * (Main_Vector.X * Main_Vector.Y - Main_Vector.W * Main_Vector.Z), 2f * Main_Vector.W * Main_Vector.W - 1f + 2f * Main_Vector.X * Main_Vector.X);
return Rad2Deg(radians);
This code works very very well if the plane heading are in -20° to +20 and 160° to 200°. If I made loops with this heading range, the angles are prettly smooth and correct. If I change the plane heading outside this, the quaternion to Euler angles doesn't work fine anymore. I think it's a Gimbal lock problem. I'm beginner in quaternions and I spent a couple weeks trying to fix it.
Is there a better way to calculate this angles without this problem?
Friends, sorry about my english.