foc_observer.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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.fusion_ceof = 1.0f;
  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) * 60.0f * nv_get_motor_params()->poles * FOC_CTRL_US)
  27. #if 1
  28. float foc_observer_update(float uAlp, float uBeta, float iAlp, float iBeta){
  29. float prev_enc_angle = foc_obser.enc_angle;
  30. float prev_enc_speed = foc_obser.enc_speed;
  31. foc_obser.enc_angle = motor_encoder_get_angle();
  32. foc_obser.enc_speed = motor_encoder_get_speed();
  33. if (!foc_obser.is_sensorless_enable) {
  34. return foc_obser.enc_angle;
  35. }
  36. float est_enc_delta = RPM_2_degree(prev_enc_speed);
  37. float real_enc_delta = foc_obser.enc_angle - prev_enc_angle;
  38. if (real_enc_delta < 0) {
  39. real_enc_delta += 360.0f;
  40. }
  41. float est_ration = real_enc_delta/est_enc_delta;
  42. if (est_ration >= 1.5f || est_ration <= 0.5f) {
  43. foc_obser.fusion_ceof -= 0.1f;
  44. if (foc_obser.fusion_ceof < 0.0f) {
  45. foc_obser.fusion_ceof = 0.0f;
  46. }
  47. if (foc_obser.enc_est_angle == INVALID_ANGLE) {
  48. foc_obser.enc_est_angle = prev_enc_angle;
  49. }else {
  50. foc_obser.enc_est_angle += est_enc_delta;
  51. rand_angle(foc_obser.enc_est_angle);
  52. }
  53. }else {
  54. foc_obser.fusion_ceof += 0.1f;
  55. if (foc_obser.fusion_ceof > 1.0f) {
  56. foc_obser.fusion_ceof = 1.0f;
  57. }
  58. foc_obser.enc_est_angle = foc_obser.enc_angle;
  59. }
  60. foc_obser.sensorless_est_angle = foc_obser.sensorless_angle + RPM_2_degree(foc_obser.sensorless_speed);
  61. #ifdef CONFIG_SMO_OBSERVER
  62. foc_obser.sensorless_angle = smo_observer_update(uAlp, uBeta, iAlp, iBeta);
  63. foc_obser.sensorless_speed = smo_observer_vel();
  64. #elif defined CONFIG_LADRC_OBSERVER
  65. foc_obser.sensorless_angle = ladrc_observer_update(uAlp, uBeta, iAlp, iBeta);
  66. foc_obser.sensorless_speed = ladrc_observer_vel();
  67. #endif
  68. if (foc_obser.is_sensorless_running) {
  69. return foc_obser.sensorless_angle;
  70. }
  71. #if 0
  72. return (foc_obser.enc_est_angle * foc_obser.fusion_ceof + foc_obser.smo_angle * (1.0f - foc_obser.fusion_ceof));
  73. #else
  74. return foc_obser.enc_angle;
  75. #endif
  76. }
  77. float foc_observer_speed(void) {
  78. if (foc_obser.is_sensorless_running) {
  79. return foc_obser.sensorless_speed;
  80. }
  81. return foc_obser.enc_speed;
  82. }
  83. #else
  84. float foc_observer_update(float uAlp, float uBeta, float iAlp, float iBeta){
  85. foc_obser.enc_angle = motor_encoder_get_angle();
  86. foc_obser.enc_speed = motor_encoder_get_speed();
  87. return foc_obser.enc_angle;
  88. }
  89. float foc_observer_speed(void) {
  90. return foc_obser.enc_speed;
  91. }
  92. #endif
  93. bool foc_observer_is_encoder(void) {
  94. return !foc_obser.is_sensorless_running;
  95. }
  96. void foc_observer_use_sensorless(bool use_smo) {
  97. if (foc_obser.is_sensorless_enable) {
  98. foc_obser.is_sensorless_running = use_smo;
  99. }else {
  100. foc_obser.is_sensorless_running = false;
  101. }
  102. }
  103. void foc_observer_enable_sensorless(bool enable) {
  104. foc_obser.is_sensorless_enable = enable;
  105. }
  106. float foc_observer_sensorless_angle(void) {
  107. return foc_obser.sensorless_angle;
  108. }
  109. float foc_observer_sensorless_speed(void) {
  110. return foc_obser.sensorless_speed;
  111. }
  112. float foc_observer_sensorless_working_speed(void) {
  113. #ifdef CONFIG_SMO_OBSERVER
  114. return CONFIG_SMO_MIN_SPEED;
  115. #elif defined CONFIG_LADRC_OBSERVER
  116. return CONFIG_LADRC_OBSERVER_MIN_SPEED;
  117. #else
  118. return 20000.0f;
  119. #endif
  120. }