throttle.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #include "foc/foc_config.h"
  2. #include "foc/core/controller.h"
  3. #include "foc/samples.h"
  4. #include "math/fast_math.h"
  5. #include "bsp/bsp_driver.h"
  6. #include "libs/logger.h"
  7. #include "foc/mc_config.h"
  8. #include "foc/motor/throttle.h"
  9. #include "foc/motor/motor.h"
  10. #include "foc/mc_error.h"
  11. static u8 err_mask;
  12. static float _start_v, _end_v;
  13. static bool _auto_detect_sv = true;
  14. static int _auto_detect_sv_cnt = 0;
  15. static float _auto_detect_sv_totle = 0;
  16. static int _detect_release_cnt = 0;
  17. #define CONFIG_SAFE_INV_V 0.1f
  18. static throttle_torque_t _throttle;
  19. void throttle_torque_reset(void) {
  20. _throttle.accl = false;
  21. _throttle.throttle_opening = _throttle.throttle_opening_last = 0.0f;
  22. _throttle.torque_req = _throttle.torque_real = _throttle.torque_acc_ = 0.0f;
  23. _throttle.gear = mc_get_internal_gear();
  24. }
  25. void throttle_init(void) {
  26. _start_v = mc_conf()->c.thro_start_vol;
  27. _end_v = mc_conf()->c.thro_end_vol;
  28. throttle_torque_reset();
  29. _throttle.vel_filted = 0;
  30. }
  31. bool throttle1_is_error(void) {
  32. if (err_mask & (THRO1_5V_ERR_BIT | THRO1_SIG_ERR_BIT)) {
  33. return true;
  34. }
  35. return false;
  36. }
  37. bool throttle2_is_error(void) {
  38. if (err_mask & (THRO2_5V_ERR_BIT | THRO2_SIG_ERR_BIT)) {
  39. return true;
  40. }
  41. return false;
  42. }
  43. u8 throttle_get_errors(void) {
  44. return err_mask;
  45. }
  46. bool throttle_is_all_error(void) {
  47. #if CONFIG_DAUL_THROTTLE==1
  48. return throttle1_is_error() && throttle2_is_error();
  49. #else
  50. return throttle1_is_error();
  51. #endif
  52. }
  53. float throttle_start_vol(void) {
  54. return _start_v;
  55. }
  56. float throttle_end_vol(void) {
  57. return _end_v;
  58. }
  59. float throttle_vol_range(void) {
  60. return (_end_v - _start_v);
  61. }
  62. float throttle_get_signal(void) {
  63. #if CONFIG_DAUL_THROTTLE==1
  64. if (throttle1_is_error() && throttle2_is_error()) {
  65. return 0.0f;
  66. }else if (throttle1_is_error() && !throttle2_is_error()) {
  67. float thr = get_thro2_5v_float() - get_throttle2_float();
  68. return fclamp(thr, _start_v, _end_v);
  69. }else if (!throttle1_is_error() && throttle2_is_error()) {
  70. return get_throttle_float();
  71. }else {
  72. float thr1 = get_throttle_float();
  73. float thr2 = get_thro2_5v_float() - get_throttle2_float();
  74. return (thr1+thr2)/2.0f;
  75. }
  76. #else
  77. return get_throttle_float();
  78. #endif
  79. }
  80. bool throttle_is_released(void) {
  81. #if CONFIG_DAUL_THROTTLE==1
  82. float signal = 0;
  83. if (throttle1_is_error() && throttle2_is_error()) {
  84. return true;
  85. }else if (throttle1_is_error() && !throttle2_is_error()) {
  86. float thr = get_thro2_5v_float() - get_throttle2_float();
  87. signal = fclamp(thr, _start_v, _end_v);
  88. }else if (!throttle1_is_error() && throttle2_is_error()) {
  89. signal = get_throttle_float();
  90. }else {
  91. float thr1 = get_throttle_float();
  92. float thr2 = get_thro2_5v_float() - get_throttle2_float();
  93. signal = (thr1+thr2)/2.0f;
  94. }
  95. return signal <= _start_v;
  96. #else
  97. return get_throttle_float() <= _start_v;
  98. #endif
  99. }
  100. bool throttle_not_released_err(void)
  101. {
  102. return ((err_mask & THRO_NOT_RELEASED) != 0);
  103. }
  104. void throttle_force_detect(void) {
  105. u32 mask = cpu_enter_critical();
  106. throttle_init();
  107. _auto_detect_sv = true;
  108. _auto_detect_sv_cnt = 0;
  109. _auto_detect_sv_totle = 0;
  110. _detect_release_cnt = 0;
  111. err_mask = 0; //clear err mask
  112. cpu_exit_critical(mask);
  113. }
  114. /* 获取转把电压对应的油门开度 */
  115. #define THRO_CURVE_K (-1.5f)
  116. float throttle_vol_to_opening(float thro_val) {
  117. if (thro_val <= throttle_start_vol()) {
  118. return 0;
  119. }
  120. float delta = thro_val - throttle_start_vol();
  121. int ration = (delta * 100.0f) / throttle_vol_range();
  122. float opening = ((float)ration)/100.0f;
  123. float curve = throttle_curve(THRO_CURVE_K, opening);
  124. return curve;
  125. }
  126. /* 获取油门开度 */
  127. float throttle_get_open_ration(void) {
  128. float thro_val = throttle_get_signal();
  129. return throttle_vol_to_opening(thro_val);
  130. }
  131. /* 获取油门开度对应的转把电压 */
  132. float throttle_opening_to_vol(float r) {
  133. if (r == 0) {
  134. return 0;
  135. }else if (r > 1.0f) {
  136. r = 1.0f;
  137. }
  138. return (throttle_start_vol() + r * throttle_vol_range());
  139. }
  140. void throttle_detect(bool ready) {
  141. float thr_5v, thr_sig;
  142. sample_throttle();
  143. thr_5v = get_thro_5v_float();
  144. thr_sig = get_throttle_float();
  145. if (thr_sig <= mc_conf()->c.thro_min_vol || thr_sig >= mc_conf()->c.thro_max_vol) {
  146. err_mask |= THRO1_SIG_ERR_BIT;
  147. }
  148. if (thr_5v <= 4.5f || thr_5v >= 5.5f) {
  149. err_mask |= THRO1_5V_ERR_BIT;
  150. }
  151. #if CONFIG_DAUL_THROTTLE==1
  152. thr_5v = get_thro2_5v_float();
  153. if (thr_5v <= 4.5f || thr_5v >= 5.5f) {
  154. err_mask |= THRO2_5V_ERR_BIT;
  155. }else {
  156. float thr2_sig = get_thro2_5v_float() - get_throttle2_float();
  157. if (thr2_sig <= mc_conf()->c.thro_min_vol || thr2_sig >= mc_conf()->c.thro_max_vol) {
  158. err_mask |= THRO2_SIG_ERR_BIT;
  159. }else {
  160. if (ABS(thr2_sig - thr_sig) > 0.5f) {
  161. err_mask |= THRO2_SIG_ERR_BIT;
  162. err_mask |= THRO1_SIG_ERR_BIT;
  163. }
  164. }
  165. }
  166. #endif
  167. if (!ready && throttle_get_signal() > _start_v) {
  168. if (_detect_release_cnt < 500) {
  169. _detect_release_cnt ++;
  170. }else {
  171. err_mask |= THRO_NOT_RELEASED;
  172. }
  173. }
  174. if (ready) {
  175. _auto_detect_sv = false;
  176. }else if (!throttle_is_all_error() && !throttle_not_released_err() && !ready && _auto_detect_sv) {
  177. float v = throttle_get_signal();
  178. if (v < _start_v) {
  179. _auto_detect_sv_totle += v;
  180. _auto_detect_sv_cnt ++;
  181. if (_auto_detect_sv_cnt == 200) {
  182. _start_v = _auto_detect_sv_totle / (float)_auto_detect_sv_cnt + CONFIG_SAFE_INV_V;
  183. _auto_detect_sv = false;
  184. mc_crit_err_add_s16(FOC_EV_THRO_START_V, (s16)(_start_v * 100.0f));
  185. }
  186. }
  187. }
  188. }
  189. float throttle_get_open_ration_filted(void) {
  190. return _throttle.throttle_opening;
  191. }
  192. #define THRO_RPM_LP_CEOF 0.01f
  193. float throttle_get_torque(mot_contrl_t * ctrl, float vol) {
  194. float throttle_opening = throttle_vol_to_opening(vol);
  195. float vel = mot_contrl_get_speed(ctrl);
  196. _throttle.gear = mc_get_internal_gear();
  197. LowPass_Filter(_throttle.vel_filted, vel, THRO_RPM_LP_CEOF);
  198. if (throttle_opening > _throttle.throttle_opening) {
  199. _throttle.accl = true;
  200. }else if (throttle_opening < _throttle.throttle_opening) {
  201. _throttle.accl = false;
  202. }
  203. _throttle.throttle_opening = throttle_opening;
  204. float max_torque = mc_gear_max_torque((s16)_throttle.vel_filted, _throttle.gear);
  205. return max_torque * throttle_opening;
  206. }
  207. void throttle_set_torque(mot_contrl_t * ctrl, float torque) {
  208. float curr_vel = mot_contrl_get_speed(ctrl);
  209. float ref_torque = torque;
  210. if (_throttle.accl) { //加速需求
  211. float hold_torque = ctrl->autohold_torque;
  212. if (hold_torque < 0) { //下坡驻车,最小给0扭矩
  213. hold_torque = 0;
  214. }
  215. ref_torque = MAX(hold_torque, ref_torque);
  216. if (curr_vel <= CONFIG_ZERO_SPEED_RPM) {//从静止开始加速
  217. if (_throttle.torque_req < hold_torque) {
  218. _throttle.torque_req = hold_torque;
  219. line_ramp_reset(&ctrl->ramp_input_torque, hold_torque);
  220. }
  221. }else {
  222. ctrl->autohold_torque = 0;
  223. }
  224. /* 处理加速ramp时间的变化,需要缓慢变小,变大可以立即处理,
  225. * 加速时间缓慢变小可以防止突然大扭矩加速
  226. */
  227. u16 now_ramp_time = mot_contrl_get_torque_acc_time(ctrl);
  228. u16 next_ramp_time = mc_gear_conf()->accl_time;
  229. if (curr_vel < CONFIG_ZERO_SPEED_RAMP_RMP) {
  230. next_ramp_time = mc_gear_conf()->zero_accl;
  231. }
  232. if (now_ramp_time != next_ramp_time) {
  233. if (next_ramp_time > now_ramp_time) {
  234. mot_contrl_set_torque_acc_time(ctrl, next_ramp_time);
  235. }else {
  236. float f_now = (float)now_ramp_time;
  237. float f_next = (float)next_ramp_time;
  238. step_towards(&f_now, f_next, 0.5f);
  239. mot_contrl_set_torque_acc_time(ctrl ,(u16)f_now);
  240. }
  241. }
  242. _throttle.torque_req = ref_torque;
  243. }else {
  244. /* autohold 启动的情况下,转把在0位置附近小幅抖动 */
  245. if (curr_vel <= CONFIG_ZERO_SPEED_RPM) {
  246. float hold_torque = ctrl->autohold_torque;
  247. ref_torque = MAX(hold_torque, ref_torque);
  248. }
  249. _throttle.torque_req = ref_torque;
  250. }
  251. mot_contrl_set_torque(ctrl, _throttle.torque_req);
  252. }
  253. /* 定速巡航需要判断是否需要加速 */
  254. float get_user_request_torque(void) {
  255. float max_torque = mc_gear_max_torque((s16)_throttle.vel_filted, _throttle.gear);
  256. return max_torque * _throttle.throttle_opening;
  257. }
  258. void throttle_log(void) {
  259. sys_debug("r:%f, last %f, real:%f, req %f\n", _throttle.throttle_opening, _throttle.throttle_opening_last, _throttle.torque_real, _throttle.torque_req);
  260. sys_debug("thro: %f-%f, %f\n", throttle_start_vol(), throttle_end_vol(), mc_gear_max_torque((s16)_throttle.vel_filted, _throttle.gear));
  261. }