foc.c 4.0 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.ts = 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.ts = foc->ts;
  22. line_ramp_init(&foc->in.target_id, CONFIG_CURRENT_LOOP_RAMP_COUNT);
  23. line_ramp_set_minstep(&foc->in.target_id, CONFIG_CURRENT_LOOP_RAMP_STEP_MIN);
  24. line_ramp_init(&foc->in.target_iq, CONFIG_CURRENT_LOOP_RAMP_COUNT);
  25. line_ramp_set_minstep(&foc->in.target_iq, CONFIG_CURRENT_LOOP_RAMP_STEP_MIN);
  26. foc->mot_velocity_filterd = 0;
  27. foc->mot_vel_radusPers = 0;
  28. memset(&foc->in, 0, sizeof(foc_in_t));
  29. memset(&foc->out, 0, sizeof(foc_out_t));
  30. }
  31. void foc_abc_2_dq(float a, float b, float c, float *d, float *q) {
  32. float alpha = a;
  33. float beta = ONE_BY_SQRT3 * (b - c);
  34. float cos,sin;
  35. arm_sin_cos(0, &sin, &cos);
  36. *d = alpha * cos + beta * sin;
  37. *q = -alpha * sin + beta * cos;
  38. }
  39. static __INLINE float id_feedforward(foc_t *foc) {
  40. #ifdef CONFIG_CURRENT_LOOP_DECOUPE
  41. return -(mc_conf()->m.lq * foc->out.curr_dq.q * foc->mot_vel_radusPers);
  42. #else
  43. return 0;
  44. #endif
  45. }
  46. static __INLINE float iq_feedforward(foc_t *foc) {
  47. #ifdef CONFIG_CURRENT_LOOP_DECOUPE
  48. return (mc_conf()->m.ld * foc->out.curr_dq.d + mc_conf()->m.flux) * foc->mot_vel_radusPers;
  49. #else
  50. return 0;
  51. #endif
  52. }
  53. void foc_update(foc_t *foc) {
  54. float max_Vdc = foc->in.dc_vol * CONFIG_SVM_MODULATION;
  55. LowPass_Filter(foc->mot_velocity_filterd, foc->in.mot_velocity, 0.01f);
  56. foc->mot_vel_radusPers = foc->mot_velocity_filterd / 30.0f * PI * mc_conf()->m.poles;
  57. arm_sin_cos(foc->in.mot_angle, &foc->sin, &foc->cos);
  58. park(foc, &foc->in.curr_ab, &foc->out.curr_dq);
  59. if (!foc->in.b_openloop) {
  60. /* limiter Vd output for PI controller */
  61. float max_vd = max_Vdc * SQRT3_BY_2;
  62. foc->daxis.max = max_vd;
  63. foc->daxis.min = -max_vd;
  64. float err = line_ramp_step(&foc->in.target_id) - foc->out.curr_dq.d;
  65. float id_ff = id_feedforward(foc);
  66. foc->in.target_vol_dq.d = PI_Controller_Current(&foc->daxis, err, id_ff);
  67. /* limiter Vq output for PI controller */
  68. float max_vq = sqrtsub2_f(max_vd, foc->in.target_vol_dq.d);
  69. foc->qaxis.max = max_vq;
  70. foc->qaxis.min = -max_vq;
  71. err = line_ramp_step(&foc->in.target_iq) - foc->out.curr_dq.q;
  72. float iq_ff = iq_feedforward(foc);
  73. foc->in.target_vol_dq.q = PI_Controller_Current(&foc->qaxis, err, iq_ff);
  74. }else {
  75. float max_vd = max_Vdc * SQRT3_BY_2;
  76. foc->in.target_vol_dq.d = fclamp(foc->in.target_vol_dq.d, -max_vd, max_vd);
  77. float max_vq = sqrtsub2_f(max_vd, foc->in.target_vol_dq.d);
  78. foc->in.target_vol_dq.q = fclamp(foc->in.target_vol_dq.q, -max_vq, max_vq);
  79. }
  80. foc->out.vol_dq.d = foc->in.target_vol_dq.d + foc->in.v_dq_inj.d;
  81. foc->out.vol_dq.q = foc->in.target_vol_dq.q + foc->in.v_dq_inj.q;
  82. if (foc->in.v_dq_inj.d != 0 || foc->in.v_dq_inj.q != 0) {
  83. saturate_vector_2d(&foc->out.vol_dq.d, &foc->out.vol_dq.q, max_Vdc * SQRT3_BY_2);
  84. }
  85. #ifdef CONFIG_Volvec_Delay_Comp
  86. float sin_old = foc->sin;
  87. float cos_old = foc->cos;
  88. if (foc->mot_velocity_filterd >= CONFIG_Volvec_Delay_Comp_Start_Vel) {
  89. float vol_dq_angle = foc->in.mot_angle + foc->mot_vel_radusPers / PI * 180.0f * (foc->ts * 0.8f);
  90. norm_angle_deg(vol_dq_angle);
  91. arm_sin_cos(vol_dq_angle, &foc->sin, &foc->cos);
  92. }
  93. #endif
  94. rev_park(foc, &foc->out.vol_dq, &foc->out.vol_albeta);
  95. SVM_Duty_Fix(&foc->out.vol_albeta, foc->in.dc_vol, foc->half_period, &foc->out);
  96. phase_current_point(&foc->out);
  97. pwm_update_duty(foc->out.duty[0], foc->out.duty[1], foc->out.duty[2]);
  98. pwm_update_sample(foc->out.sample1, foc->out.sample2, foc->out.sample_phase);
  99. #ifdef CONFIG_Volvec_Delay_Comp
  100. foc->sin = sin_old;
  101. foc->cos = cos_old;
  102. #endif
  103. }