void ahrs_realign_heading(float heading) { FLOAT_ANGLE_NORMALIZE(heading); /* quaternion representing only the heading rotation from ltp to body */ struct FloatQuat q_h_new; q_h_new.qx = 0.0; q_h_new.qy = 0.0; q_h_new.qz = sinf(heading/2.0); q_h_new.qi = cosf(heading/2.0); struct FloatQuat* ltp_to_body_quat = stateGetNedToBodyQuat_f(); /* quaternion representing current heading only */ struct FloatQuat q_h; QUAT_COPY(q_h, *ltp_to_body_quat); q_h.qx = 0.; q_h.qy = 0.; FLOAT_QUAT_NORMALIZE(q_h); /* quaternion representing rotation from current to new heading */ struct FloatQuat q_c; FLOAT_QUAT_INV_COMP_NORM_SHORTEST(q_c, q_h, q_h_new); /* correct current heading in body frame */ struct FloatQuat q; FLOAT_QUAT_COMP_NORM_SHORTEST(q, q_c, *ltp_to_body_quat); /* compute ltp to imu rotation quaternion and matrix */ FLOAT_QUAT_COMP(ahrs_impl.ltp_to_imu_quat, q, ahrs_impl.body_to_imu_quat); FLOAT_RMAT_OF_QUAT(ahrs_impl.ltp_to_imu_rmat, ahrs_impl.ltp_to_imu_quat); /* set state */ stateSetNedToBodyQuat_f(&q); ahrs_impl.heading_aligned = TRUE; }
void stabilization_attitude_read_rc_setpoint_quat_f(struct FloatQuat* q_sp, bool_t in_flight) { // FIXME: remove me, do in quaternion directly // is currently still needed, since the yaw setpoint integration is done in eulers #if defined STABILIZATION_ATTITUDE_TYPE_INT stabilization_attitude_read_rc_setpoint_eulers(&stab_att_sp_euler, in_flight); #else stabilization_attitude_read_rc_setpoint_eulers_f(&stab_att_sp_euler, in_flight); #endif struct FloatQuat q_rp_cmd; #if USE_EARTH_BOUND_RC_SETPOINT stabilization_attitude_read_rc_roll_pitch_earth_quat_f(&q_rp_cmd); #else stabilization_attitude_read_rc_roll_pitch_quat_f(&q_rp_cmd); #endif /* get current heading */ const struct FloatVect3 zaxis = {0., 0., 1.}; struct FloatQuat q_yaw; //Care Free mode if (guidance_h_mode == GUIDANCE_H_MODE_CARE_FREE) { //care_free_heading has been set to current psi when entering care free mode. FLOAT_QUAT_OF_AXIS_ANGLE(q_yaw, zaxis, care_free_heading); } else { FLOAT_QUAT_OF_AXIS_ANGLE(q_yaw, zaxis, stateGetNedToBodyEulers_f()->psi); } /* roll/pitch commands applied to to current heading */ struct FloatQuat q_rp_sp; FLOAT_QUAT_COMP(q_rp_sp, q_yaw, q_rp_cmd); FLOAT_QUAT_NORMALIZE(q_rp_sp); if (in_flight) { /* get current heading setpoint */ struct FloatQuat q_yaw_sp; #if defined STABILIZATION_ATTITUDE_TYPE_INT FLOAT_QUAT_OF_AXIS_ANGLE(q_yaw_sp, zaxis, ANGLE_FLOAT_OF_BFP(stab_att_sp_euler.psi)); #else FLOAT_QUAT_OF_AXIS_ANGLE(q_yaw_sp, zaxis, stab_att_sp_euler.psi); #endif /* rotation between current yaw and yaw setpoint */ struct FloatQuat q_yaw_diff; FLOAT_QUAT_COMP_INV(q_yaw_diff, q_yaw_sp, q_yaw); /* compute final setpoint with yaw */ FLOAT_QUAT_COMP_NORM_SHORTEST(*q_sp, q_rp_sp, q_yaw_diff); } else { QUAT_COPY(*q_sp, q_rp_sp); } }
void stabilization_attitude_read_rc(bool_t in_flight) { #if USE_SETPOINTS_WITH_TRANSITIONS stabilization_attitude_read_rc_absolute(in_flight); #else //FIXME: remove me, do in quaternion directly stabilization_attitude_read_rc_setpoint_eulers(&stab_att_sp_euler, in_flight); struct FloatQuat q_rp_cmd; #if USE_EARTH_BOUND_RC_SETPOINT stabilization_attitude_read_rc_roll_pitch_earth_quat(&q_rp_cmd); #else stabilization_attitude_read_rc_roll_pitch_quat(&q_rp_cmd); #endif /* get current heading */ const struct FloatVect3 zaxis = {0., 0., 1.}; struct FloatQuat q_yaw; FLOAT_QUAT_OF_AXIS_ANGLE(q_yaw, zaxis, ANGLE_FLOAT_OF_BFP(stateGetNedToBodyEulers_i()->psi)); /* apply roll and pitch commands with respect to current heading */ struct FloatQuat q_sp; FLOAT_QUAT_COMP(q_sp, q_yaw, q_rp_cmd); FLOAT_QUAT_NORMALIZE(q_sp); if (in_flight) { /* get current heading setpoint */ struct FloatQuat q_yaw_sp; FLOAT_QUAT_OF_AXIS_ANGLE(q_yaw_sp, zaxis, ANGLE_FLOAT_OF_BFP(stab_att_sp_euler.psi)); /* rotation between current yaw and yaw setpoint */ struct FloatQuat q_yaw_diff; FLOAT_QUAT_COMP_INV(q_yaw_diff, q_yaw_sp, q_yaw); /* temporary copy with roll/pitch command and current heading */ struct FloatQuat q_rp_sp; QUAT_COPY(q_rp_sp, q_sp); /* compute final setpoint with yaw */ FLOAT_QUAT_COMP_NORM_SHORTEST(q_sp, q_rp_sp, q_yaw_diff); } QUAT_BFP_OF_REAL(stab_att_sp_quat, q_sp); #endif }