/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.c

https://bitbucket.org/tamasszabo/paparazzi_mavlink · C · 151 lines · 86 code · 24 blank · 41 comment · 1 complexity · a097f21dfe5475bcf4c9fe69add7c3e8 MD5 · raw file

  1. /*
  2. * Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
  3. *
  4. * This file is part of paparazzi.
  5. *
  6. * paparazzi is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2, or (at your option)
  9. * any later version.
  10. *
  11. * paparazzi is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with paparazzi; see the file COPYING. If not, write to
  18. * the Free Software Foundation, 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. /**
  22. * @file firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.c
  23. *
  24. * Rotorcraft attitude reference generation.
  25. * (quaternion float version)
  26. *
  27. */
  28. #include "generated/airframe.h"
  29. #include "firmwares/rotorcraft/stabilization.h"
  30. #include "state.h"
  31. #include "stabilization_attitude_ref_float.h"
  32. #define REF_ACCEL_MAX_P STABILIZATION_ATTITUDE_REF_MAX_PDOT
  33. #define REF_ACCEL_MAX_Q STABILIZATION_ATTITUDE_REF_MAX_QDOT
  34. #define REF_ACCEL_MAX_R STABILIZATION_ATTITUDE_REF_MAX_RDOT
  35. struct FloatEulers stab_att_sp_euler;
  36. struct FloatQuat stab_att_sp_quat;
  37. struct FloatEulers stab_att_ref_euler;
  38. struct FloatQuat stab_att_ref_quat;
  39. struct FloatRates stab_att_ref_rate;
  40. struct FloatRates stab_att_ref_accel;
  41. struct FloatRefModel stab_att_ref_model[STABILIZATION_ATTITUDE_GAIN_NB];
  42. static int ref_idx = STABILIZATION_ATTITUDE_GAIN_IDX_DEFAULT;
  43. static const float omega_p[] = STABILIZATION_ATTITUDE_REF_OMEGA_P;
  44. static const float zeta_p[] = STABILIZATION_ATTITUDE_REF_ZETA_P;
  45. static const float omega_q[] = STABILIZATION_ATTITUDE_REF_OMEGA_Q;
  46. static const float zeta_q[] = STABILIZATION_ATTITUDE_REF_ZETA_Q;
  47. static const float omega_r[] = STABILIZATION_ATTITUDE_REF_OMEGA_R;
  48. static const float zeta_r[] = STABILIZATION_ATTITUDE_REF_ZETA_R;
  49. static inline void reset_psi_ref_from_body(void) {
  50. //sp has been set from body using stabilization_attitude_get_yaw_f, use that value
  51. stab_att_ref_euler.psi = stab_att_sp_euler.psi;
  52. stab_att_ref_rate.r = 0;
  53. stab_att_ref_accel.r = 0;
  54. }
  55. static inline void update_ref_quat_from_eulers(void) {
  56. struct FloatRMat ref_rmat;
  57. FLOAT_RMAT_OF_EULERS(ref_rmat, stab_att_ref_euler);
  58. FLOAT_QUAT_OF_RMAT(stab_att_ref_quat, ref_rmat);
  59. FLOAT_QUAT_WRAP_SHORTEST(stab_att_ref_quat);
  60. }
  61. void stabilization_attitude_ref_init(void) {
  62. FLOAT_EULERS_ZERO(stab_att_sp_euler);
  63. FLOAT_QUAT_ZERO( stab_att_sp_quat);
  64. FLOAT_EULERS_ZERO(stab_att_ref_euler);
  65. FLOAT_QUAT_ZERO( stab_att_ref_quat);
  66. FLOAT_RATES_ZERO( stab_att_ref_rate);
  67. FLOAT_RATES_ZERO( stab_att_ref_accel);
  68. for (int i = 0; i < STABILIZATION_ATTITUDE_GAIN_NB; i++) {
  69. RATES_ASSIGN(stab_att_ref_model[i].omega, omega_p[i], omega_q[i], omega_r[i]);
  70. RATES_ASSIGN(stab_att_ref_model[i].zeta, zeta_p[i], zeta_q[i], zeta_r[i]);
  71. }
  72. }
  73. void stabilization_attitude_ref_schedule(uint8_t idx) {
  74. ref_idx = idx;
  75. }
  76. void stabilization_attitude_ref_enter(void) {
  77. reset_psi_ref_from_body();
  78. update_ref_quat_from_eulers();
  79. }
  80. /*
  81. * Reference
  82. */
  83. #define DT_UPDATE (1./PERIODIC_FREQUENCY)
  84. // default to fast but less precise quaternion integration
  85. #ifndef STABILIZATION_ATTITUDE_REF_QUAT_INFINITESIMAL_STEP
  86. #define STABILIZATION_ATTITUDE_REF_QUAT_INFINITESIMAL_STEP TRUE
  87. #endif
  88. void stabilization_attitude_ref_update(void) {
  89. /* integrate reference attitude */
  90. #if STABILIZATION_ATTITUDE_REF_QUAT_INFINITESIMAL_STEP
  91. struct FloatQuat qdot;
  92. FLOAT_QUAT_DERIVATIVE(qdot, stab_att_ref_rate, stab_att_ref_quat);
  93. QUAT_SMUL(qdot, qdot, DT_UPDATE);
  94. QUAT_ADD(stab_att_ref_quat, qdot);
  95. #else // use finite step (involves trig)
  96. struct FloatQuat delta_q;
  97. FLOAT_QUAT_DIFFERENTIAL(delta_q, stab_att_ref_rate, DT_UPDATE);
  98. /* compose new ref_quat by quaternion multiplication of delta rotation and current ref_quat */
  99. struct FloatQuat new_ref_quat;
  100. FLOAT_QUAT_COMP(new_ref_quat, delta_q, stab_att_ref_quat);
  101. QUAT_COPY(stab_att_ref_quat, new_ref_quat);
  102. #endif
  103. FLOAT_QUAT_NORMALIZE(stab_att_ref_quat);
  104. /* integrate reference rotational speeds */
  105. struct FloatRates delta_rate;
  106. RATES_SMUL(delta_rate, stab_att_ref_accel, DT_UPDATE);
  107. RATES_ADD(stab_att_ref_rate, delta_rate);
  108. /* compute reference angular accelerations */
  109. struct FloatQuat err;
  110. /* compute reference attitude error */
  111. FLOAT_QUAT_INV_COMP(err, stab_att_sp_quat, stab_att_ref_quat);
  112. /* wrap it in the shortest direction */
  113. FLOAT_QUAT_WRAP_SHORTEST(err);
  114. /* propagate the 2nd order linear model */
  115. stab_att_ref_accel.p = -2.*stab_att_ref_model[ref_idx].zeta.p*stab_att_ref_model[ref_idx].omega.p*stab_att_ref_rate.p
  116. - stab_att_ref_model[ref_idx].omega.p*stab_att_ref_model[ref_idx].omega.p*err.qx;
  117. stab_att_ref_accel.q = -2.*stab_att_ref_model[ref_idx].zeta.q*stab_att_ref_model[ref_idx].omega.q*stab_att_ref_rate.q
  118. - stab_att_ref_model[ref_idx].omega.q*stab_att_ref_model[ref_idx].omega.q*err.qy;
  119. stab_att_ref_accel.r = -2.*stab_att_ref_model[ref_idx].zeta.r*stab_att_ref_model[ref_idx].omega.r*stab_att_ref_rate.r
  120. - stab_att_ref_model[ref_idx].omega.r*stab_att_ref_model[ref_idx].omega.r*err.qz;
  121. /* saturate acceleration */
  122. const struct FloatRates MIN_ACCEL = { -REF_ACCEL_MAX_P, -REF_ACCEL_MAX_Q, -REF_ACCEL_MAX_R };
  123. const struct FloatRates MAX_ACCEL = { REF_ACCEL_MAX_P, REF_ACCEL_MAX_Q, REF_ACCEL_MAX_R };
  124. RATES_BOUND_BOX(stab_att_ref_accel, MIN_ACCEL, MAX_ACCEL);
  125. /* compute ref_euler */
  126. FLOAT_EULERS_OF_QUAT(stab_att_ref_euler, stab_att_ref_quat);
  127. }