foc.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include "foc.h"
  2. #include "arm_math.h"
  3. #include "math/fix_math.h"
  4. #include "math/fast_math.h"
  5. #include "foc/core/svpwm.h"
  6. #include "libs/logger.h"
  7. #include "bsp/bsp_driver.h"
  8. #include "foc/mc_config.h"
  9. #include "foc/foc_config.h"
  10. #include "foc/motor/current.h"
  11. void foc_init(foc_t *foc) {
  12. PI_Controller_Reset(&foc->daxis, 0);
  13. PI_Controller_Reset(&foc->qaxis, 0);
  14. foc->daxis.kp = mc_conf()->c.pid[PID_ID_ID].kp;
  15. foc->daxis.ki = mc_conf()->c.pid[PID_ID_ID].ki;
  16. foc->daxis.kd = mc_conf()->c.pid[PID_ID_ID].kd;
  17. foc->daxis.DT = foc->ts;
  18. foc->qaxis.kp = mc_conf()->c.pid[PID_IQ_ID].kp;
  19. foc->qaxis.ki = mc_conf()->c.pid[PID_IQ_ID].ki;
  20. foc->qaxis.kd = mc_conf()->c.pid[PID_IQ_ID].kd;
  21. foc->qaxis.DT = foc->ts;
  22. foc->ramp_curr_dq.d = 0;
  23. foc->ramp_curr_dq.q = 0;
  24. foc->mot_velocity_filterd = 0;
  25. foc->mot_vel_radusPers = 0;
  26. memset(&foc->in, 0, sizeof(foc_in_t));
  27. memset(&foc->out, 0, sizeof(foc_out_t));
  28. }
  29. void foc_abc_2_dq(float a, float b, float c, float *d, float *q) {
  30. float alpha = a;
  31. float beta = ONE_BY_SQRT3 * (b - c);
  32. float cos,sin;
  33. arm_sin_cos(0, &sin, &cos);
  34. *d = alpha * cos + beta * sin;
  35. *q = -alpha * sin + beta * cos;
  36. }
  37. static __INLINE float id_feedforward(foc_t *foc) {
  38. #ifdef CONFIG_CURRENT_LOOP_DECOUPE
  39. return -(mc_conf()->m.lq * foc->out.curr_dq.q * foc->mot_vel_radusPers);
  40. #else
  41. return 0;
  42. #endif
  43. }
  44. static __INLINE float iq_feedforward(foc_t *foc) {
  45. #ifdef CONFIG_CURRENT_LOOP_DECOUPE
  46. return (mc_conf()->m.ld * foc->out.curr_dq.d + mc_conf()->m.flux) * foc->mot_vel_radusPers;
  47. #else
  48. return 0;
  49. #endif
  50. }
  51. void foc_update(foc_t *foc) {
  52. float max_Vdc = foc->in.dc_vol * CONFIG_SVM_MODULATION;
  53. LowPass_Filter(foc->mot_velocity_filterd, foc->in.mot_velocity, 0.01f);
  54. foc->mot_vel_radusPers = foc->mot_velocity_filterd / 30.0f * PI * mc_conf()->m.poles;
  55. arm_sin_cos(foc->in.mot_angle, &foc->sin, &foc->cos);
  56. park(foc, &foc->in.curr_ab, &foc->out.curr_dq);
  57. if (!foc->in.b_openloop) {
  58. float d_step = (foc->in.target_curr_dq.d - foc->ramp_curr_dq.d) / foc->d_ramp_time;
  59. float q_step = (foc->in.target_curr_dq.q - foc->ramp_curr_dq.q) / foc->q_ramp_time;
  60. if (d_step < 0) {
  61. d_step = -d_step;
  62. }
  63. if (q_step < 0) {
  64. q_step = -q_step;
  65. }
  66. /* limiter Vd output for PI controller */
  67. float max_vd = max_Vdc * SQRT3_BY_2;
  68. foc->daxis.max = max_vd;
  69. foc->daxis.min = -max_vd;
  70. step_towards(&foc->ramp_curr_dq.d, foc->in.target_curr_dq.d, d_step);
  71. float err = foc->ramp_curr_dq.d - foc->out.curr_dq.d;
  72. float id_ff = id_feedforward(foc);
  73. foc->in.target_vol_dq.d = PI_Controller_Current(&foc->daxis, err, id_ff);
  74. /* limiter Vq output for PI controller */
  75. float max_vq = sqrtf(SQ(max_vd) - SQ(foc->in.target_vol_dq.d));
  76. foc->qaxis.max = max_vq;
  77. foc->qaxis.min = -max_vq;
  78. step_towards(&foc->ramp_curr_dq.q, foc->in.target_curr_dq.q, q_step);
  79. err = foc->ramp_curr_dq.q - foc->out.curr_dq.q;
  80. float iq_ff = iq_feedforward(foc);
  81. foc->in.target_vol_dq.q = PI_Controller_Current(&foc->qaxis, err, iq_ff);
  82. }else {
  83. float max_vd = max_Vdc * SQRT3_BY_2;
  84. foc->in.target_vol_dq.d = fclamp(foc->in.target_vol_dq.d, -max_vd, max_vd);
  85. float max_vq = sqrtf(SQ(max_vd) - SQ(foc->in.target_vol_dq.d));
  86. foc->in.target_vol_dq.q = fclamp(foc->in.target_vol_dq.q, -max_vq, max_vq);
  87. }
  88. foc->out.vol_dq.d = foc->in.target_vol_dq.d;
  89. foc->out.vol_dq.q = foc->in.target_vol_dq.q;
  90. #ifdef CONFIG_Volvec_Delay_Comp
  91. if (foc->mot_velocity_filterd >= CONFIG_Volvec_Delay_Comp_Start_Vel) {
  92. float vol_dq_angle = foc->in.mot_angle + foc->mot_velocity_filterd / PI * 180.0f * (foc->ts * 0.8f);
  93. rand_angle(vol_dq_angle);
  94. arm_sin_cos(vol_dq_angle, &foc->sin, &foc->cos);
  95. }
  96. #endif
  97. rev_park(foc, &foc->out.vol_dq, &foc->out.vol_albeta);
  98. SVM_Duty_Fix(&foc->out.vol_albeta, foc->in.dc_vol, foc->half_period, &foc->out);
  99. phase_current_point(&foc->out);
  100. pwm_update_duty(foc->out.duty[0], foc->out.duty[1], foc->out.duty[2]);
  101. pwm_update_sample(foc->out.sample1, foc->out.sample2, foc->out.sample_phase);
  102. }