@@ -222,27 +222,48 @@ void loop()
222
222
SERIAL_PORT.println(q3, 3);
223
223
*/
224
224
225
- // Convert the quaternions to Euler angles (roll, pitch, yaw)
226
- // https://en.wikipedia.org/w/index.php?title=Conversion_between_quaternions_and_Euler_angles§ion=8#Source_code_2
225
+ // The ICM 20948 chip has axes y-forward, x-right and Z-up - see Figure 12:
226
+ // Orientation of Axes of Sensitivity and Polarity of Rotation
227
+ // in DS-000189-ICM-20948-v1.6.pdf These are the axes for gyro and accel and quat
228
+ //
229
+ // For conversion to roll, pitch and yaw for the equations below, the coordinate frame
230
+ // must be in aircraft reference frame.
231
+ //
232
+ // We use the Tait Bryan angles (in terms of flight dynamics):
233
+ // ref: https://en.wikipedia.org/w/index.php?title=Conversion_between_quaternions_and_Euler_angles
234
+ //
235
+ // Heading – ψ : rotation about the Z-axis (+/- 180 deg.)
236
+ // Pitch – θ : rotation about the new Y-axis (+/- 90 deg.)
237
+ // Bank – ϕ : rotation about the new X-axis (+/- 180 deg.)
238
+ //
239
+ // where the X-axis points forward (pin 1 on chip), Y-axis to the right and Z-axis downward.
240
+ // In the conversion example above the rotation occurs in the order heading, pitch, bank.
241
+ // To get the roll, pitch and yaw equations to work properly we need to exchange the axes
242
+
243
+ // Note when pitch approaches +/- 90 deg. the heading and bank become less meaningfull because the
244
+ // device is pointing up/down. (Gimbal lock)
227
245
228
246
double q0 = sqrt (1.0 - ((q1 * q1) + (q2 * q2) + (q3 * q3)));
229
247
230
- double q2sqr = q2 * q2;
248
+ double qw = q0; // See issue #145 - thank you @Gord1
249
+ double qx = q2;
250
+ double qy = q1;
251
+ double qz = -q3;
231
252
232
253
// roll (x-axis rotation)
233
- double t0 = +2.0 * (q0 * q1 + q2 * q3 );
234
- double t1 = +1.0 - 2.0 * (q1 * q1 + q2sqr );
254
+ double t0 = +2.0 * (qw * qx + qy * qz );
255
+ double t1 = +1.0 - 2.0 * (qx * qx + qy * qy );
235
256
double roll = atan2 (t0, t1) * 180.0 / PI;
236
257
237
258
// pitch (y-axis rotation)
238
- double t2 = +2.0 * (q0 * q2 - q3 * q1 );
259
+ double t2 = +2.0 * (qw * qy - qx * qz );
239
260
t2 = t2 > 1.0 ? 1.0 : t2;
240
261
t2 = t2 < -1.0 ? -1.0 : t2;
241
262
double pitch = asin (t2) * 180.0 / PI;
242
263
243
264
// yaw (z-axis rotation)
244
- double t3 = +2.0 * (q0 * q3 + q1 * q2 );
245
- double t4 = +1.0 - 2.0 * (q2sqr + q3 * q3 );
265
+ double t3 = +2.0 * (qw * qz + qx * qy );
266
+ double t4 = +1.0 - 2.0 * (qy * qy + qz * qz );
246
267
double yaw = atan2 (t3, t4) * 180.0 / PI;
247
268
248
269
#ifndef QUAT_ANIMATION
0 commit comments