limit.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "foc/limit.h"
  2. #include "foc/core/controller.h"
  3. #include "foc/motor/motor.h"
  4. #include "foc/motor/motor_param.h"
  5. #include "foc/samples.h"
  6. #include "foc/mc_error.h"
  7. #include "libs/logger.h"
  8. static temp_lim_t motor_tl;
  9. static temp_lim_t mosfet_t;
  10. static vol_limt_t vbus;
  11. static bool _inited = false;
  12. static bool _can_recovery = true;
  13. static void limiter_init(void) {
  14. if (_inited) {
  15. return;
  16. }
  17. motor_tl.high = mc_conf()->p_mot[0].enter_pointer;
  18. motor_tl.high_lim = mc_conf()->p_mot[0].limit_value;
  19. motor_tl.mid = mc_conf()->p_mot[1].enter_pointer;
  20. motor_tl.mid_lim = mc_conf()->p_mot[1].limit_value;
  21. motor_tl.start = mc_conf()->p_mot[2].enter_pointer;
  22. motor_tl.start_lim = mc_conf()->p_mot[2].limit_value;
  23. motor_tl.curr_lim = 1.0f;
  24. motor_tl.temp = sample_motor_temp();
  25. sys_debug("mot: %d-%d, %d-%d, %d-%d\n", motor_tl.high, motor_tl.high_lim, motor_tl.mid, motor_tl.mid_lim, motor_tl.start, motor_tl.start_lim);
  26. mosfet_t.high = mc_conf()->p_mos[0].enter_pointer;
  27. mosfet_t.high_lim = mc_conf()->p_mos[0].limit_value;
  28. mosfet_t.mid = mc_conf()->p_mos[1].enter_pointer;
  29. mosfet_t.mid_lim = mc_conf()->p_mos[1].limit_value;
  30. mosfet_t.start = mc_conf()->p_mos[2].enter_pointer;
  31. mosfet_t.start_lim = mc_conf()->p_mos[2].limit_value;
  32. mosfet_t.curr_lim = 1.0f;
  33. mosfet_t.temp = sample_mos_temp();
  34. sys_debug("mos: %d-%d, %d-%d, %d-%d\n", mosfet_t.high, mosfet_t.high_lim, mosfet_t.mid, mosfet_t.mid_lim, mosfet_t.start, mosfet_t.start_lim);
  35. vbus.crit_low = mc_conf()->c.min_dc_vol;
  36. vbus.lower = mc_conf()->p_vol.enter_pointer;
  37. vbus.lower_lim = mc_conf()->p_vol.limit_value;
  38. sys_debug("vbus: %d, %d-%d\n", vbus.crit_low, vbus.lower, vbus.lower_lim);
  39. _inited = true;
  40. }
  41. static bool temp_limit_check(temp_lim_t *limit, s16 temp) {
  42. if (!limit->is_limit) {
  43. if (temp < limit->start) {
  44. limit->lim_ticks = 0;
  45. }else {
  46. if (++limit->lim_ticks >= 1) {
  47. limit->is_limit = true;
  48. limit->lim_ticks = 0;
  49. }
  50. }
  51. }
  52. if (limit->is_limit) {
  53. if (temp < limit->start) {
  54. if (++limit->lim_ticks >= 1) {
  55. limit->is_limit = false;
  56. limit->lim_ticks = 0;
  57. }
  58. }else {
  59. limit->lim_ticks = 0;
  60. }
  61. }
  62. return limit->is_limit;
  63. }
  64. #define TEMP_SENSOR_ERR_CNT 20
  65. float get_temp_limit_value(temp_lim_t *limit, s16 temp, s16 err_temp) {
  66. if ((temp == err_temp) || ABS(temp - limit->temp) >= 20) {
  67. limit->temp = temp;
  68. if (limit->temp_sensor_err < TEMP_SENSOR_ERR_CNT) {
  69. limit->temp_sensor_err++;
  70. return limit->curr_lim;
  71. }else {
  72. return min(limit->curr_lim, 0.5f); //温度传感器异常,返回上次的限流
  73. }
  74. }else {
  75. limit->temp_sensor_err = 0;
  76. }
  77. limit->temp = temp;
  78. if (!temp_limit_check(limit, temp)) {
  79. limit->curr_lim = 1.0f;
  80. }else {
  81. if (temp < limit->start) {
  82. return limit->curr_lim; //keep prev limit value
  83. }else if (temp > limit->high) {
  84. limit->curr_lim = 0;
  85. }else {
  86. if (temp >= limit->start && temp <= limit->mid) {
  87. limit->curr_lim = f_map(temp, limit->start, limit->mid, limit->start_lim, limit->mid_lim)/100.0f;
  88. }else {
  89. limit->curr_lim = f_map(temp, limit->mid, limit->high, limit->mid_lim, limit->high_lim)/100.0f;
  90. }
  91. }
  92. }
  93. return limit->curr_lim;
  94. }
  95. /* this maybe limit power or torque, based on the current power */
  96. float motor_temp_high_limit(void) {
  97. limiter_init();
  98. s16 temp = get_motor_temp_raw();
  99. float value = get_temp_limit_value(&motor_tl, temp, 300);
  100. if (motor_tl.temp_sensor_err == TEMP_SENSOR_ERR_CNT) {
  101. if (mc_set_critical_error(FOC_CRIT_MOT_TEMP_Sensor)) {
  102. mc_crit_err_add(FOC_CRIT_MOT_TEMP_Sensor, temp, motor_tl.temp);
  103. }
  104. }
  105. if (value == 0.0f) {
  106. if (mc_set_critical_error(FOC_CRIT_MOTOR_TEMP_Lim)) {
  107. mc_crit_err_add(FOC_CRIT_MOTOR_TEMP_Lim, temp, (s16)mot_contrl_get_speed(mot_contrl()));
  108. }
  109. }else if (_can_recovery){
  110. mc_clr_critical_error(FOC_CRIT_MOTOR_TEMP_Lim);
  111. }
  112. return value;
  113. }
  114. float motor_temp_high_limit_test(s16 temp) {
  115. limiter_init();
  116. float value = get_temp_limit_value(&motor_tl, temp, 300);
  117. if (motor_tl.temp_sensor_err == TEMP_SENSOR_ERR_CNT) {
  118. if (mc_set_critical_error(FOC_CRIT_MOT_TEMP_Sensor)) {
  119. mc_crit_err_add(FOC_CRIT_MOT_TEMP_Sensor, temp, motor_tl.temp);
  120. }
  121. }
  122. if (value == 0.0f) {
  123. if (mc_set_critical_error(FOC_CRIT_MOTOR_TEMP_Lim)) {
  124. mc_crit_err_add(FOC_CRIT_MOTOR_TEMP_Lim, temp, (s16)mot_contrl_get_speed(mot_contrl()));
  125. }
  126. }else if (_can_recovery){
  127. mc_clr_critical_error(FOC_CRIT_MOTOR_TEMP_Lim);
  128. }
  129. return value;
  130. }
  131. /* limit the max torque(max phase current) */
  132. float mos_temp_high_limit(void) {
  133. limiter_init();
  134. s16 temp = get_mos_temp_raw();
  135. float value = get_temp_limit_value(&mosfet_t, temp, -40);
  136. if (mosfet_t.temp_sensor_err == TEMP_SENSOR_ERR_CNT) {
  137. if (mc_set_critical_error(FOC_CRIT_MOS_TEMP_Sensor)) {
  138. mc_crit_err_add(FOC_CRIT_MOS_TEMP_Sensor, temp, mosfet_t.temp);
  139. }
  140. }
  141. if (value == 0.0f) {
  142. if (mc_set_critical_error(FOC_CRIT_MOS_TEMP_Lim)) {
  143. mc_crit_err_add(FOC_CRIT_MOS_TEMP_Lim, temp, (s16)mot_contrl_get_speed(mot_contrl()));
  144. }
  145. }else if (_can_recovery){
  146. mc_clr_critical_error(FOC_CRIT_MOS_TEMP_Lim);
  147. }
  148. return value;
  149. }
  150. float mos_temp_high_limit_test(s16 temp) {
  151. limiter_init();
  152. float value = get_temp_limit_value(&mosfet_t, temp, -40);
  153. if (mosfet_t.temp_sensor_err == TEMP_SENSOR_ERR_CNT) {
  154. if (mc_set_critical_error(FOC_CRIT_MOS_TEMP_Sensor)) {
  155. mc_crit_err_add(FOC_CRIT_MOS_TEMP_Sensor, temp, mosfet_t.temp);
  156. }
  157. }
  158. if (value == 0.0f) {
  159. if (mc_set_critical_error(FOC_CRIT_MOS_TEMP_Lim)) {
  160. mc_crit_err_add(FOC_CRIT_MOS_TEMP_Lim, temp, (s16)mot_contrl_get_speed(mot_contrl()));
  161. }
  162. }else if (_can_recovery){
  163. mc_clr_critical_error(FOC_CRIT_MOS_TEMP_Lim);
  164. }
  165. return value;
  166. }
  167. /* limit the DC bus current */
  168. u16 vbus_voltage_low_limit(void) {
  169. limiter_init();
  170. s16 vol = (s16)sample_vbus_raw();
  171. if (!vbus.is_limit && (vol <= vbus.lower)) {
  172. vbus.is_limit = true;
  173. if (mc_set_critical_error(FOC_CRIT_UN_Vol_Err)) {
  174. if (mot_contrl_get_speed(mot_contrl()) > CONFIG_ZERO_SPEED_RPM) {
  175. mc_crit_err_add(FOC_CRIT_UN_Vol_Err, vol, (s16)mot_contrl_get_speed(mot_contrl()));
  176. }
  177. }
  178. }else if (vbus.is_limit && (vol > vbus.lower)) {
  179. vbus.is_limit = false;
  180. if (_can_recovery) {
  181. mc_clr_critical_error(FOC_CRIT_UN_Vol_Err);
  182. }
  183. }
  184. if (vol > vbus.lower) {
  185. return HW_LIMIT_NONE;
  186. }else if (vol < vbus.crit_low) {
  187. return 0.0f;
  188. }
  189. return (u16)f_map(vol, vbus.crit_low, vbus.lower, 0.0f, vbus.lower_lim);
  190. }
  191. u16 vbus_voltage_low_limit_test(s16 vol) {
  192. limiter_init();
  193. if (!vbus.is_limit && (vol <= vbus.lower)) {
  194. vbus.is_limit = true;
  195. if (mc_set_critical_error(FOC_CRIT_UN_Vol_Err)) {
  196. if (mot_contrl_get_speed(mot_contrl()) > CONFIG_ZERO_SPEED_RPM) {
  197. mc_crit_err_add(FOC_CRIT_UN_Vol_Err, vol, (s16)mot_contrl_get_speed(mot_contrl()));
  198. }
  199. }
  200. }else if (vbus.is_limit && (vol > vbus.lower)) {
  201. vbus.is_limit = false;
  202. if (_can_recovery) {
  203. mc_clr_critical_error(FOC_CRIT_UN_Vol_Err);
  204. }
  205. }
  206. if (vol > vbus.lower) {
  207. return HW_LIMIT_NONE;
  208. }else if (vol < vbus.crit_low) {
  209. return 0.0f;
  210. }
  211. return (u16)f_map(vol, vbus.crit_low, vbus.lower, 0.0f, vbus.lower_lim);
  212. }
  213. bool motor_temp_limited(void) {
  214. return motor_tl.is_limit;
  215. }
  216. bool mos_temp_limited(void) {
  217. return mosfet_t.is_limit;
  218. }