void ahrs_update_accel(void) {

    // c2 = ltp z-axis in imu-frame
    struct Int32Vect3 c2 = { RMAT_ELMT(ahrs.ltp_to_imu_rmat, 0,2),
               RMAT_ELMT(ahrs.ltp_to_imu_rmat, 1,2),
               RMAT_ELMT(ahrs.ltp_to_imu_rmat, 2,2)
    };
    struct Int32Vect3 residual;

    if (ahrs_impl.correct_gravity && ahrs_impl.ltp_vel_norm_valid) {
        /*
         * centrifugal acceleration in body frame
         * a_c_body = omega x (omega x r)
         * (omega x r) = tangential velocity in body frame
         * a_c_body = omega x vel_tangential_body
         * assumption: tangential velocity only along body x-axis
         */

        // FIXME: check overflows !
        const struct Int32Vect3 vel_tangential_body = {(ahrs_impl.ltp_vel_norm>>INT32_ACCEL_FRAC), 0.0, 0.0};
        struct Int32Vect3 acc_c_body;
        VECT3_RATES_CROSS_VECT3(acc_c_body, ahrs.body_rate, vel_tangential_body);
        INT32_VECT3_RSHIFT(acc_c_body, acc_c_body, INT32_SPEED_FRAC+INT32_RATE_FRAC-INT32_ACCEL_FRAC-INT32_ACCEL_FRAC);

        /* convert centrifucal acceleration from body to imu frame */
        struct Int32Vect3 acc_c_imu;
        INT32_RMAT_VMULT(acc_c_imu, imu.body_to_imu_rmat, acc_c_body);

        /* and subtract it from imu measurement to get a corrected measurement of the gravitiy vector */
        struct Int32Vect3 corrected_gravity;
        INT32_VECT3_DIFF(corrected_gravity, imu.accel, acc_c_imu);

        /* compute the residual of gravity vector in imu frame */
        INT32_VECT3_CROSS_PRODUCT(residual, corrected_gravity, c2);
    } else {
示例#2
0
void ahrs_update_accel(void) {

  struct Int32Vect3 c2 = { RMAT_ELMT(ahrs.ltp_to_imu_rmat, 0,2),
			   RMAT_ELMT(ahrs.ltp_to_imu_rmat, 1,2),
			   RMAT_ELMT(ahrs.ltp_to_imu_rmat, 2,2)};
  struct Int32Vect3 residual;
#ifdef AHRS_GRAVITY_UPDATE_COORDINATED_TURN
  // FIXME: check overflow ?
  const struct Int32Vect3 Xdd_imu = {
    0,
     ((ahrs_impl.ltp_vel_norm>>INT32_ACCEL_FRAC) * ahrs.imu_rate.r)
    >>(INT32_SPEED_FRAC+INT32_RATE_FRAC-INT32_ACCEL_FRAC-INT32_ACCEL_FRAC),
    -((ahrs_impl.ltp_vel_norm>>INT32_ACCEL_FRAC) * ahrs.imu_rate.q)
    >>(INT32_SPEED_FRAC+INT32_RATE_FRAC-INT32_ACCEL_FRAC-INT32_ACCEL_FRAC)
  };
  struct Int32Vect3 corrected_gravity;
  VECT3_DIFF(corrected_gravity, imu.accel, Xdd_imu);
  INT32_VECT3_CROSS_PRODUCT(residual, corrected_gravity, c2);
#else
  INT32_VECT3_CROSS_PRODUCT(residual, imu.accel, c2);
#endif

  // residual FRAC : ACCEL_FRAC + TRIG_FRAC = 10 + 14 = 24
  // rate_correction FRAC = RATE_FRAC = 12
  // 2^12 / 2^24 * 5e-2 = 1/81920
  ahrs_impl.rate_correction.p += -residual.x/82000;
  ahrs_impl.rate_correction.q += -residual.y/82000;
  ahrs_impl.rate_correction.r += -residual.z/82000;

  // residual FRAC = ACCEL_FRAC + TRIG_FRAC = 10 + 14 = 24
  // high_rez_bias = RATE_FRAC+28 = 40
  // 2^40 / 2^24 * 5e-6 = 1/3.05

  //  ahrs_impl.high_rez_bias.p += residual.x*3;
  //  ahrs_impl.high_rez_bias.q += residual.y*3;
  //  ahrs_impl.high_rez_bias.r += residual.z*3;

  ahrs_impl.high_rez_bias.p += residual.x;
  ahrs_impl.high_rez_bias.q += residual.y;
  ahrs_impl.high_rez_bias.r += residual.z;


  /*                        */
  INT_RATES_RSHIFT(ahrs_impl.gyro_bias, ahrs_impl.high_rez_bias, 28);


}
示例#3
0
static inline void ahrs_update_mag_full(void) {
  const struct Int32Vect3 expected_ltp = {MAG_BFP_OF_REAL(AHRS_H_X),
					  MAG_BFP_OF_REAL(AHRS_H_Y),
					  MAG_BFP_OF_REAL(AHRS_H_Z)};
  struct Int32Vect3 expected_imu;
  INT32_RMAT_VMULT(expected_imu, ahrs.ltp_to_imu_rmat, expected_ltp);

  struct Int32Vect3 residual;
  INT32_VECT3_CROSS_PRODUCT(residual, imu.mag, expected_imu);

  ahrs_impl.rate_correction.p += residual.x/32/16;
  ahrs_impl.rate_correction.q += residual.y/32/16;
  ahrs_impl.rate_correction.r += residual.z/32/16;


  ahrs_impl.high_rez_bias.p += -residual.x/32*1024;
  ahrs_impl.high_rez_bias.q += -residual.y/32*1024;
  ahrs_impl.high_rez_bias.r += -residual.z/32*1024;


  INT_RATES_RSHIFT(ahrs_impl.gyro_bias, ahrs_impl.high_rez_bias, 28);

}