| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #include "app/nv_storage.h"
- #include "math/fast_math.h"
- #include "PMSM_FOC_Core.h"
- #include "smo_observer.h"
- static smo_observer_t smo;
- static void smo_observer(float uAlpha, float uBeta, float iAlpha, float iBeta);
- static void smo_pll(void);
- void smo_observer_init(float pll_bandwith, float lpf_wc, float Ksmo, float Ksta) {
- smo.ts = 1.0f/(float)FOC_PWM_FS;
- smo.bandwith = pll_bandwith;
- smo.pll_kp = pll_bandwith * 2 * M_PI * 2;
- smo.pll_ki = 0.25f * SQ(smo.pll_kp);
- smo.pll_max_rad_pers = CONFIG_MAX_MOT_RPM/30.0f * M_PI;
- smo.lpf_wc = lpf_wc;
- smo.lpf_ceof = (lpf_wc*2*M_PI/(float)FOC_PWM_FS);
- smo.Ksmo = Ksmo;
- smo.Ksta = Ksta;
- smo.motor_r = nv_get_motor_params()->r;
- smo.motor_ld = nv_get_motor_params()->ld;
- smo.motor_lq = nv_get_motor_params()->lq;
- smo.motor_poles = nv_get_motor_params()->poles;
- smo.ldq_diff_dm = (smo.motor_ld-smo.motor_lq)/smo.motor_lq*smo.motor_ld;
- smo.ld_inv = 1.0f / smo.motor_ld;
- }
- float smo_observer_update(float uAlpha, float uBeta, float iAlpha, float iBeta) {
- smo_observer(uAlpha, uBeta, iAlpha, iBeta);
- smo_pll();
- return pi_2_degree(smo.est_angle_out);
- }
- smo_observer_t *get_smo(void) {
- return &smo;
- }
- static void smo_observer(float uAlpha, float uBeta, float iAlpha, float iBeta) {
- float est_ab = smo.ldq_diff_dm * smo.est_rad_pers;//(smo.motor_ld-smo.motor_lq)/smo.motor_lq * smo.est_rad_pers;
- /* est alpha back emf */
- float calc_alpha = (uAlpha - smo.Ialpha_hat*smo.motor_r - smo.est_eAlpha - est_ab * smo.IBeta_hat) * smo.ld_inv;
- smo.Ialpha_hat += calc_alpha * smo.ts; //积分
- float err_iAlpha = smo.Ialpha_hat - iAlpha;
-
- smo.est_eAlpha = fclamp(err_iAlpha, -smo.Ksta, smo.Ksta) * smo.Ksmo;
- smo.est_eAlpha_Filted = do_lpf(smo.est_eAlpha_Filted, smo.est_eAlpha, smo.lpf_ceof);
- /* est beta back emf */
- float calc_beta = (uBeta - smo.IBeta_hat*smo.motor_r - smo.est_eBeta + est_ab * smo.Ialpha_hat) * smo.ld_inv;
- smo.IBeta_hat += calc_beta * smo.ts; //积分
-
- float err_iBeta = smo.IBeta_hat - iBeta;
-
- smo.est_eBeta = fclamp(err_iBeta, -smo.Ksta, smo.Ksta) * smo.Ksmo;
- smo.est_eBeta_Filted = do_lpf(smo.est_eBeta_Filted, smo.est_eBeta, smo.lpf_ceof);
- }
- #define angle_clamp(a) {while (a >= M_PI*2) a-=M_PI*2;while (a < 0) a +=M_PI*2;};
- #define ANGLE_COMP_RPM_CEOF (2.44E-4F)
- static void smo_pll(void) {
- float eab_sqr = sqrtf(SQ(smo.est_eAlpha_Filted) + SQ(smo.est_eBeta_Filted) + (1e-10f));
- float ealpha_in = -smo.est_eAlpha_Filted/eab_sqr;
- float ebeta_in = smo.est_eBeta_Filted/eab_sqr;
- float sin, cos;
- float angle_rad = pi_2_degree(smo.est_angle);
-
- arm_sin_cos_f32(angle_rad, &sin, &cos);
- float pi_err = cos * ealpha_in - sin * ebeta_in;
- float perr = pi_err * smo.pll_kp;
- smo.est_rad_pers = perr + smo.pll_integrator; //计算角速度
- if (smo.pll_integrator < smo.pll_max_rad_pers) {
- smo.pll_integrator += smo.ts * pi_err * smo.pll_ki; //更新pll的pi的积分xiang
- }
- smo.est_rad_pers_filted = do_lpf(smo.est_rad_pers_filted, smo.est_rad_pers, smo.lpf_ceof); //对速度低通滤波
- smo.est_angle += smo.ts * smo.est_rad_pers; //角速度积分
- angle_clamp(smo.est_angle);
- smo.est_rpm = (30.0f * smo.est_rad_pers_filted/M_PI/smo.motor_poles);
- if (smo.est_rpm > CONFIG_MAX_MOT_RPM) {
- smo.est_rpm = CONFIG_MAX_MOT_RPM;
- }else if (smo.est_rpm < 0) {
- smo.est_rpm = 0;
- }
- /* 对低通进行角度补偿 */
- smo.est_angle_out = smo.est_angle;// + fast_arctan2(smo.est_rad_pers_filted, smo.lpf_wc*2*M_PI);
- /* 通过速度对角度再次补偿, ANGLE_COMP_RPM_CEOF 这个值通过校准获取 */
- smo.est_angle_out += smo.est_rpm * ANGLE_COMP_RPM_CEOF;
- angle_clamp(smo.est_angle_out);
- }
- float smo_observer_est_angle(void) {
- return pi_2_degree(smo.est_angle_out);
- }
- //机械角度 rpm
- float smo_observer_est_rpm(void) {
- return smo.est_rpm;
- }
|