ladrc_observer.c 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "ladrc_observer.h"
  2. #include "app/nv_storage.h"
  3. #include "math/fast_math.h"
  4. static ladrc_observer observer;
  5. #define angle_clamp(a) {while (a >= M_PI*2) a-=M_PI*2;while (a < 0) a +=M_PI*2;};
  6. static __inline float ladrc_observer_band(float vel) {
  7. float ration = vel / observer.vel_min;
  8. float Wo = observer.Wo;
  9. if (ration > 1) {
  10. Wo = ration * Wo;
  11. }
  12. observer.B1 = 2 * Wo;
  13. observer.B2 = SQ(Wo);
  14. return Wo;
  15. }
  16. void ladrc_observer_init(float Wo, float vel_min, float lpf_cut_off) {
  17. observer.Wo = Wo;
  18. observer.vel_min = vel_min;
  19. observer.ts = FOC_CTRL_US;
  20. observer.lpf_cutoff_freq = lpf_cut_off * 2 * M_PI;
  21. observer.ld = nv_get_motor_params()->ld;
  22. observer.lq = nv_get_motor_params()->lq;
  23. observer.r = nv_get_motor_params()->r;
  24. observer.poles = nv_get_motor_params()->poles;
  25. ladrc_observer_band(0);
  26. }
  27. void ladrc_observer_update(float va, float vb, float ia, float ib) {
  28. float induct = observer.Vel_El * (observer.ld - observer.lq) / observer.ld;
  29. /* update Wc for current est vel */
  30. float Wo = ladrc_observer_band(observer.Vel_El);
  31. /* est alpha emf */
  32. float F0 = -observer.r/observer.ld * ia;
  33. float e = observer.alpha.z1 - ia;
  34. observer.alpha.z2 += (-e * observer.B2);
  35. observer.alpha.z1 += (observer.alpha.z2 + F0 + va/observer.ld + e * observer.B1 * observer.Vel_El - induct * observer.beta.z1);
  36. observer.Ealpha = observer.alpha.z2 * (-observer.ld);
  37. /* est beta emf */
  38. F0 = -observer.r/observer.ld * ib;
  39. e = observer.beta.z1 - ib;
  40. observer.beta.z2 += (-e * observer.B2);
  41. observer.beta.z1 += (observer.beta.z2 + F0 + va/observer.ld - e * observer.B1 * observer.Vel_El + induct * observer.alpha.z1);
  42. observer.Ebeta = observer.beta.z2 * (-observer.ld);
  43. float angle = fast_atan_2(-observer.Ealpha, observer.Ebeta);
  44. /* 补偿ladrc相位延时, 同时电流和电压滞后一个控制周期,需要通过当前的电角速度对计算的角度进行补偿 */
  45. float angle_comp = fast_atan_2(observer.Vel_El * Wo, SQ(Wo) - SQ(observer.Vel_El)) + observer.Vel_El * observer.ts;
  46. angle += angle_comp;
  47. angle_clamp(angle);
  48. float delta_angle = angle - observer.angle_last;
  49. float delta_angle_abs = ABS(delta_angle);
  50. if (delta_angle_abs >= M_PI) {
  51. delta_angle = 2 * M_PI - delta_angle_abs;
  52. }
  53. observer.angle_sum += angle;
  54. observer.angle_sum -= observer.angle_array[observer.angle_idx];
  55. observer.angle_array[observer.angle_idx++] = delta_angle;
  56. if (observer.angle_idx == ANGLE_BUF_NUM) {
  57. observer.angle_idx = 0;
  58. }
  59. float vel = observer.angle_sum / (ANGLE_BUF_NUM * observer.ts);
  60. LowPass_Filter(observer.Vel_El, vel, (observer.lpf_cutoff_freq * observer.ts));
  61. observer.angle_last = angle;
  62. }
  63. float ladrc_observer_angle(void) {
  64. return observer.angle_last;
  65. }
  66. float ladrc_observer_vel(void) {
  67. return (observer.Vel_El * (30.0f / M_PI) / observer.poles);
  68. }