void stabilization_attitude_run(bool_t enable_integrator) { /* * Update reference */ stabilization_attitude_ref_update(); /* * Compute errors for feedback */ /* attitude error */ struct Int32Quat att_err; struct Int32Quat* att_quat = stateGetNedToBodyQuat_i(); INT32_QUAT_INV_COMP(att_err, *att_quat, stab_att_ref_quat); /* wrap it in the shortest direction */ INT32_QUAT_WRAP_SHORTEST(att_err); INT32_QUAT_NORMALIZE(att_err); /* rate error */ struct Int32Rates rate_err; struct Int32Rates* body_rate = stateGetBodyRates_i(); RATES_DIFF(rate_err, stab_att_ref_rate, *body_rate); /* integrated error */ if (enable_integrator) { struct Int32Quat new_sum_err, scaled_att_err; /* update accumulator */ scaled_att_err.qi = att_err.qi; scaled_att_err.qx = att_err.qx / IERROR_SCALE; scaled_att_err.qy = att_err.qy / IERROR_SCALE; scaled_att_err.qz = att_err.qz / IERROR_SCALE; INT32_QUAT_COMP(new_sum_err, stabilization_att_sum_err_quat, scaled_att_err); INT32_QUAT_NORMALIZE(new_sum_err); QUAT_COPY(stabilization_att_sum_err_quat, new_sum_err); INT32_EULERS_OF_QUAT(stabilization_att_sum_err, stabilization_att_sum_err_quat); } else { /* reset accumulator */ INT32_QUAT_ZERO( stabilization_att_sum_err_quat ); INT_EULERS_ZERO( stabilization_att_sum_err ); } /* compute the feed forward command */ attitude_run_ff(stabilization_att_ff_cmd, &stabilization_gains, &stab_att_ref_accel); /* compute the feed back command */ attitude_run_fb(stabilization_att_fb_cmd, &stabilization_gains, &att_err, &rate_err, &stabilization_att_sum_err_quat); /* sum feedforward and feedback */ stabilization_cmd[COMMAND_ROLL] = stabilization_att_fb_cmd[COMMAND_ROLL] + stabilization_att_ff_cmd[COMMAND_ROLL]; stabilization_cmd[COMMAND_PITCH] = stabilization_att_fb_cmd[COMMAND_PITCH] + stabilization_att_ff_cmd[COMMAND_PITCH]; stabilization_cmd[COMMAND_YAW] = stabilization_att_fb_cmd[COMMAND_YAW] + stabilization_att_ff_cmd[COMMAND_YAW]; /* bound the result */ BoundAbs(stabilization_cmd[COMMAND_ROLL], MAX_PPRZ); BoundAbs(stabilization_cmd[COMMAND_PITCH], MAX_PPRZ); BoundAbs(stabilization_cmd[COMMAND_YAW], MAX_PPRZ); }
void stabilization_attitude_run(bool_t enable_integrator) { /* * Update reference */ stabilization_attitude_ref_update(); /* * Compute errors for feedback */ /* attitude error */ struct Int32Quat att_err; INT32_QUAT_INV_COMP(att_err, ahrs.ltp_to_body_quat, stab_att_ref_quat); /* wrap it in the shortest direction */ INT32_QUAT_WRAP_SHORTEST(att_err); INT32_QUAT_NORMALIZE(att_err); /* rate error */ struct Int32Rates rate_err; RATES_DIFF(rate_err, ahrs.body_rate, stab_att_ref_rate); /* integrated error */ if (enable_integrator) { struct Int32Quat new_sum_err, scaled_att_err; /* update accumulator */ scaled_att_err.qi = att_err.qi; scaled_att_err.qx = att_err.qx / IERROR_SCALE; scaled_att_err.qy = att_err.qy / IERROR_SCALE; scaled_att_err.qz = att_err.qz / IERROR_SCALE; INT32_QUAT_COMP_INV(new_sum_err, stabilization_att_sum_err_quat, scaled_att_err); INT32_QUAT_NORMALIZE(new_sum_err); QUAT_COPY(stabilization_att_sum_err_quat, new_sum_err); INT32_EULERS_OF_QUAT(stabilization_att_sum_err, stabilization_att_sum_err_quat); } else { /* reset accumulator */ INT32_QUAT_ZERO( stabilization_att_sum_err_quat ); INT_EULERS_ZERO( stabilization_att_sum_err ); } attitude_run_ff(stabilization_att_ff_cmd, current_stabilization_gains, &stab_att_ref_accel); attitude_run_fb(stabilization_att_fb_cmd, current_stabilization_gains, &att_err, &rate_err, &stabilization_att_sum_err_quat); for (int i = COMMAND_ROLL; i <= COMMAND_YAW; i++) { stabilization_cmd[i] = stabilization_att_fb_cmd[i]+stabilization_att_ff_cmd[i]; Bound(stabilization_cmd[i], -200, 200); } }
float test_INT32_QUAT_OF_RMAT(struct FloatEulers* eul_f, bool_t display) { struct Int32Eulers eul312_i; EULERS_BFP_OF_REAL(eul312_i, (*eul_f)); if (display) DISPLAY_INT32_EULERS("eul312_i", eul312_i); struct FloatRMat rmat_f; FLOAT_RMAT_OF_EULERS_312(rmat_f, (*eul_f)); if (display) DISPLAY_FLOAT_RMAT_AS_EULERS_DEG("rmat float", rmat_f); if (display) DISPLAY_FLOAT_RMAT("rmat float", rmat_f); struct Int32RMat rmat_i; INT32_RMAT_OF_EULERS_312(rmat_i, eul312_i); if (display) DISPLAY_INT32_RMAT_AS_EULERS_DEG("rmat int", rmat_i); if (display) DISPLAY_INT32_RMAT("rmat int", rmat_i); if (display) DISPLAY_INT32_RMAT_AS_FLOAT("rmat int", rmat_i); struct FloatQuat qf; FLOAT_QUAT_OF_RMAT(qf, rmat_f); FLOAT_QUAT_WRAP_SHORTEST(qf); if (display) DISPLAY_FLOAT_QUAT("qf", qf); struct Int32Quat qi; INT32_QUAT_OF_RMAT(qi, rmat_i); INT32_QUAT_WRAP_SHORTEST(qi); if (display) DISPLAY_INT32_QUAT("qi", qi); if (display) DISPLAY_INT32_QUAT_2("qi", qi); struct FloatQuat qif; QUAT_FLOAT_OF_BFP(qif, qi); struct FloatQuat qerr; QUAT_DIFF(qerr, qif, qf); float err_norm = FLOAT_QUAT_NORM(qerr); if (display) printf("err %f\n", err_norm); if (display) printf("\n"); return err_norm; }
void stabilization_attitude_set_from_eulers_i(struct Int32Eulers *sp_euler) { // copy euler setpoint for debugging memcpy(&stab_att_sp_euler, sp_euler, sizeof(struct Int32Eulers)); INT32_QUAT_OF_EULERS(stab_att_sp_quat, *sp_euler); INT32_QUAT_WRAP_SHORTEST(stab_att_sp_quat); }