foc_observer.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. void foc_observer_init(void) {
  8. foc_obser.is_sensorless_enable = false;
  9. foc_obser.is_sensorless_running = false;
  10. foc_obser.enc_angle = INVALID_ANGLE;
  11. foc_obser.enc_est_angle = INVALID_ANGLE;
  12. foc_obser.enc_speed = 0;
  13. foc_obser.sensorless_angle = INVALID_ANGLE;
  14. foc_obser.sensorless_est_angle = INVALID_ANGLE;
  15. foc_obser.sensorless_speed = 0;
  16. foc_obser.enc_err_cnt = 0;
  17. #ifdef CONFIG_SMO_OBSERVER
  18. smo_observer_init(CONFIG_SMO_PLL_BANDWITH, CONFIG_SMO_LFP_WC, CONFIG_SMO_GAIN_K, CONFIG_SMO_SIGMOID_MAX);
  19. foc_obser.is_sensorless_enable = true;
  20. #endif
  21. #ifdef CONFIG_LADRC_OBSERVER
  22. ladrc_observer_init(CONFIG_LADRC_OBSERVER_MIN_Wo, CONFIG_LADRC_OBSERVER_MIN_eVEL, CONFIG_LADRC_OBSERVER_LPF_FREQ);
  23. foc_obser.is_sensorless_enable = true;
  24. #endif
  25. }
  26. #define RPM_2_degree(rpm) ((rpm) * 6.0f * nv_get_motor_params()->poles * FOC_CTRL_US)
  27. float foc_observer_update(float uAlp, float uBeta, float iAlp, float iBeta){
  28. foc_obser.sensorless_est_angle = foc_obser.sensorless_angle + RPM_2_degree(foc_obser.sensorless_speed);
  29. #ifdef CONFIG_SMO_OBSERVER
  30. foc_obser.sensorless_angle = smo_observer_update(uAlp, uBeta, iAlp, iBeta);
  31. foc_obser.sensorless_speed = smo_observer_vel();
  32. #elif defined CONFIG_LADRC_OBSERVER
  33. foc_obser.sensorless_angle = ladrc_observer_update(uAlp, uBeta, iAlp, iBeta);
  34. foc_obser.sensorless_speed = ladrc_observer_vel();
  35. #endif
  36. return foc_obser.sensorless_angle;
  37. }
  38. bool foc_observer_diagnostic(float enc_angle, float enc_vel) {
  39. if (enc_vel <= 50.0f) {
  40. foc_obser.enc_angle = enc_angle;
  41. foc_obser.enc_speed = ABS(enc_vel);
  42. return true;
  43. }
  44. if (!foc_obser.is_sensorless_running) {
  45. float delta_angle_est = RPM_2_degree((foc_obser.enc_speed + ABS(enc_vel))/2.0f);
  46. float delta_angle_enc = enc_angle - foc_obser.enc_angle;
  47. delta_angle_enc = ABS(delta_angle_enc);
  48. if (delta_angle_enc > 180.0f) {
  49. delta_angle_enc = 360.0f - delta_angle_enc;
  50. }
  51. float r = ABS(delta_angle_enc - delta_angle_est)/(delta_angle_est + 1e-20f);
  52. float thro = 2.0f;
  53. if (delta_angle_est < 0.5f) {
  54. thro = 6.0f;
  55. }else if (delta_angle_est < 2.0f) {
  56. thro = 2.0f;
  57. }else if (delta_angle_est < 4.0f) {
  58. thro = 1.0f;
  59. }else if (delta_angle_est < 6.0f) {
  60. thro = 0.7f;
  61. }else if (delta_angle_est < 10.0f) {
  62. thro = 0.5f;
  63. }else {
  64. thro = 0.4f;
  65. }
  66. if (r >= thro) {
  67. if (foc_obser.enc_err_cnt < 65535) {
  68. foc_obser.enc_err_cnt ++;
  69. }
  70. }
  71. }
  72. foc_obser.enc_angle = enc_angle;
  73. foc_obser.enc_speed = ABS(enc_vel);
  74. return !foc_obser.is_sensorless_running;
  75. }
  76. float foc_observer_speed(void) {
  77. return foc_obser.sensorless_speed;
  78. }
  79. bool foc_observer_is_encoder(void) {
  80. return !foc_obser.is_sensorless_running;
  81. }
  82. void foc_observer_use_sensorless(bool use_smo) {
  83. if (foc_obser.is_sensorless_enable) {
  84. foc_obser.is_sensorless_running = use_smo;
  85. }else {
  86. foc_obser.is_sensorless_running = false;
  87. }
  88. }
  89. void foc_observer_enable_sensorless(bool enable) {
  90. foc_obser.is_sensorless_enable = enable;
  91. }
  92. float foc_observer_sensorless_angle(void) {
  93. return foc_obser.sensorless_angle;
  94. }
  95. float foc_observer_sensorless_speed(void) {
  96. return foc_obser.sensorless_speed;
  97. }
  98. u16 foc_observer_enc_errcount(void) {
  99. return foc_obser.enc_err_cnt;
  100. }
  101. float foc_observer_sensorless_working_speed(void) {
  102. #ifdef CONFIG_SMO_OBSERVER
  103. return CONFIG_SMO_MIN_SPEED;
  104. #elif defined CONFIG_LADRC_OBSERVER
  105. return CONFIG_LADRC_OBSERVER_MIN_SPEED;
  106. #else
  107. return 20000.0f;
  108. #endif
  109. }