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

https://github.com/AshuLara/lisa · C · 159 lines · 70 code · 28 blank · 61 comment · 2 complexity · 4f2bc5a90912ab4e14cae48c2099f963 MD5 · raw file

  1. /*
  2. *
  3. * Copyright (C) 2008-2011 Joby Energy Inc
  4. *
  5. */
  6. /** \file quat_setpoint.c
  7. * \brief Quaternion setpoint generation
  8. *
  9. */
  10. #include "subsystems/ahrs.h"
  11. #include "stabilization/stabilization_attitude_ref_quat_int.h"
  12. #include "stabilization/quat_setpoint.h"
  13. #include "stabilization.h"
  14. #include "messages.h"
  15. #include "mcu_periph/uart.h"
  16. #include "downlink.h"
  17. #define QUAT_SETPOINT_HOVER_PITCH RadOfDeg(90)
  18. // reset to "hover" setpoint
  19. static void reset_sp_quat(int32_t _psi, int32_t _theta, struct Int32Quat *initial)
  20. {
  21. int32_t pitch_rotation_angle;
  22. struct Int32Quat pitch_axis_quat;
  23. struct Int32Quat pitch_rotated_quat, pitch_rotated_quat2;
  24. struct Int32Vect3 y_axis = { 0, 1, 0 };
  25. struct Int32Eulers rotated_eulers;
  26. // compose rotation about Y axis (pitch axis) from hover
  27. pitch_rotation_angle = ANGLE_BFP_OF_REAL(-QUAT_SETPOINT_HOVER_PITCH);
  28. INT32_QUAT_OF_AXIS_ANGLE(pitch_axis_quat, y_axis, pitch_rotation_angle);
  29. INT32_QUAT_COMP_NORM_SHORTEST(pitch_rotated_quat, *initial, pitch_axis_quat);
  30. INT32_EULERS_OF_QUAT(rotated_eulers, pitch_rotated_quat);
  31. // reset euler angles
  32. rotated_eulers.theta = _theta;
  33. rotated_eulers.phi = _psi;
  34. INT32_QUAT_OF_EULERS(pitch_rotated_quat, rotated_eulers);
  35. // compose rotation about Y axis (pitch axis) to hover
  36. pitch_rotation_angle = ANGLE_BFP_OF_REAL(QUAT_SETPOINT_HOVER_PITCH);
  37. INT32_QUAT_OF_AXIS_ANGLE(pitch_axis_quat, y_axis, pitch_rotation_angle);
  38. INT32_QUAT_COMP_NORM_SHORTEST(pitch_rotated_quat2, pitch_rotated_quat, pitch_axis_quat);
  39. // store result into setpoint
  40. QUAT_COPY(stab_att_sp_quat, pitch_rotated_quat2);
  41. }
  42. static void update_sp_quat_from_eulers(void) {
  43. struct Int32RMat sp_rmat;
  44. #ifdef STICKS_RMAT312
  45. INT32_RMAT_OF_EULERS_312(sp_rmat, stab_att_sp_euler);
  46. #else
  47. INT32_RMAT_OF_EULERS_321(sp_rmat, stab_att_sp_euler);
  48. #endif
  49. INT32_QUAT_OF_RMAT(stab_att_sp_quat, sp_rmat);
  50. INT32_QUAT_WRAP_SHORTEST(stab_att_sp_quat);
  51. }
  52. /*
  53. void stabilization_attitude_read_rc_incremental(bool_t enable_alpha_vane, bool_t enable_beta_vane)
  54. {
  55. pprz_t roll = radio_control.values[RADIO_ROLL];
  56. pprz_t pitch = radio_control.values[RADIO_PITCH];
  57. pprz_t yaw = radio_control.values[RADIO_YAW];
  58. struct Int32Quat prev_sp_quat, q_e2s, temp_quat;
  59. struct Int32RMat R_e2s;
  60. struct Int32Rates sticks_w_bn_e, sticks_w_bn_s;
  61. QUAT_COPY(prev_sp_quat, stab_att_sp_quat);
  62. sticks_w_bn_e.p = APPLY_DEADBAND(roll, STABILIZATION_ATTITUDE_DEADBAND_A) * ROLL_COEF_H;
  63. sticks_w_bn_e.q = APPLY_DEADBAND(pitch, STABILIZATION_ATTITUDE_DEADBAND_E) * PITCH_COEF_RATE;
  64. sticks_w_bn_e.r = APPLY_DEADBAND(yaw, STABILIZATION_ATTITUDE_DEADBAND_R) * YAW_COEF_RATE;
  65. // Don't let the sticks command a theta rotation in vane mode
  66. if (enable_alpha_vane) {
  67. sticks_w_bn_e.q = 0;
  68. }
  69. if (enable_beta_vane) {
  70. sticks_w_bn_e.r = 0;
  71. }
  72. // q_e2s = q_sp (comp) q_b^(-1)
  73. INT_QUAT_INV_COMP_NORM_SHORTEST(q_e2s, ahrs.ltp_to_body_quat, stab_att_sp_quat);
  74. INT_RMAT_OF_QUAT(R_e2s, q_e2s);
  75. INT_RMAT_RATEMULT(sticks_w_bn_s, R_e2s, sticks_w_bn_e);
  76. INT_QUAT_DIFFERENTIAL(temp_quat, sticks_w_bn_s, 1/RC_UPDATE_FREQ);
  77. INT32_QUAT_COMP_NORM_SHORTEST(stab_att_sp_quat, prev_sp_quat, temp_quat);
  78. // update euler setpoints for telemetry
  79. INT32_EULERS_OF_QUAT(stab_att_sp_euler, stab_att_sp_quat);
  80. }
  81. */
  82. void stabilization_attitude_read_rc_absolute(struct Int32Eulers sp, bool_t in_flight) {
  83. #ifdef AIRPLANE_STICKS
  84. pprz_t roll = radio_control.values[RADIO_ROLL];
  85. pprz_t pitch = radio_control.values[RADIO_PITCH];
  86. pprz_t yaw = radio_control.values[RADIO_YAW];
  87. #else // QUAD STICKS
  88. pprz_t roll = radio_control.values[RADIO_YAW];
  89. pprz_t pitch = radio_control.values[RADIO_PITCH];
  90. pprz_t yaw = -radio_control.values[RADIO_ROLL];
  91. #endif
  92. struct Int32Eulers sticks_eulers;
  93. struct Int32Quat sticks_quat, prev_sp_quat;
  94. // heading hold?
  95. if (in_flight) {
  96. // compose setpoint based on previous setpoint + pitch/roll sticks
  97. reset_sp_quat(RATE_BFP_OF_REAL(yaw * YAW_COEF), RATE_BFP_OF_REAL(pitch * PITCH_COEF), &stab_att_sp_quat);
  98. // get commanded yaw rate from sticks
  99. sticks_eulers.phi = RATE_BFP_OF_REAL(APPLY_DEADBAND(roll, STABILIZATION_ATTITUDE_DEADBAND_A) * ROLL_COEF / RC_UPDATE_FREQ);
  100. sticks_eulers.theta = 0;
  101. sticks_eulers.psi = 0;
  102. // convert yaw rate * dt into quaternion
  103. INT32_QUAT_OF_EULERS(sticks_quat, sticks_eulers);
  104. QUAT_COPY(prev_sp_quat, stab_att_sp_quat)
  105. // update setpoint by rotating by incremental yaw command
  106. INT32_QUAT_COMP_NORM_SHORTEST(stab_att_sp_quat, prev_sp_quat, sticks_quat);
  107. } else { /* if not flying, use current body position + pitch/yaw from sticks to compose setpoint */
  108. reset_sp_quat(RATE_BFP_OF_REAL(yaw * YAW_COEF), RATE_BFP_OF_REAL(pitch * PITCH_COEF), &ahrs.ltp_to_body_quat);
  109. }
  110. // update euler setpoints for telemetry
  111. INT32_EULERS_OF_QUAT(stab_att_sp_euler, stab_att_sp_quat);
  112. }
  113. void stabilization_attitude_sp_enter()
  114. {
  115. quat_setpoint_enter_absolute();
  116. }
  117. void quat_setpoint_enter_absolute()
  118. {
  119. // reset setpoint to "hover"
  120. reset_sp_quat(0., 0., &ahrs.ltp_to_body_quat);
  121. }