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

https://bitbucket.org/tamasszabo/paparazzi_mavlink · C · 180 lines · 92 code · 32 blank · 56 comment · 0 complexity · 08e42df2cb585cf4ba816dd9fdaecda3 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_int.c
  23. *
  24. * Rotorcraft attitude reference generation.
  25. * (quaternion int version)
  26. *
  27. */
  28. #include "generated/airframe.h"
  29. #include "firmwares/rotorcraft/stabilization.h"
  30. #include "stabilization_attitude_ref_int.h"
  31. #define REF_ACCEL_MAX_P BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_PDOT, REF_ACCEL_FRAC)
  32. #define REF_ACCEL_MAX_Q BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_QDOT, REF_ACCEL_FRAC)
  33. #define REF_ACCEL_MAX_R BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_RDOT, REF_ACCEL_FRAC)
  34. #define REF_RATE_MAX_P BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_P, REF_RATE_FRAC)
  35. #define REF_RATE_MAX_Q BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_Q, REF_RATE_FRAC)
  36. #define REF_RATE_MAX_R BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_R, REF_RATE_FRAC)
  37. #define OMEGA_P STABILIZATION_ATTITUDE_REF_OMEGA_P
  38. #define ZETA_P STABILIZATION_ATTITUDE_REF_ZETA_P
  39. #define ZETA_OMEGA_P_RES 10
  40. #define ZETA_OMEGA_P BFP_OF_REAL((ZETA_P*OMEGA_P), ZETA_OMEGA_P_RES)
  41. #define OMEGA_2_P_RES 7
  42. #define OMEGA_2_P BFP_OF_REAL((OMEGA_P*OMEGA_P), OMEGA_2_P_RES)
  43. #define OMEGA_Q STABILIZATION_ATTITUDE_REF_OMEGA_Q
  44. #define ZETA_Q STABILIZATION_ATTITUDE_REF_ZETA_Q
  45. #define ZETA_OMEGA_Q_RES 10
  46. #define ZETA_OMEGA_Q BFP_OF_REAL((ZETA_Q*OMEGA_Q), ZETA_OMEGA_Q_RES)
  47. #define OMEGA_2_Q_RES 7
  48. #define OMEGA_2_Q BFP_OF_REAL((OMEGA_Q*OMEGA_Q), OMEGA_2_Q_RES)
  49. #define OMEGA_R STABILIZATION_ATTITUDE_REF_OMEGA_R
  50. #define ZETA_R STABILIZATION_ATTITUDE_REF_ZETA_R
  51. #define ZETA_OMEGA_R_RES 10
  52. #define ZETA_OMEGA_R BFP_OF_REAL((ZETA_R*OMEGA_R), ZETA_OMEGA_R_RES)
  53. #define OMEGA_2_R_RES 7
  54. #define OMEGA_2_R BFP_OF_REAL((OMEGA_R*OMEGA_R), OMEGA_2_R_RES)
  55. struct Int32Eulers stab_att_sp_euler;
  56. struct Int32Quat stab_att_sp_quat;
  57. struct Int32Eulers stab_att_ref_euler;
  58. struct Int32Quat stab_att_ref_quat;
  59. struct Int32Rates stab_att_ref_rate;
  60. struct Int32Rates stab_att_ref_accel;
  61. struct Int32RefModel stab_att_ref_model = {
  62. {STABILIZATION_ATTITUDE_REF_OMEGA_P, STABILIZATION_ATTITUDE_REF_OMEGA_Q, STABILIZATION_ATTITUDE_REF_OMEGA_R},
  63. {STABILIZATION_ATTITUDE_REF_ZETA_P, STABILIZATION_ATTITUDE_REF_ZETA_Q, STABILIZATION_ATTITUDE_REF_ZETA_R}
  64. };
  65. static inline void reset_psi_ref_from_body(void) {
  66. //sp has been set from body using stabilization_attitude_get_yaw_i, use that value
  67. stab_att_ref_euler.psi = stab_att_sp_euler.psi << (REF_ANGLE_FRAC - INT32_ANGLE_FRAC);
  68. stab_att_ref_rate.r = 0;
  69. stab_att_ref_accel.r = 0;
  70. }
  71. void stabilization_attitude_ref_init(void) {
  72. INT_EULERS_ZERO(stab_att_sp_euler);
  73. INT32_QUAT_ZERO(stab_att_sp_quat);
  74. INT_EULERS_ZERO(stab_att_ref_euler);
  75. INT32_QUAT_ZERO(stab_att_ref_quat);
  76. INT_RATES_ZERO(stab_att_ref_rate);
  77. INT_RATES_ZERO(stab_att_ref_accel);
  78. /*
  79. for (int i = 0; i < STABILIZATION_ATTITUDE_GAIN_NB; i++) {
  80. RATES_ASSIGN(stab_att_ref_model[i].omega, omega_p[i], omega_q[i], omega_r[i]);
  81. RATES_ASSIGN(stab_att_ref_model[i].zeta, zeta_p[i], zeta_q[i], zeta_r[i]);
  82. }
  83. */
  84. }
  85. void stabilization_attitude_ref_enter(void)
  86. {
  87. reset_psi_ref_from_body();
  88. /* convert reference attitude with REF_ANGLE_FRAC to eulers with normal INT32_ANGLE_FRAC */
  89. struct Int32Eulers ref_eul;
  90. INT32_EULERS_RSHIFT(ref_eul, stab_att_ref_euler, (REF_ANGLE_FRAC - INT32_ANGLE_FRAC));
  91. INT32_QUAT_OF_EULERS(stab_att_ref_quat, ref_eul);
  92. INT32_QUAT_WRAP_SHORTEST(stab_att_ref_quat);
  93. /* set reference rate and acceleration to zero */
  94. memset(&stab_att_ref_accel, 0, sizeof(struct Int32Rates));
  95. memset(&stab_att_ref_rate, 0, sizeof(struct Int32Rates));
  96. }
  97. /*
  98. * Reference
  99. */
  100. #define DT_UPDATE (1./PERIODIC_FREQUENCY)
  101. // CAUTION! Periodic frequency is assumed to be 512 Hz
  102. // which is equal to >> 9
  103. #define F_UPDATE_RES 9
  104. void stabilization_attitude_ref_update(void) {
  105. /* integrate reference attitude */
  106. struct Int32Quat qdot;
  107. INT32_QUAT_DERIVATIVE(qdot, stab_att_ref_rate, stab_att_ref_quat);
  108. //QUAT_SMUL(qdot, qdot, DT_UPDATE);
  109. qdot.qi = qdot.qi >> F_UPDATE_RES;
  110. qdot.qx = qdot.qx >> F_UPDATE_RES;
  111. qdot.qy = qdot.qy >> F_UPDATE_RES;
  112. qdot.qz = qdot.qz >> F_UPDATE_RES;
  113. QUAT_ADD(stab_att_ref_quat, qdot);
  114. INT32_QUAT_NORMALIZE(stab_att_ref_quat);
  115. /* integrate reference rotational speeds
  116. * delta rate = ref_accel * dt
  117. * ref_rate = old_ref_rate + delta_rate
  118. */
  119. const struct Int32Rates delta_rate = {
  120. stab_att_ref_accel.p >> ( F_UPDATE_RES + REF_ACCEL_FRAC - REF_RATE_FRAC),
  121. stab_att_ref_accel.q >> ( F_UPDATE_RES + REF_ACCEL_FRAC - REF_RATE_FRAC),
  122. stab_att_ref_accel.r >> ( F_UPDATE_RES + REF_ACCEL_FRAC - REF_RATE_FRAC)};
  123. RATES_ADD(stab_att_ref_rate, delta_rate);
  124. /* compute reference angular accelerations */
  125. struct Int32Quat err;
  126. /* compute reference attitude error */
  127. INT32_QUAT_INV_COMP(err, stab_att_sp_quat, stab_att_ref_quat);
  128. /* wrap it in the shortest direction */
  129. INT32_QUAT_WRAP_SHORTEST(err);
  130. /* propagate the 2nd order linear model */
  131. const struct Int32Rates accel_rate = {
  132. ((int32_t)(-2.*ZETA_OMEGA_P) * (stab_att_ref_rate.p >> (REF_RATE_FRAC - REF_ACCEL_FRAC))) >> (ZETA_OMEGA_P_RES),
  133. ((int32_t)(-2.*ZETA_OMEGA_Q) * (stab_att_ref_rate.q >> (REF_RATE_FRAC - REF_ACCEL_FRAC))) >> (ZETA_OMEGA_Q_RES),
  134. ((int32_t)(-2.*ZETA_OMEGA_R) * (stab_att_ref_rate.r >> (REF_RATE_FRAC - REF_ACCEL_FRAC))) >> (ZETA_OMEGA_R_RES) };
  135. const struct Int32Rates accel_angle = {
  136. ((int32_t)(-OMEGA_2_P)* (err.qx >> (REF_ANGLE_FRAC - REF_ACCEL_FRAC))) >> (OMEGA_2_P_RES),
  137. ((int32_t)(-OMEGA_2_Q)* (err.qy >> (REF_ANGLE_FRAC - REF_ACCEL_FRAC))) >> (OMEGA_2_Q_RES),
  138. ((int32_t)(-OMEGA_2_R)* (err.qz >> (REF_ANGLE_FRAC - REF_ACCEL_FRAC))) >> (OMEGA_2_R_RES) };
  139. RATES_SUM(stab_att_ref_accel, accel_rate, accel_angle);
  140. /* saturate acceleration */
  141. //const struct Int32Rates MIN_ACCEL = { -REF_ACCEL_MAX_P, -REF_ACCEL_MAX_Q, -REF_ACCEL_MAX_R };
  142. //const struct Int32Rates MAX_ACCEL = { REF_ACCEL_MAX_P, REF_ACCEL_MAX_Q, REF_ACCEL_MAX_R };
  143. //RATES_BOUND_BOX(stab_att_ref_accel, MIN_ACCEL, MAX_ACCEL);
  144. /* compute ref_euler for debugging and telemetry */
  145. struct Int32Eulers ref_eul;
  146. INT32_EULERS_OF_QUAT(ref_eul, stab_att_ref_quat);
  147. INT32_EULERS_LSHIFT(stab_att_ref_euler, ref_eul, (REF_ANGLE_FRAC - INT32_ANGLE_FRAC));
  148. }