예제 #1
0
/**
 *  Magnetic heading/field strength in body frame.
 *  TODO: No difference between mag_north and true_north yet.
 *  @param[out] mag_north   Heading relative to magnetic north in degrees.
 *  @param[out] true_north  Heading relative to true north in degrees.
 *  @param[out] values      Field strength in milligauss.
 *  @param[out] accuracy    0 (uncalibrated) to 3 (most accurate).
 *  @param[out] timestamp   Time when sensor was sampled.
 */
void inv_get_sensor_type_compass_float(float *mag_north, float *true_north,
        float *values, int8_t *accuracy, inv_time_t *timestamp)
{
    long compass[3];
    long q00, q12, q22, q03, t1, t2;

    /* 1 uT = 10 milligauss. */
#define COMPASS_CONVERSION  (10 / 65536.f)
    inv_get_compass_set(compass, accuracy, timestamp);
    if (values) {
        values[0] = (float)compass[0]*COMPASS_CONVERSION;
        values[1] = (float)compass[1]*COMPASS_CONVERSION;
        values[2] = (float)compass[2]*COMPASS_CONVERSION;
    }

    /* TODO: Stolen from euler angle computation. Calculate this only once per
     * callback.
     */
    q00 = inv_q29_mult(dl_out.quat[0], dl_out.quat[0]);
    q12 = inv_q29_mult(dl_out.quat[1], dl_out.quat[2]);
    q22 = inv_q29_mult(dl_out.quat[2], dl_out.quat[2]);
    q03 = inv_q29_mult(dl_out.quat[0], dl_out.quat[3]);
    t1 = q12 - q03;
    t2 = q22 + q00 - (1L << 30);
    if (mag_north) {
        *mag_north = atan2f((float) t1, (float) t2) * 180.f / (float) M_PI;
        if (*mag_north < 0)
            *mag_north += 360;
    }
    if (true_north) {
        if (!mag_north) {
            *true_north = atan2f((float) t1, (float) t2) * 180.f / (float) M_PI;
            if (*true_north < 0)
                *true_north += 360;
        } else {
            *true_north = *mag_north;
        }
    }
}
예제 #2
0
파일: eMPL_outputs.c 프로젝트: fishr/Origin
/**
 *  @brief      Quaternion-derived heading.
 *  @param[out] data        Heading in degrees, q16 fixed point.
 *  @param[out] accuracy    Accuracy of the measurement from 0 (least accurate)
 *                          to 3 (most accurate).
 *  @param[out] timestamp   The time in milliseconds when this sensor was read.
 *  @return     1 if data was updated. 
 */
int inv_get_sensor_type_heading(long *data, int8_t *accuracy, inv_time_t *timestamp)
{
    long t1, t2, q00, q03, q12, q22;
    float fdata;

    q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]);
    q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]);
    q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]);
    q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]);

    /* X component of the Ybody axis in World frame */
    t1 = q12 - q03;

    /* Y component of the Ybody axis in World frame */
    t2 = q22 + q00 - (1L << 30);
    fdata = atan2f((float) t1, (float) t2) * 180.f / (float) M_PI;
    if (fdata < 0.f)
        fdata += 360.f;
    data[0] = (long)(fdata * 65536.f);

    accuracy[0] = eMPL_out.quat_accuracy;
    timestamp[0] = eMPL_out.nine_axis_timestamp;
    return eMPL_out.nine_axis_status;
}
예제 #3
0
inv_error_t inv_get_gravity_6x(long *data)
{
    data[0] =
        inv_q29_mult(rh.gam_quat[1], rh.gam_quat[3]) - inv_q29_mult(rh.gam_quat[2], rh.gam_quat[0]);
    data[1] =
        inv_q29_mult(rh.gam_quat[2], rh.gam_quat[3]) + inv_q29_mult(rh.gam_quat[1], rh.gam_quat[0]);
    data[2] =
        (inv_q29_mult(rh.gam_quat[3], rh.gam_quat[3]) + inv_q29_mult(rh.gam_quat[0], rh.gam_quat[0])) -
        1073741824L;
    return INV_SUCCESS;
}
예제 #4
0
파일: eMPL_outputs.c 프로젝트: fishr/Origin
/**
 *  @brief      Body-to-world frame euler angles.
 *  The euler angles are output with the following convention:
 *  Pitch: -180 to 180
 *  Roll: -90 to 90
 *  Yaw: -180 to 180
 *  @param[out] data        Euler angles in degrees, q16 fixed point.
 *  @param[out] accuracy    Accuracy of the measurement from 0 (least accurate)
 *                          to 3 (most accurate).
 *  @param[out] timestamp   The time in milliseconds when this sensor was read.
 *  @return     1 if data was updated.
 */
int inv_get_sensor_type_euler(long *data, int8_t *accuracy, inv_time_t *timestamp)
{
    long t1, t2, t3;
    long q00, q01, q02, q03, q11, q12, q13, q22, q23, q33;
    float values[3];

    q00 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[0]);
    q01 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[1]);
    q02 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[2]);
    q03 = inv_q29_mult(eMPL_out.quat[0], eMPL_out.quat[3]);
    q11 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[1]);
    q12 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[2]);
    q13 = inv_q29_mult(eMPL_out.quat[1], eMPL_out.quat[3]);
    q22 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[2]);
    q23 = inv_q29_mult(eMPL_out.quat[2], eMPL_out.quat[3]);
    q33 = inv_q29_mult(eMPL_out.quat[3], eMPL_out.quat[3]);

    /* X component of the Ybody axis in World frame */
    t1 = q12 - q03;

    /* Y component of the Ybody axis in World frame */
    t2 = q22 + q00 - (1L << 30);
    values[2] = -atan2f((float) t1, (float) t2) * 180.f / (float) M_PI;

    /* Z component of the Ybody axis in World frame */
    t3 = q23 + q01;
    values[0] =
        atan2f((float) t3,
                sqrtf((float) t1 * t1 +
                      (float) t2 * t2)) * 180.f / (float) M_PI;
    /* Z component of the Zbody axis in World frame */
    t2 = q33 + q00 - (1L << 30);
    if (t2 < 0) {
        if (values[0] >= 0)
            values[0] = 180.f - values[0];
        else
            values[0] = -180.f - values[0];
    }

    /* X component of the Xbody axis in World frame */
    t1 = q11 + q00 - (1L << 30);
    /* Y component of the Xbody axis in World frame */
    t2 = q12 + q03;
    /* Z component of the Xbody axis in World frame */
    t3 = q13 - q02;

    values[1] =
        (atan2f((float)(q33 + q00 - (1L << 30)), (float)(q13 - q02)) *
          180.f / (float) M_PI - 90);
    if (values[1] >= 90)
        values[1] = 180 - values[1];

    if (values[1] < -90)
        values[1] = -180 - values[1];
    data[0] = (long)(values[0] * 65536.f);
    data[1] = (long)(values[1] * 65536.f);
    data[2] = (long)(values[2] * 65536.f);

    accuracy[0] = eMPL_out.quat_accuracy;
    timestamp[0] = eMPL_out.nine_axis_timestamp;
    return eMPL_out.nine_axis_status;
}