void MPUQuaternionEulerToQuaternion(const MPUVector3 v, MPUQuaternion q) { float cosX2 = cos(v[VEC3_X] / 2.0f); float sinX2 = sin(v[VEC3_X] / 2.0f); float cosY2 = cos(v[VEC3_Y] / 2.0f); float sinY2 = sin(v[VEC3_Y] / 2.0f); float cosZ2 = cos(v[VEC3_Z] / 2.0f); float sinZ2 = sin(v[VEC3_Z] / 2.0f); q[QUAT_W] = cosX2 * cosY2 * cosZ2 + sinX2 * sinY2 * sinZ2; q[QUAT_X] = sinX2 * cosY2 * cosZ2 - cosX2 * sinY2 * sinZ2; q[QUAT_Y] = cosX2 * sinY2 * cosZ2 + sinX2 * cosY2 * sinZ2; q[QUAT_Z] = cosX2 * cosY2 * sinZ2 - sinX2 * sinY2 * cosZ2; MPUQuaternionNormalize(q); }
boolean MPU9150Lib::read() { short intStatus; int result; short sensors; unsigned char more; unsigned long timestamp; mpu_get_int_status(&intStatus); // get the current MPU state if ((intStatus & MPU_INT_STATUS_DMP_0) == 0) // return false if definitely not ready yet return false; // get the data from the fifo if ((result = dmp_read_fifo(m_rawGyro, m_rawAccel, m_rawQuaternion, ×tamp, &sensors, &more)) != 0) { return false; } // got the fifo data so now get the mag data if ((result = mpu_get_compass_reg(m_rawMag, ×tamp)) != 0) { #ifdef MPULIB_DEBUG Serial.print("Failed to read compass: "); Serial.println(result); return false; #endif } // got the raw data - now process m_dmpQuaternion[QUAT_W] = (float)m_rawQuaternion[QUAT_W]; // get float version of quaternion m_dmpQuaternion[QUAT_X] = (float)m_rawQuaternion[QUAT_X]; m_dmpQuaternion[QUAT_Y] = (float)m_rawQuaternion[QUAT_Y]; m_dmpQuaternion[QUAT_Z] = (float)m_rawQuaternion[QUAT_Z]; MPUQuaternionNormalize(m_dmpQuaternion); // and normalize MPUQuaternionQuaternionToEuler(m_dmpQuaternion, m_dmpEulerPose); // *** Note mag axes are changed here to align with gyros: Y = -X, X = Y if (m_useMagCalibration) { m_calMag[VEC3_Y] = -(short)(((long)(m_rawMag[VEC3_X] - m_magXOffset) * (long)SENSOR_RANGE) / (long)m_magXRange); m_calMag[VEC3_X] = (short)(((long)(m_rawMag[VEC3_Y] - m_magYOffset) * (long)SENSOR_RANGE) / (long)m_magYRange); m_calMag[VEC3_Z] = (short)(((long)(m_rawMag[VEC3_Z] - m_magZOffset) * (long)SENSOR_RANGE) / (long)m_magZRange); } else { m_calMag[VEC3_Y] = -m_rawMag[VEC3_X]; m_calMag[VEC3_X] = m_rawMag[VEC3_Y]; m_calMag[VEC3_Z] = m_rawMag[VEC3_Z]; } // Scale accel data if (m_useAccelCalibration) { m_calAccel[VEC3_X] = -(short)(((long)m_rawAccel[VEC3_X] * (long)SENSOR_RANGE) / (long)m_accelXRange); m_calAccel[VEC3_Y] = (short)(((long)m_rawAccel[VEC3_Y] * (long)SENSOR_RANGE) / (long)m_accelYRange); m_calAccel[VEC3_Z] = (short)(((long)m_rawAccel[VEC3_Z] * (long)SENSOR_RANGE) / (long)m_accelZRange); } else { m_calAccel[VEC3_X] = -m_rawAccel[VEC3_X]; m_calAccel[VEC3_Y] = m_rawAccel[VEC3_Y]; m_calAccel[VEC3_Z] = m_rawAccel[VEC3_Z]; } dataFusion(); return true; }