예제 #1
0
void ahrs_align(void) {

#if USE_MAGNETOMETER
  /* Compute an initial orientation from accel and mag directly as quaternion */
  ahrs_float_get_quat_from_accel_mag(&ahrs_impl.ltp_to_imu_quat, &ahrs_aligner.lp_accel, &ahrs_aligner.lp_mag);
  ahrs_impl.heading_aligned = TRUE;
#else
  /* Compute an initial orientation from accel and just set heading to zero */
  ahrs_float_get_quat_from_accel(&ahrs_impl.ltp_to_imu_quat, &ahrs_aligner.lp_accel);
  ahrs_impl.heading_aligned = FALSE;
#endif

  /* Convert initial orientation from quat to rotation matrix representations. */
  FLOAT_RMAT_OF_QUAT(ahrs_impl.ltp_to_imu_rmat, ahrs_impl.ltp_to_imu_quat);

  /* Compute initial body orientation */
  compute_body_orientation_and_rates();

  /* used averaged gyro as initial value for bias */
  struct Int32Rates bias0;
  RATES_COPY(bias0, ahrs_aligner.lp_gyro);
  RATES_FLOAT_OF_BFP(ahrs_impl.gyro_bias, bias0);

  ahrs.status = AHRS_RUNNING;
}
예제 #2
0
void ahrs_propagate(void) {

  /* converts gyro to floating point */
  struct FloatRates gyro_float;
  RATES_FLOAT_OF_BFP(gyro_float, imu.gyro_prev);
  /* unbias measurement */
  RATES_SUB(gyro_float, ahrs_impl.gyro_bias);

#ifdef AHRS_PROPAGATE_LOW_PASS_RATES
  const float alpha = 0.1;
  FLOAT_RATES_LIN_CMB(ahrs_impl.imu_rate, ahrs_impl.imu_rate, (1.-alpha), gyro_float, alpha);
#else
  RATES_COPY(ahrs_impl.imu_rate,gyro_float);
#endif

  /* add correction     */
  struct FloatRates omega;
  RATES_SUM(omega, gyro_float, ahrs_impl.rate_correction);
  /* and zeros it */
  FLOAT_RATES_ZERO(ahrs_impl.rate_correction);

  const float dt = 1./AHRS_PROPAGATE_FREQUENCY;
#if AHRS_PROPAGATE_RMAT
  FLOAT_RMAT_INTEGRATE_FI(ahrs_impl.ltp_to_imu_rmat, omega, dt);
  float_rmat_reorthogonalize(&ahrs_impl.ltp_to_imu_rmat);
  FLOAT_QUAT_OF_RMAT(ahrs_impl.ltp_to_imu_quat, ahrs_impl.ltp_to_imu_rmat);
#endif
#if AHRS_PROPAGATE_QUAT
  FLOAT_QUAT_INTEGRATE(ahrs_impl.ltp_to_imu_quat, omega, dt);
  FLOAT_QUAT_NORMALIZE(ahrs_impl.ltp_to_imu_quat);
  FLOAT_RMAT_OF_QUAT(ahrs_impl.ltp_to_imu_rmat, ahrs_impl.ltp_to_imu_quat);
#endif
  compute_body_orientation_and_rates();

}
예제 #3
0
static inline void compute_ahrs_representations(void) {
#if (OUTPUTMODE==2)         // Only accelerometer info (debugging purposes)
  ahrs_float.ltp_to_imu_euler.phi = atan2(accel_float.y,accel_float.z);    // atan2(acc_y,acc_z)
  ahrs_float.ltp_to_imu_euler.theta = -asin((accel_float.x)/GRAVITY); // asin(acc_x)
  ahrs_float.ltp_to_imu_euler.psi = 0;
#else
  ahrs_float.ltp_to_imu_euler.phi = atan2(DCM_Matrix[2][1],DCM_Matrix[2][2]);
  ahrs_float.ltp_to_imu_euler.theta = -asin(DCM_Matrix[2][0]);
  ahrs_float.ltp_to_imu_euler.psi = atan2(DCM_Matrix[1][0],DCM_Matrix[0][0]);
  ahrs_float.ltp_to_imu_euler.psi += M_PI; // Rotating the angle 180deg to fit for PPRZ
#endif

  /* set quaternion and rotation matrix representations as well */
  FLOAT_QUAT_OF_EULERS(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_euler);
  FLOAT_RMAT_OF_EULERS(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_euler);

  compute_body_orientation_and_rates();

  /*
    RunOnceEvery(6,DOWNLINK_SEND_RMAT_DEBUG(DefaultChannel, DefaultDevice,
    &(DCM_Matrix[0][0]),
    &(DCM_Matrix[0][1]),
    &(DCM_Matrix[0][2]),

    &(DCM_Matrix[1][0]),
    &(DCM_Matrix[1][1]),
    &(DCM_Matrix[1][2]),

    &(DCM_Matrix[2][0]),
    &(DCM_Matrix[2][1]),
    &(DCM_Matrix[2][2])

    ));
  */
}
예제 #4
0
void ahrs_propagate(void) {

  /* converts gyro to floating point */
  struct FloatRates gyro_float;
  RATES_FLOAT_OF_BFP(gyro_float, imu.gyro_prev);
  /* unbias measurement */
  RATES_DIFF(ahrs_float.imu_rate, gyro_float, ahrs_impl.gyro_bias);
  const float dt = 1./512.;
  /* add correction     */
  struct FloatRates omega;
  RATES_SUM(omega, ahrs_float.imu_rate, ahrs_impl.rate_correction);
  //  DISPLAY_FLOAT_RATES("omega ", omega);
  /* and zeros it */
  FLOAT_RATES_ZERO(ahrs_impl.rate_correction);

  /* first order integration of rotation matrix */
  struct FloatRMat exp_omega_dt = {
    { 1.        ,  dt*omega.r, -dt*omega.q,
     -dt*omega.r,  1.        ,  dt*omega.p,
      dt*omega.q, -dt*omega.p,  1.                       }};
  struct FloatRMat R_tdt;
  FLOAT_RMAT_COMP(R_tdt, ahrs_float.ltp_to_imu_rmat, exp_omega_dt);
  memcpy(&ahrs_float.ltp_to_imu_rmat, &R_tdt, sizeof(R_tdt));

  float_rmat_reorthogonalize(&ahrs_float.ltp_to_imu_rmat);
  //  struct FloatRMat test;
  //  FLOAT_RMAT_COMP_INV(test, ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_rmat);
  //  DISPLAY_FLOAT_RMAT("foo", test);

  compute_imu_quat_and_euler_from_rmat();
  compute_body_orientation_and_rates();

}
예제 #5
0
void ahrs_align(void)
{
  /* Currently not really simulated
   * body and imu have the same frame and always set to true value from sim
   */

  update_ahrs_from_sim();

  /* Compute initial body orientation */
  compute_body_orientation_and_rates();

  ahrs.status = AHRS_RUNNING;
}
예제 #6
0
void update_ahrs_from_sim(void) {
  ahrs_float.ltp_to_imu_euler.phi = sim_phi;
  ahrs_float.ltp_to_imu_euler.theta = sim_theta;
  ahrs_float.ltp_to_imu_euler.psi = sim_psi;

  ahrs_float.imu_rate.p = sim_p;
  ahrs_float.imu_rate.q = sim_q;

  /* set quaternion and rotation matrix representations as well */
  FLOAT_QUAT_OF_EULERS(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_euler);
  FLOAT_RMAT_OF_EULERS(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_euler);

  compute_body_orientation_and_rates();
}
예제 #7
0
void ahrs_align(void) {

  /* Compute an initial orientation using euler angles */
  ahrs_float_get_euler_from_accel_mag(&ahrs_float.ltp_to_imu_euler, &ahrs_aligner.lp_accel, &ahrs_aligner.lp_mag);
  /* Convert initial orientation in quaternion and rotation matrice representations. */
  FLOAT_QUAT_OF_EULERS(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_euler);
  FLOAT_RMAT_OF_QUAT(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_quat);
  /* Compute initial body orientation */
  compute_body_orientation_and_rates();

  /* used averaged gyro as initial value for bias */
  struct Int32Rates bias0;
  RATES_COPY(bias0, ahrs_aligner.lp_gyro);
  RATES_FLOAT_OF_BFP(ahrs_impl.gyro_bias, bias0);

  ahrs.status = AHRS_RUNNING;

}
예제 #8
0
void ahrs_update_fw_estimator( void )
{
#if (OUTPUTMODE==2)         // Only accelerometer info (debugging purposes)
  ahrs_float.ltp_to_imu_euler.phi = atan2(accel_float.y,accel_float.z);    // atan2(acc_y,acc_z)
  ahrs_float.ltp_to_imu_euler.theta = -asin((accel_float.x)/GRAVITY); // asin(acc_x)
  ahrs_float.ltp_to_imu_euler.psi = 0;
#else
  ahrs_float.ltp_to_imu_euler.phi = atan2(DCM_Matrix[2][1],DCM_Matrix[2][2]);
  ahrs_float.ltp_to_imu_euler.theta = -asin(DCM_Matrix[2][0]);
  ahrs_float.ltp_to_imu_euler.psi = atan2(DCM_Matrix[1][0],DCM_Matrix[0][0]);
  ahrs_float.ltp_to_imu_euler.psi += M_PI; // Rotating the angle 180deg to fit for PPRZ
#endif

  /* set quaternion and rotation matrix representations as well */
  FLOAT_QUAT_OF_EULERS(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_euler);
  FLOAT_RMAT_OF_EULERS(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_euler);

  compute_body_orientation_and_rates();

  // export results to estimator
  estimator_phi   = ahrs_float.ltp_to_body_euler.phi - ins_roll_neutral;
  estimator_theta = ahrs_float.ltp_to_body_euler.theta - ins_pitch_neutral;
  estimator_psi   = ahrs_float.ltp_to_body_euler.psi;

  estimator_p = ahrs_float.body_rate.p;
  estimator_q = ahrs_float.body_rate.q;
/*
  RunOnceEvery(6,DOWNLINK_SEND_RMAT_DEBUG(DefaultChannel,
    &(DCM_Matrix[0][0]),
    &(DCM_Matrix[0][1]),
    &(DCM_Matrix[0][2]),

    &(DCM_Matrix[1][0]),
    &(DCM_Matrix[1][1]),
    &(DCM_Matrix[1][2]),

    &(DCM_Matrix[2][0]),
    &(DCM_Matrix[2][1]),
    &(DCM_Matrix[2][2])

  ));
*/
}
예제 #9
0
void ahrs_propagate(float dt) {

  /* converts gyro to floating point */
  struct FloatRates gyro_float;
  RATES_FLOAT_OF_BFP(gyro_float, imu.gyro_prev);
  /* unbias measurement */
  RATES_SUB(gyro_float, ahrs_impl.gyro_bias);

#ifdef AHRS_PROPAGATE_LOW_PASS_RATES
  const float alpha = 0.1;
  FLOAT_RATES_LIN_CMB(ahrs_impl.imu_rate, ahrs_impl.imu_rate, (1.-alpha), gyro_float, alpha);
#else
  RATES_COPY(ahrs_impl.imu_rate,gyro_float);
#endif

  /* add correction     */
  struct FloatRates omega;
  RATES_SUM(omega, gyro_float, ahrs_impl.rate_correction);
  /* and zeros it */
  FLOAT_RATES_ZERO(ahrs_impl.rate_correction);

#if AHRS_PROPAGATE_RMAT
  float_rmat_integrate_fi(&ahrs_impl.ltp_to_imu_rmat, &omega, dt);
  float_rmat_reorthogonalize(&ahrs_impl.ltp_to_imu_rmat);
  float_quat_of_rmat(&ahrs_impl.ltp_to_imu_quat, &ahrs_impl.ltp_to_imu_rmat);
#endif
#if AHRS_PROPAGATE_QUAT
  float_quat_integrate(&ahrs_impl.ltp_to_imu_quat, &omega, dt);
  float_quat_normalize(&ahrs_impl.ltp_to_imu_quat);
  float_rmat_of_quat(&ahrs_impl.ltp_to_imu_rmat, &ahrs_impl.ltp_to_imu_quat);
#endif
  compute_body_orientation_and_rates();

  // increase accel and mag propagation counters
  ahrs_impl.accel_cnt++;
  ahrs_impl.mag_cnt++;
}