I have an accelerometer that is communicating serially to a PC. As I read in the data, I filter it to clean it up and calculate the angle of the pitch and roll. This all works great. Then I want to apply these angles to an object in Unity3D.
I created an object an try to rotate it using
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(new Vector3(pitchAngle, 0f, rollAngle)), Time.time);
I use this method because I read that if you try and apply Euler angles, there is potential to run into gimbal lock, so I attempted to use Quaternion to fix that. It seems I might still be running into the problem.
If I try something like
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(new Vector3(pitchAngle, 0f, 0f)), Time.time);
or
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(new Vector3(0, 0f, rollAngle)), Time.time);
The rotation is perfect, there is no 180 degree flip.
I also tried one more thing that can be ruled out that did not work, I tried,
transform.localRotation =
Quaternion.AngleAxis(rollAngle, Vector3.forward) *
Quaternion.AngleAxis(0, Vector3.up) *
Quaternion.AngleAxis(pitchAngle, Vector3.right);
To describe the numbers on the next three images, the very top line is the calculated angle of pitch and roll (respectively). The line below that is the m/sec^2 (g's) recorded from the accelerometer. The very last line is obtained by transform.eulerAngles.ToString()
.
The picture above is before pitch crosses 90 degrees
The picture above is after pitch crosses 90 degrees, notice the 180 degree turn
This picture is removing roll from the equation. The angle of the pitch works perfectly fine. transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(new Vector3(pitchAngle, 0f, 0f)), Time.time);
The 'roll' also works perfect if pitch is removed. They just don't work well together.
The one thing I noticed is when only rotating one axis, the other two both change from 0 to 180. But I can't simply subtract the 180 from one axis, as I lose my full range of motion.
- Question:
How to I fix this (gimbal lock) problem? After trying Quaternion and failing to use it properly, I am very confused with finding a solution. The math doesn't seem to be clicking in my head to manipulate the angles properly.
string.Split(',')
. I glanced at the Quaternion.LookRotation function, I don't fully understand your comment and how that function would work. I'm going to dig into it further and see what I can do. \$\endgroup\$Math.Atan2(-x, z) * 180 / Math.PI;
for Pitch andMath.Atan2(y, z) * 180 / Math.PI;
for Roll. These return my full range of rotation. Which individually they work perfect, but together they cause the unwanted 'flip'. \$\endgroup\$