control_rate.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "control_throttle.h"
  2. #include "flight_mode.h"
  3. #include "helpler_funtions.h"
  4. #include "lowpass_filter.h"
  5. #include "my_math.h"
  6. #include "params.h"
  7. #include "soft_gs.h"
  8. #include "soft_motor_output.h"
  9. #include "soft_rc_input.h"
  10. #include "soft_time.h"
  11. #include "soft_imu.h"
  12. #include <control_rate.h>
  13. #include <math.h>
  14. // malloc测试,定义结构体指针的话必须要malloc申请空间,
  15. // 否则只会分配4字节的指针空间,不会自动分配结构体内存空间,导致无法计算以及赋值
  16. // 所以决定定义变量时都定义为变量,不定义指针,
  17. struct pid_method_rpy pid_m_roll;
  18. struct pid_method_rpy pid_m_pitch;
  19. struct pid_method_rpy pid_m_yaw;
  20. struct pid_method_ap pid_m_alt;
  21. struct pid_method_ap pid_m_posx;
  22. struct pid_method_ap pid_m_posy;
  23. struct pid_value_rpy pid_v_roll;
  24. struct pid_value_rpy pid_v_pitch;
  25. struct pid_value_rpy pid_v_yaw;
  26. struct pid_value_ap pid_v_alt;
  27. struct pid_value_ap pid_v_pos;
  28. // 陀螺积分的虚拟机头方向
  29. float attitude_head = 0.0f;
  30. /*
  31. 内环的速率控制函数
  32. */
  33. float rate_pid_ctl_rp(struct pid_method_rpy *method, struct pid_value_rpy *value, float dt)
  34. {
  35. // 计算目标角速度与当前角度的差
  36. method->gyro_e = method->gyro_t - method->gyro_c;
  37. if (method->gyro_filter_ready != true)
  38. {
  39. method->gyro_filter_ready = true;
  40. butter2_filter_init(&method->gyro_dirv_filter, 400, 25);
  41. // butter2_filter_init(&method->gyro_dirv_filter, 400, 20);
  42. method->gyro_d_item = 0.f;
  43. }
  44. else
  45. {
  46. float dirv = 0.f;
  47. if (dt > 0.f)
  48. {
  49. dirv = value->gyro_d * (method->gyro_e - method->gyro_e_last) / dt;
  50. dirv = constrain_float(dirv, -120, 120);
  51. method->gyro_e_last = method->gyro_e;
  52. }
  53. method->gyro_d_item = butter2_filter_apply(&method->gyro_dirv_filter, dirv);
  54. }
  55. if (ground_air_status == ON_GROUND)
  56. {
  57. method->gyro_d_item = 0.f;
  58. butter2_filter_reset(&method->gyro_dirv_filter, 0);
  59. }
  60. // 计算角速度的P值
  61. method->gyro_p_item = constrain_float(method->gyro_e, -250, 250) * value->gyro_p;
  62. method->gyro_i_item += method->gyro_e * dt * value->gyro_i * 10.0f;
  63. // 角速度的I值得限幅
  64. method->gyro_i_item = constrain_float(method->gyro_i_item, -value->gyro_imax, value->gyro_imax);
  65. method->pid_out = method->gyro_p_item + method->gyro_i_item + method->gyro_d_item;
  66. if ((control_mode == CONTROL_REMOTE) &&
  67. (rc_signal_health == RC_SIGNAL_HEALTH) && (rc_in[RC_CH1] < 1050) &&
  68. (rc_in[RC_CH4] > 1950) && (rc_in[RC_CH3] < 1050) &&
  69. (rc_in[RC_CH2] > 1950))
  70. method->pid_out = 0.0f;
  71. return method->pid_out;
  72. }
  73. /*
  74. 内环的速率控制函数
  75. */
  76. float rate_pid_ctl_yaw(struct pid_method_rpy *method,
  77. struct pid_value_rpy *value, float dt)
  78. {
  79. // 如果电机输出有饱和,则目标航向角速度指数递减
  80. if (MotorOutput_GetYawRestrictionStatus())
  81. {
  82. pid_m_yaw.gyro_t = 0.5f * pid_m_yaw.gyro_c;
  83. }
  84. // 计算目标角速度与当前角度的差
  85. method->gyro_e = method->gyro_t - method->gyro_c;
  86. if (method->gyro_filter_ready != true)
  87. {
  88. method->gyro_filter_ready = true;
  89. butter2_filter_init(&method->gyro_dirv_filter, 400, 30);
  90. method->gyro_d_item = 0.f;
  91. }
  92. else
  93. {
  94. float dirv = 0.f;
  95. if (dt > 0.f)
  96. {
  97. dirv = value->gyro_d * (method->gyro_e - method->gyro_e_last) / dt;
  98. dirv = constrain_float(dirv, -100, 100);
  99. method->gyro_e_last = method->gyro_e;
  100. }
  101. method->gyro_d_item = butter2_filter_apply(&method->gyro_dirv_filter, dirv);
  102. }
  103. if (ground_air_status == ON_GROUND)
  104. {
  105. method->gyro_d_item = 0.f;
  106. butter2_filter_reset(&method->gyro_dirv_filter, 0);
  107. }
  108. // 角速度差限幅
  109. method->gyro_e = constrain_float(method->gyro_e, -200.0f, 200.0f);
  110. // 计算角速度的P值
  111. method->gyro_p_item = method->gyro_e * value->gyro_p;
  112. // 计算角速度的I值
  113. method->gyro_i_item += method->gyro_e * dt * value->gyro_i * 10.0f;
  114. // 角速度的I值得限幅
  115. if (MotorOutput_GetYawRestrictionStatus())
  116. {
  117. method->gyro_i_item = constrain_float( method->gyro_i_item, -2.0f * value->gyro_imax, 2.0f * value->gyro_imax);
  118. }
  119. else
  120. {
  121. method->gyro_i_item = constrain_float(method->gyro_i_item, -value->gyro_imax, value->gyro_imax);
  122. }
  123. method->pid_out =
  124. method->gyro_p_item + method->gyro_i_item + method->gyro_d_item;
  125. method->pid_out = constrain_float(method->pid_out, -300.0f, +300.0f);
  126. if ((control_mode == CONTROL_REMOTE) &&
  127. (rc_signal_health == RC_SIGNAL_HEALTH) && (rc_in[RC_CH1] < 1050) &&
  128. (rc_in[RC_CH4] > 1950) && (rc_in[RC_CH3] < 1050) &&
  129. (rc_in[RC_CH2] > 1950))
  130. method->pid_out = 0.0f;
  131. return method->pid_out;
  132. }
  133. extern float thr_max; // 前面上升阶段为了减小电流 限制油门最大为 1400
  134. /*
  135. 内环获取油门量
  136. */
  137. float rate_pid_ctl_thr(void)
  138. {
  139. float throttle_ctrl_value = 1000.0f;
  140. /* 根据油门控制状态标志,选择油门输出是 灭车、控制量、怠速 */
  141. switch (throttle_pidctrl_status)
  142. {
  143. case THROTTLE_INAIR_RUNNING:
  144. if ((rc_in[RC_CH8] < 1500) && (comp_rc_status == COMP_NORMAL) &&
  145. (rc_signal_health == RC_SIGNAL_HEALTH) &&
  146. (control_mode == CONTROL_REMOTE))
  147. {
  148. throttle_ctrl_value = rc_in[RC_CH3];
  149. throttle_ctrl_value = constrain_float(throttle_ctrl_value, 1000.0f, 2000.0f);
  150. base_thr = throttle_ctrl_value;
  151. pid_m_alt.acc_i_item = 0;
  152. }
  153. else
  154. {
  155. if (base_thr < HOVER_THR) // 电机怠速是默认等级2 怠速油门10 基础油门宏默认是应该给到1300 如果后续需要响应高度需要变换
  156. base_thr += 1.0f;
  157. throttle_ctrl_value = base_thr + pid_m_alt.pid_out;
  158. throttle_ctrl_value = constrain_float(throttle_ctrl_value, 1000.0f, thr_max);
  159. }
  160. break;
  161. case THROTTLE_ONGROUND_IDLE:
  162. if ((rc_in[RC_CH8] < 1500) && (comp_rc_status == COMP_NORMAL) &&
  163. (rc_signal_health == RC_SIGNAL_HEALTH) &&
  164. (control_mode == CONTROL_REMOTE))
  165. {
  166. throttle_ctrl_value = rc_in[RC_CH3];
  167. base_thr = throttle_ctrl_value;
  168. pid_m_alt.acc_i_item = 0;
  169. }
  170. else
  171. {
  172. throttle_ctrl_value = conf_par.idle_speed + 25.0f;
  173. }
  174. break;
  175. case THROTTLE_OFF:
  176. default:
  177. break;
  178. }
  179. return throttle_ctrl_value;
  180. }
  181. /*
  182. 清零积分项
  183. */
  184. void clear_rate_i_item(struct pid_method_rpy *method)
  185. {
  186. method->gyro_i_item = 0.0f;
  187. }
  188. void init_attitude_head(void)
  189. {
  190. attitude_head = pid_m_yaw.angle_c;
  191. pid_m_yaw.angle_t = pid_m_yaw.angle_c;
  192. }