A hello world for inertial sensors
Dependencies: FXAS21000 FXOS8700Q mbed
Fork of FRDM-STBC-AGM01 by
Adafruit_9DOF.cpp
- Committer:
- Elecia
- Date:
- 2015-06-30
- Revision:
- 4:5ab2bb2f062b
- Parent:
- 3:123b546e4a5c
File content as of revision 4:5ab2bb2f062b:
/*************************************************************************** ** https://github.com/adafruit/Adafruit_9DOF/blob/master/Adafruit_9DOF.cpp ** Modifed Adafruit's orientation code to get only the tilt compensated heading ***************************************************************************/ /*************************************************************************** This is a library for the Adafruit 9DOF Breakout Designed specifically to work with the Adafruit 9DOF Breakout: http://www.adafruit.com/products/1714 These displays use I2C to communicate, 2 pins are required to interface. Adafruit invests time and resources providing this open source code, please support Adafruit andopen-source hardware by purchasing products from Adafruit! Written by Kevin Townsend for Adafruit Industries. BSD license, all text above must be included in any redistribution ***************************************************************************/ #include <math.h> #include "Adafruit_9DOF.h" #define SENSORS_GRAVITY_EARTH (9.80665F) #define MILLIG_TO_M_PER_S2 (SENSORS_GRAVITY_EARTH/1000.0F) #define MILLIGAUSS_TO_MICROTESLA (10.0F) /**************************************************************************/ /*! @brief Populates the .roll/.pitch/.heading fields in the sensors_vec_t struct with the right angular data (in degree). The starting position is set by placing the object flat and pointing northwards (Z-axis pointing upward and X-axis pointing northwards). The orientation of the object can be modeled as resulting from 3 consecutive rotations in turn: heading (Z-axis), pitch (Y-axis), and roll (X-axis) applied to the starting position. @param accel The vector variable containing the data from the accelerometer @param mag The vector variable containing the data from the magnetometer @param orientation The sensors_vec_t object that will have it's .roll, .pitch and .heading fields populated */ /**************************************************************************/ bool fusionGetOrientation(int16_t *accel, int16_t *mag, tOrientation *orientation) { /* Make sure the input is valid, not null, etc. */ if ( accel == NULL) return false; if ( mag == NULL) return false; if ( orientation == NULL) return false; float const PI_F = 3.14159265F; double aX = ((double) accel[X]) * MILLIG_TO_M_PER_S2; double aY = ((double) accel[Y]) * MILLIG_TO_M_PER_S2; double aZ = ((double) accel[Z]) * MILLIG_TO_M_PER_S2; double mX = ((double) mag[X]) * MILLIGAUSS_TO_MICROTESLA; double mY = ((double) mag[Y]) * MILLIGAUSS_TO_MICROTESLA; double mZ = ((double) mag[Z]) * MILLIGAUSS_TO_MICROTESLA; /* roll: Rotation around the X-axis. -180 <= roll <= 180 */ /* a positive roll angle is defined to be a clockwise rotation about the positive X-axis */ /* */ /* y */ /* roll = atan2(---) */ /* z */ /* */ /* where: y, z are returned value from accelerometer sensor */ orientation->roll = (float)atan2(aY, aZ); /* pitch: Rotation around the Y-axis. -180 <= roll <= 180 */ /* a positive pitch angle is defined to be a clockwise rotation about the positive Y-axis */ /* */ /* x */ /* roll = atan(-----------------) */ /* sqrt(y^2 + z^2) */ /* where: x, y, z are returned value from accelerometer sensor */ double t_pitch = (aY*aY) + (aZ*aZ); float signOfZ = aZ >= 0 ? 1.0F : -1.0F; orientation->pitch = (float)atan2(aX, signOfZ * sqrt(t_pitch)); /* heading: Rotation around the Z-axis. -180 <= roll <= 180 */ /* a positive heading angle is defined to be a clockwise rotation about the positive Z-axis */ /* */ /* z * sin(roll) - y * cos(roll) */ /* heading = atan2(--------------------------------------------------------------------------) */ /* x * cos(pitch) + y * sin(pitch) * sin(roll) + z * sin(pitch) * cos(roll)) */ /* */ /* where: x, y, z are returned value from magnetometer sensor */ orientation->heading = (float)atan2(mZ * sin(orientation->roll) - mY * cos(orientation->roll), \ mX * cos(orientation->pitch) + \ mY * sin(orientation->pitch) * sin(orientation->roll) + \ mZ * sin(orientation->pitch) * cos(orientation->roll)); orientation->heading = (float)atan2(mY, mX); /* Convert angular data to degree */ orientation->roll = orientation->roll * 180 / PI_F; orientation->pitch = orientation->pitch * 180 / PI_F; orientation->heading = orientation->heading * 180 / PI_F; return true; }