So I've got a Sparkfun LSM6DSV16X (6DOF IMU board with sensor fusion) and although the Sparkfun library doesn't seem to output the sensor fusion quaternions (as far as I've been able to tell from the examples), there's another library (by stm32duino) that does output quaternions.
There's even a handy web visualizer that works with it:
https://adafruit.github.io/Adafruit_WebSerial_3DModelViewer/
Now the issue I'm having is that I want to get an Euler (pitch/roll/yaw) representation of the orientation of the sensor rather than the Quaternion but I'm a bit confused by the specifications.
The datasheet says:
Game rotation vector: X, Y, and Z axes (vector part of the quaternion) are stored in half-precision floating- point format, where w (scalar part of the quaternion) is computed in software after reading the data from the FIFO, since the game rotation vector is a unit quaternion.
Which would lead me to believe that it's just a 3d vector output, but the code itself is outputting 4d:
AccGyr.FIFO_Get_Tag(&tag);
if (tag == 0x13u) {
AccGyr.FIFO_Get_Rotation_Vector(&quaternions[0]);
// Print Quaternion data
Serial.print("Quaternion: ");
Serial.print(quaternions[3], 4);
Serial.print(", ");
Serial.print(quaternions[0], 4);
Serial.print(", ");
Serial.print(quaternions[1], 4);
Serial.print(", ");
Serial.println(quaternions[2], 4);
That in-and-of-itself isn't too bad, but where I'm getting really confused is that I know that quaternions can come in different orders (w, x, y, z
or x, y, z, w
), furthermore, the order the quaternions are being print
-ed here is different too (3, 0, 1, 2
). From what I can tell, there's no mention of what order the LSM6DSV16X is outputting the data as.
My math isn't good enough to be able to tell what the order is just by looking at the numbers.
Now the main reason I'm writing this is because I found another forum post on here for converting from quaternions to Euler angles, but this only works with one of the orders.
float yaw = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);
float pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
float roll = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
Does anyone have experience with using the LSM6DSV16X with Euler outputs or know maths well enough to know what order things are coming in as in the sensor fusion library?
9 posts - 2 participants