Hello everyone,
Update:
Solved in the meantime.
Rotation that has to applied is simple:
transform.rotation = Quaternion.Inverse(CalculatedQuaternionFromAlgorithm);
Quote from own comment below:
So basically, all of the available algorithms just don’t put out the
rotation of the sensor with respect to
earth, but vice versa: orientation of
earth frame with respect to sensor
frame. This gets a bit more clear when
you use the magnetic field as well and
not just acceleration for gravity and
see what the outcome is. Simple as
that, the calculated quaternion has to
be inverted in order to apply the
actual sensor orientation to the
GameObject.
**Original question: **
I’ve just messed over 4 1/2 hours with applying an orientation I get from an Inertial Movement (IMU) sensor to a simple cube in Unity.
Straight away: I’ve actually solved it with very simple code. But I have no idea why, and instead this code should to the opposite…
So here’s what I do:
I calculate a quaternion from my sensor data and want to see a cube in Unity move the same as my sensor. My problem was, that when I rotated around a sensor axis, say X, the cube got rotated around the world’s axis X, and not its local axis. I read nearly everything google and Unity Answers provided as information, and I understand a bit about quaternions.
However, the only and really only solution that worked is as follows:
void Update ()
{
diffQuat = Quaternion.Inverse(bodyQuat) * lastQuat ;
transform.Rotate(diffQuat.eulerAngles, Space.World);
lastQuat = bodyQuat;
}
- I calculate a difference Quaternion (diffQuat) from the last sensor Quaternion (bodyQuat) and the latest sensor Quaternion. So, bodyQuat gets updated between the frame updates. This difference calculation is necessary in order not to rotate infinitely fast around random axes, but only the delta value. Doing it this way, I can use…
- … the Rotate() function, where I apply the Euler Angles of my difference Quaternion. Oddly, I have to set
Space.World
here. I would have expectedSpace.Self
(!) in order to rotate around the cube’s axes, but somehow this leads to the opposite.
Even more strange: Initially, I thought that
transform.Rotate(diffQuat.eulerAngles, Space.Self)
would be the same (in my case) as
transform.rotation = transform.rotation * diffQuat;
However, using transform.rotation
, I also get only the rotation around the world’s axes, when I move the sensor around.
So two questions:
- Why does the
transform.rotation
-method not work? - Why do I have to use
Space.World
in order to get local axis’ rotations?
Can anybody tell me if that code is really the way to go or if there’s another thing I haven’t realized yet how to “attach” an IMU sensor to a simple cube in Unity.
By the way one of the most unresolved questions out there…