foc_observer.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "bsp/bsp_driver.h"
  2. #include "foc/core/foc_observer.h"
  3. #include "foc/core/ladrc_observer.h"
  4. #include "foc/core/smo_observer.h"
  5. #include "foc/motor/motor.h"
  6. static foc_observer_t foc_obser = {
  7. .enc_err_cnt = 0,
  8. };
  9. void foc_observer_init(void) {
  10. foc_obser.is_sensorless_enable = false;
  11. foc_obser.is_sensorless_running = false;
  12. foc_obser.enc_angle = INVALID_ANGLE;
  13. foc_obser.enc_est_angle = INVALID_ANGLE;
  14. foc_obser.enc_speed = 0;
  15. foc_obser.sensorless_angle = INVALID_ANGLE;
  16. foc_obser.sensorless_est_angle = INVALID_ANGLE;
  17. foc_obser.sensorless_speed = 0;
  18. #ifdef CONFIG_SMO_OBSERVER
  19. smo_observer_init(CONFIG_SMO_PLL_BANDWITH, CONFIG_SMO_LFP_WC, CONFIG_SMO_GAIN_K, CONFIG_SMO_SIGMOID_MAX);
  20. foc_obser.is_sensorless_enable = true;
  21. #endif
  22. #ifdef CONFIG_LADRC_OBSERVER
  23. ladrc_observer_init(CONFIG_LADRC_OBSERVER_MIN_Wo, CONFIG_LADRC_OBSERVER_MIN_eVEL, CONFIG_LADRC_OBSERVER_LPF_FREQ);
  24. foc_obser.is_sensorless_enable = true;
  25. #endif
  26. }
  27. #define RPM_2_degree(rpm) ((rpm) * 6.0f * nv_get_motor_params()->poles * FOC_CTRL_US)
  28. float foc_observer_update(float uAlp, float uBeta, float iAlp, float iBeta){
  29. foc_obser.sensorless_est_angle = foc_obser.sensorless_angle + RPM_2_degree(foc_obser.sensorless_speed);
  30. #ifdef CONFIG_SMO_OBSERVER
  31. foc_obser.sensorless_angle = smo_observer_update(uAlp, uBeta, iAlp, iBeta);
  32. foc_obser.sensorless_speed = smo_observer_vel();
  33. #elif defined CONFIG_LADRC_OBSERVER
  34. foc_obser.sensorless_angle = ladrc_observer_update(uAlp, uBeta, iAlp, iBeta);
  35. foc_obser.sensorless_speed = ladrc_observer_vel();
  36. #endif
  37. return foc_obser.sensorless_angle;
  38. }
  39. bool foc_observer_diagnostic(float enc_angle, float enc_vel) {
  40. if (enc_vel <= (foc_observer_sensorless_working_speed() - 100.0f)) {
  41. foc_obser.enc_angle = enc_angle;
  42. foc_obser.enc_speed = ABS(enc_vel);
  43. return true;
  44. }
  45. if (!foc_obser.is_sensorless_running) {
  46. float est_diff = RPM_2_degree(foc_obser.enc_speed);
  47. float enc_angle_est = est_diff + foc_obser.enc_angle;
  48. rand_angle(enc_angle_est);
  49. float real_est_diff = enc_angle - enc_angle_est;
  50. float s, c;
  51. arm_sin_cos_f32(real_est_diff, &s, &c);
  52. real_est_diff = fast_atan2(s, c)/PI*180.0f;
  53. float ration = ABS(real_est_diff)/est_diff;
  54. float ration_thrl = 1.0f;
  55. if (est_diff < 3.0f) {
  56. ration_thrl = 0.5f;
  57. }else if (est_diff < 6.0f) {
  58. ration_thrl = 0.4;
  59. }else {
  60. ration_thrl = 0.3f;
  61. }
  62. if (ration > ration_thrl) {
  63. foc_obser.enc_err_cnt++;
  64. }
  65. foc_obser.real_est_diff = real_est_diff;
  66. foc_obser.real_est_ration = ration;
  67. }
  68. foc_obser.enc_angle = enc_angle;
  69. foc_obser.enc_speed = ABS(enc_vel);
  70. return !foc_obser.is_sensorless_running;
  71. }
  72. float foc_observer_speed(void) {
  73. return foc_obser.sensorless_speed;
  74. }
  75. bool foc_observer_is_encoder(void) {
  76. return !foc_obser.is_sensorless_running;
  77. }
  78. void foc_observer_use_sensorless(bool use_smo) {
  79. if (foc_obser.is_sensorless_enable) {
  80. foc_obser.is_sensorless_running = use_smo;
  81. }else {
  82. foc_obser.is_sensorless_running = false;
  83. }
  84. }
  85. void foc_observer_enable_sensorless(bool enable) {
  86. foc_obser.is_sensorless_enable = enable;
  87. }
  88. float foc_observer_sensorless_angle(void) {
  89. return foc_obser.sensorless_angle;
  90. }
  91. float foc_observer_sensorless_speed(void) {
  92. return foc_obser.sensorless_speed;
  93. }
  94. u16 foc_observer_enc_errcount(void) {
  95. return foc_obser.enc_err_cnt;
  96. }
  97. float foc_observer_sensorless_diff(void) {
  98. return foc_obser.real_est_diff;
  99. }
  100. float foc_observer_sensorless_ration(void) {
  101. return foc_obser.real_est_ration;
  102. }
  103. float foc_observer_sensorless_working_speed(void) {
  104. #ifdef CONFIG_SMO_OBSERVER
  105. return CONFIG_SMO_MIN_SPEED;
  106. #elif defined CONFIG_LADRC_OBSERVER
  107. return CONFIG_LADRC_OBSERVER_MIN_SPEED;
  108. #else
  109. return 20000.0f;
  110. #endif
  111. }