133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/*
233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall $License:
333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    See included License.txt for License information.
533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall $
633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall */
733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/**
933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *   @defgroup  HAL_Outputs hal_outputs
1033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *   @brief     Motion Library - HAL Outputs
1133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *              Sets up common outputs for HAL
1233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *
1333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *   @{
1433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *       @file hal_outputs.c
1533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall *       @brief HAL Outputs.
1633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall */
1733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "hal_outputs.h"
1833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "log.h"
1933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "ml_math_func.h"
2033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "mlmath.h"
2133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "start_manager.h"
2233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "data_builder.h"
2333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#include "results_holder.h"
2433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
2533ce91b37062fa63af192f5643de93f3beebe854JP Abgrallstruct hal_output_t {
2633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int accuracy_mag;    /**< Compass accuracy */
2733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall//    int accuracy_gyro;   /**< Gyro Accuracy */
2833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall//    int accuracy_accel;  /**< Accel Accuracy */
2933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int accuracy_quat;   /**< quat Accuracy */
3033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
3133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_time_t nav_timestamp;
3233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_time_t gam_timestamp;
3333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall//    inv_time_t accel_timestamp;
3433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_time_t mag_timestamp;
3533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long nav_quat[4];
3633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int gyro_status;
3733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int accel_status;
3833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int compass_status;
3933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int nine_axis_status;
4033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_biquad_filter_t lp_filter[3];
4133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    float compass_float[3];
4233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall};
4333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
4433ce91b37062fa63af192f5643de93f3beebe854JP Abgrallstatic struct hal_output_t hal_out;
4533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
4633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Acceleration (m/s^2) in body frame.
4733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Acceleration in m/s^2 includes gravity. So while not in motion, it
4833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             should return a vector of magnitude near 9.81 m/s^2
4933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate.
5033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to
5133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             inv_build_accel().
5233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
5333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
5433ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_accelerometer(float *values, int8_t *accuracy,
5533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                       inv_time_t * timestamp)
5633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
5733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int status;
5833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    /* Converts fixed point to m/s^2. Fixed point has 1g = 2^16.
5933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall     * So this 9.80665 / 2^16 */
6033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#define ACCEL_CONVERSION 0.000149637603759766f
6133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long accel[3];
6233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_accel_set(accel, accuracy, timestamp);
6333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[0] = accel[0] * ACCEL_CONVERSION;
6433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[1] = accel[1] * ACCEL_CONVERSION;
6533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[2] = accel[2] * ACCEL_CONVERSION;
6633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (hal_out.accel_status & INV_NEW_DATA)
6733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 1;
6833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    else
6933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 0;
7033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return status;
7133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
7233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
7333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Linear Acceleration (m/s^2) in Body Frame.
7433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Linear Acceleration in body frame, length 3, (m/s^2). May show
7533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             accel biases while at rest.
7633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate.
7733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to
7833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             inv_build_accel().
7933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
8033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
8133ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_linear_acceleration(float *values, int8_t *accuracy,
8233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        inv_time_t * timestamp)
8333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
8433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long gravity[3], accel[3];
8533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
8633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_accel_set(accel, accuracy, timestamp);
8733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_gravity(gravity);
8833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    accel[0] -= gravity[0] >> 14;
8933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    accel[1] -= gravity[1] >> 14;
9033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    accel[2] -= gravity[2] >> 14;
9133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[0] = accel[0] * ACCEL_CONVERSION;
9233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[1] = accel[1] * ACCEL_CONVERSION;
9333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[2] = accel[2] * ACCEL_CONVERSION;
9433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
9533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return hal_out.nine_axis_status;
9633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
9733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
9833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Gravity vector (m/s^2) in Body Frame.
9933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Gravity vector in body frame, length 3, (m/s^2)
10033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate.
10133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to
10233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             inv_build_accel().
10333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
10433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
10533ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_gravity(float *values, int8_t *accuracy,
10633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                 inv_time_t * timestamp)
10733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
10833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long gravity[3];
10933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int status;
11033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
11133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *accuracy = (int8_t) hal_out.accuracy_quat;
11233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *timestamp = hal_out.nav_timestamp;
11333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_gravity(gravity);
11433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[0] = (gravity[0] >> 14) * ACCEL_CONVERSION;
11533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[1] = (gravity[1] >> 14) * ACCEL_CONVERSION;
11633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[2] = (gravity[2] >> 14) * ACCEL_CONVERSION;
11733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if ((hal_out.accel_status & INV_NEW_DATA) || (hal_out.gyro_status & INV_NEW_DATA))
11833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 1;
11933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    else
12033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 0;
12133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return status;
12233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
12333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
12433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Gyroscope calibrated data (rad/s) in body frame.
12533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Rotation Rate in rad/sec.
12633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate.
12733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to
12833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             inv_build_gyro().
12933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
13033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
13133ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_gyroscope(float *values, int8_t *accuracy,
13233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                   inv_time_t * timestamp)
13333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
13433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    /* Converts fixed point to rad/sec. Fixed point has 1 dps = 2^16.
13533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall     * So this is: pi / 2^16 / 180 */
13633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#define GYRO_CONVERSION 2.66316109007924e-007f
13733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long gyro[3];
13833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int status;
13933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
14033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_gyro_set(gyro, accuracy, timestamp);
14133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[0] = gyro[0] * GYRO_CONVERSION;
14233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[1] = gyro[1] * GYRO_CONVERSION;
14333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[2] = gyro[2] * GYRO_CONVERSION;
14433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (hal_out.gyro_status & INV_NEW_DATA)
14533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 1;
14633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    else
14733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 0;
14833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return status;
14933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
15033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
15133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Gyroscope raw data (rad/s) in body frame.
15233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Rotation Rate in rad/sec.
15333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate.
15433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp The timestamp for this sensor. Derived from the timestamp sent to
15533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             inv_build_gyro().
15633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
15733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
15833ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_gyroscope_raw(float *values, int8_t *accuracy,
15933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                   inv_time_t * timestamp)
16033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
16133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    /* Converts fixed point to rad/sec. Fixed point has 1 dps = 2^16.
16233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall     * So this is: pi / 2^16 / 180 */
16333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall#define GYRO_CONVERSION 2.66316109007924e-007f
16433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long gyro[3];
16533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int status;
16633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
16733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_gyro_set_raw(gyro, accuracy, timestamp);
16833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[0] = gyro[0] * GYRO_CONVERSION;
16933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[1] = gyro[1] * GYRO_CONVERSION;
17033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[2] = gyro[2] * GYRO_CONVERSION;
17133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (hal_out.gyro_status & INV_NEW_DATA)
17233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 1;
17333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    else
17433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 0;
17533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return status;
17633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
17733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
17833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/**
17933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* This corresponds to Sensor.TYPE_ROTATION_VECTOR.
18033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* The rotation vector represents the orientation of the device as a combination
18133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* of an angle and an axis, in which the device has rotated through an angle @f$\theta@f$
18233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* around an axis {x, y, z}. <br>
18333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* The three elements of the rotation vector are
18433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* {x*sin(@f$\theta@f$/2), y*sin(@f$\theta@f$/2), z*sin(@f$\theta@f$/2)}, such that the magnitude of the rotation
18533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* vector is equal to sin(@f$\theta@f$/2), and the direction of the rotation vector is
18633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* equal to the direction of the axis of rotation.
18733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*
18833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* The three elements of the rotation vector are equal to the last three components of a unit quaternion
18933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* {x*sin(@f$\theta@f$/2), y*sin(@f$\theta@f$/2), z*sin(@f$\theta@f$/2)>. The 4th element is cos(@f$\theta@f$/2).
19033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*
19133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* Elements of the rotation vector are unitless. The x,y and z axis are defined in the same way as the acceleration sensor.
19233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* The reference coordinate system is defined as a direct orthonormal basis, where:
19333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
19433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    -X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East).
19533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    -Y is tangential to the ground at the device's current location and points towards the magnetic North Pole.
19633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    -Z points towards the sky and is perpendicular to the ground.
19733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Length 4.
19833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy 0 to 3, 3 = most accurate
19933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp Timestamp. In (ns) for Android.
20033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
20133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
20233ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_rotation_vector(float *values, int8_t *accuracy,
20333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        inv_time_t * timestamp)
20433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
20533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *accuracy = (int8_t) hal_out.accuracy_quat;
20633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *timestamp = hal_out.nav_timestamp;
20733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
20833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (hal_out.nav_quat[0] >= 0) {
20933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[0] = hal_out.nav_quat[1] * INV_TWO_POWER_NEG_30;
21033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[1] = hal_out.nav_quat[2] * INV_TWO_POWER_NEG_30;
21133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[2] = hal_out.nav_quat[3] * INV_TWO_POWER_NEG_30;
21233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[3] = hal_out.nav_quat[0] * INV_TWO_POWER_NEG_30;
21333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    } else {
21433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[0] = -hal_out.nav_quat[1] * INV_TWO_POWER_NEG_30;
21533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[1] = -hal_out.nav_quat[2] * INV_TWO_POWER_NEG_30;
21633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[2] = -hal_out.nav_quat[3] * INV_TWO_POWER_NEG_30;
21733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[3] = -hal_out.nav_quat[0] * INV_TWO_POWER_NEG_30;
21833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
21933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    values[4] = inv_get_heading_confidence_interval();
22033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
22133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return hal_out.nine_axis_status;
22233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
22333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
22433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
22533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Compass data (uT) in body frame.
22633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Compass data in (uT), length 3. May be calibrated by having
22733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*             biases removed and sensitivity adjusted
22833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy 0 to 3, 3 = most accurate
22933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp Timestamp. In (ns) for Android.
23033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
23133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
23233ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_magnetic_field(float *values, int8_t *accuracy,
23333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                        inv_time_t * timestamp)
23433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
23533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int status;
23633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    /* Converts fixed point to uT. Fixed point has 1 uT = 2^16.
23733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall     * So this is: 1 / 2^16*/
23833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall//#define COMPASS_CONVERSION 1.52587890625e-005f
23933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int i;
24033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
24133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *timestamp = hal_out.mag_timestamp;
24233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *accuracy = (int8_t) hal_out.accuracy_mag;
24333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
24433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    for (i=0; i<3; i++)  {
24533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        values[i] = hal_out.compass_float[i];
24633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
24733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (hal_out.compass_status & INV_NEW_DATA)
24833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 1;
24933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    else
25033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        status = 0;
25133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return status;
25233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
25333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
25433ce91b37062fa63af192f5643de93f3beebe854JP Abgrallstatic void inv_get_rotation(float r[3][3])
25533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
25633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long rot[9];
25733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    float conv = 1.f / (1L<<30);
25833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
25933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_quaternion_to_rotation(hal_out.nav_quat, rot);
26033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[0][0] = rot[0]*conv;
26133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[0][1] = rot[1]*conv;
26233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[0][2] = rot[2]*conv;
26333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[1][0] = rot[3]*conv;
26433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[1][1] = rot[4]*conv;
26533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[1][2] = rot[5]*conv;
26633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[2][0] = rot[6]*conv;
26733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[2][1] = rot[7]*conv;
26833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    r[2][2] = rot[8]*conv;
26933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
27033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
27133ce91b37062fa63af192f5643de93f3beebe854JP Abgrallstatic void google_orientation(float *g)
27233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
27333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    float rad2deg = (float)(180.0 / M_PI);
27433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    float R[3][3];
27533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
27633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_rotation(R);
27733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
27833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    g[0] = atan2f(-R[1][0], R[0][0]) * rad2deg;
27933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    g[1] = atan2f(-R[2][1], R[2][2]) * rad2deg;
28033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    g[2] = asinf ( R[2][0])          * rad2deg;
28133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (g[0] < 0)
28233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        g[0] += 360;
28333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
28433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
28533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
28633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** This corresponds to Sensor.TYPE_ORIENTATION. All values are angles in degrees.
28733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] values Length 3, Degrees.<br>
28833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        - values[0]: Azimuth, angle between the magnetic north direction
28933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*         and the y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, 270=West<br>
29033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        - values[1]: Pitch, rotation around x-axis (-180 to 180), with positive values
29133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*         when the z-axis moves toward the y-axis.<br>
29233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        - values[2]: Roll, rotation around y-axis (-90 to 90), with positive
29333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*          values when the x-axis moves toward the z-axis.<br>
29433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*
29533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @note  This definition is different from yaw, pitch and roll used in aviation
29633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        where the X axis is along the long side of the plane (tail to nose).
29733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        Note: This sensor type exists for legacy reasons, please use getRotationMatrix()
29833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        in conjunction with remapCoordinateSystem() and getOrientation() to compute
29933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        these values instead.
30033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        Important note: For historical reasons the roll angle is positive in the
30133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        clockwise direction (mathematically speaking, it should be positive in
30233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*        the counter-clockwise direction).
30333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] accuracy Accuracy of the measurment, 0 is least accurate, while 3 is most accurate.
30433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[out] timestamp The timestamp for this sensor.
30533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return     Returns 1 if the data was updated or 0 if it was not updated.
30633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
30733ce91b37062fa63af192f5643de93f3beebe854JP Abgrallint inv_get_sensor_type_orientation(float *values, int8_t *accuracy,
30833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                     inv_time_t * timestamp)
30933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
31033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *accuracy = (int8_t) hal_out.accuracy_quat;
31133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    *timestamp = hal_out.nav_timestamp;
31233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
31333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    google_orientation(values);
31433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
31533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return hal_out.nine_axis_status;
31633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
31733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
31833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Main callback to generate HAL outputs. Typically not called by library users.
31933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @param[in] sensor_cal Input variable to take sensor data whenever there is new
32033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* sensor data.
32133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return Returns INV_SUCCESS if successful or an error code if not.
32233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
32333ce91b37062fa63af192f5643de93f3beebe854JP Abgrallinv_error_t inv_generate_hal_outputs(struct inv_sensor_cal_t *sensor_cal)
32433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
32533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int use_sensor = 0;
32633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long sr = 1000;
32733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    long compass[3];
32833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int8_t accuracy;
32933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int i;
33033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    (void) sensor_cal;
33133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
33233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_quaternion_set(hal_out.nav_quat, &hal_out.accuracy_quat,
33333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                           &hal_out.nav_timestamp);
33433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    hal_out.gyro_status = sensor_cal->gyro.status;
33533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    hal_out.accel_status = sensor_cal->accel.status;
33633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    hal_out.compass_status = sensor_cal->compass.status;
33733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
33833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    // Find the highest sample rate and tie generating 9-axis to that one.
33933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if (sensor_cal->gyro.status & INV_SENSOR_ON) {
34033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        sr = sensor_cal->gyro.sample_rate_ms;
34133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        use_sensor = 0;
34233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
34333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if ((sensor_cal->accel.status & INV_SENSOR_ON) && (sr > sensor_cal->accel.sample_rate_ms)) {
34433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        sr = sensor_cal->accel.sample_rate_ms;
34533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        use_sensor = 1;
34633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
34733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if ((sensor_cal->compass.status & INV_SENSOR_ON) && (sr > sensor_cal->compass.sample_rate_ms)) {
34833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        sr = sensor_cal->compass.sample_rate_ms;
34933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        use_sensor = 2;
35033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
35133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    if ((sensor_cal->quat.status & INV_SENSOR_ON) && (sr > sensor_cal->quat.sample_rate_ms)) {
35233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        sr = sensor_cal->quat.sample_rate_ms;
35333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        use_sensor = 3;
35433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
35533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
35633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    switch (use_sensor) {
35733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    default:
35833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    case 0:
35933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nine_axis_status = (sensor_cal->gyro.status & INV_NEW_DATA) ? 1 : 0;
36033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nav_timestamp = sensor_cal->gyro.timestamp;
36133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        break;
36233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    case 1:
36333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nine_axis_status = (sensor_cal->accel.status & INV_NEW_DATA) ? 1 : 0;
36433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nav_timestamp = sensor_cal->accel.timestamp;
36533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        break;
36633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    case 2:
36733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nine_axis_status = (sensor_cal->compass.status & INV_NEW_DATA) ? 1 : 0;
36833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nav_timestamp = sensor_cal->compass.timestamp;
36933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        break;
37033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    case 3:
37133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nine_axis_status = (sensor_cal->quat.status & INV_NEW_DATA) ? 1 : 0;
37233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        hal_out.nav_timestamp = sensor_cal->quat.timestamp;
37333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        break;
37433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
37533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
37633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    /* Converts fixed point to uT. Fixed point has 1 uT = 2^16.
37733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall     * So this is: 1 / 2^16*/
37833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    #define COMPASS_CONVERSION 1.52587890625e-005f
37933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
38033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_get_compass_set(compass, &accuracy, &(hal_out.mag_timestamp) );
38133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    hal_out.accuracy_mag = (int ) accuracy;
38233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
38333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    for (i=0; i<3; i++) {
38433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        if ((sensor_cal->compass.status & (INV_NEW_DATA | INV_CONTIGUOUS)) ==
38533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                                             INV_NEW_DATA )  {
38633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall            // set the state variables to match output with input
38733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall            inv_calc_state_to_match_output(&hal_out.lp_filter[i], (float ) compass[i]);
38833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        }
38933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
39033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        if ((sensor_cal->compass.status & (INV_NEW_DATA | INV_RAW_DATA)) ==
39133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                         (INV_NEW_DATA | INV_RAW_DATA)   )  {
39233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
39333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall            hal_out.compass_float[i] = inv_biquad_filter_process(&hal_out.lp_filter[i],
39433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                                           (float ) compass[i]) * COMPASS_CONVERSION;
39533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
39633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        } else if ((sensor_cal->compass.status & INV_NEW_DATA) == INV_NEW_DATA )  {
39733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall            hal_out.compass_float[i] = (float ) compass[i] * COMPASS_CONVERSION;
39833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        }
39933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
40033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
40133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return INV_SUCCESS;
40233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
40333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
40433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Turns off generation of HAL outputs.
40533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return Returns INV_SUCCESS if successful or an error code if not.
40633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall */
40733ce91b37062fa63af192f5643de93f3beebe854JP Abgrallinv_error_t inv_stop_hal_outputs(void)
40833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
40933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_error_t result;
41033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    result = inv_unregister_data_cb(inv_generate_hal_outputs);
41133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return result;
41233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
41333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
41433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Turns on generation of HAL outputs. This should be called after inv_stop_hal_outputs()
41533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* to turn generation of HAL outputs back on. It is automatically called by inv_enable_hal_outputs().
41633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return Returns INV_SUCCESS if successful or an error code if not.
41733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
41833ce91b37062fa63af192f5643de93f3beebe854JP Abgrallinv_error_t inv_start_hal_outputs(void)
41933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
42033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_error_t result;
42133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    result =
42233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        inv_register_data_cb(inv_generate_hal_outputs,
42333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                             INV_PRIORITY_HAL_OUTPUTS,
42433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall                             INV_GYRO_NEW | INV_ACCEL_NEW | INV_MAG_NEW);
42533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return result;
42633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
42733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/* file name: lowPassFilterCoeff_1_6.c */
42833ce91b37062fa63af192f5643de93f3beebe854JP Abgrallfloat compass_low_pass_filter_coeff[5] =
42933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{+2.000000000000f, +1.000000000000f, -1.279632424998f, +0.477592250073f, +0.049489956269f};
43033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
43133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Initializes hal outputs class. This is called automatically by the
43233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* enable function. It may be called any time the feature is enabled, but
43333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* is typically not needed to be called by outside callers.
43433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return Returns INV_SUCCESS if successful or an error code if not.
43533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
43633ce91b37062fa63af192f5643de93f3beebe854JP Abgrallinv_error_t inv_init_hal_outputs(void)
43733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
43833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    int i;
43933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    memset(&hal_out, 0, sizeof(hal_out));
44033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    for (i=0; i<3; i++)  {
44133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall        inv_init_biquad_filter(&hal_out.lp_filter[i], compass_low_pass_filter_coeff);
44233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    }
44333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
44433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return INV_SUCCESS;
44533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
44633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
44733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Turns on creation and storage of HAL type results.
44833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall* @return Returns INV_SUCCESS if successful or an error code if not.
44933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
45033ce91b37062fa63af192f5643de93f3beebe854JP Abgrallinv_error_t inv_enable_hal_outputs(void)
45133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
45233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_error_t result;
45333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
45433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall	// don't need to check the result for inv_init_hal_outputs
45533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall	// since it's always INV_SUCCESS
45633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall	inv_init_hal_outputs();
45733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
45833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    result = inv_register_mpl_start_notification(inv_start_hal_outputs);
45933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return result;
46033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
46133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
46233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/** Turns off creation and storage of HAL type results.
46333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall*/
46433ce91b37062fa63af192f5643de93f3beebe854JP Abgrallinv_error_t inv_disable_hal_outputs(void)
46533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall{
46633ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_error_t result;
46733ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
46833ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    inv_stop_hal_outputs(); // Ignore error if we have already stopped this
46933ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    result = inv_unregister_mpl_start_notification(inv_start_hal_outputs);
47033ce91b37062fa63af192f5643de93f3beebe854JP Abgrall    return result;
47133ce91b37062fa63af192f5643de93f3beebe854JP Abgrall}
47233ce91b37062fa63af192f5643de93f3beebe854JP Abgrall
47333ce91b37062fa63af192f5643de93f3beebe854JP Abgrall/**
47433ce91b37062fa63af192f5643de93f3beebe854JP Abgrall * @}
47533ce91b37062fa63af192f5643de93f3beebe854JP Abgrall */
476