| 本帖最后由 穿西装的强子 于 2025-1-8 18:47 编辑 
 #申请原创#  @21小跑堂
 无感foc与有感foc的区别只是有没有接入编码器、HALL传感器的区别;
 有感foc通过编码器、HALL识别初始角度,计算电角度;
 无感foc有许多方案进行电角度识别,高频注入、磁链观测等多种方案,这次只说明磁链观测器的方案解读;
 先是foc的配置,一般有但电阻、双电阻、三电阻识别,常用的双电阻识别较多;
 理论上双电阻可以计算出第三路电流;
 foc大致流程
 通过三路电流,Ia,Ib,Ic值,使用clark变化,得到Iα和Iβ;
 使用Park变化得到d轴电流和q轴电流;
 通过pid电流环使用Id/Iq得到Vd/Vq;
 根据编码器或其它方式得到电角度;
 使用逆向park变化通过电角度参数得到Vα和Vβ;
 计算SVPWM;
 根据Vα和Vβ获取当前所在电角度扇区,计算SVPWM的Ta,Tb,Tc值,输出到三相桥的pwm控制;
 
 磁链观测器源码
 
 flux_observer函数的核心部分,主要实现了基于磁场定向控制(FOC)的电机磁通观测器的计算逻辑。以下是详细的功能解释:
 
 1. 变量声明与初始化
 float VoltRs[2];
 float VoltdPhi[2];
 
 float g_fluxfluxR = 0.0f;
 float sin_theta = 0.0f;
 float cos_theta = 0.0f;
 
 VoltRs :存储α轴和β轴的电阻压降。
 VoltdPhi :存储α轴和β轴的磁通变化。
 g_fluxfluxR :用于存储转子磁通的平方和。
 sin_theta  和  cos_theta :用于存储角度的正弦和余弦值。
 
 2. 计算α轴磁通
 //calc alpha axis flux
 VoltRs[0] = Foc_observer.Rs * Foc_calc.Ialpha;
 VoltdPhi[0] = Foc_calc.Valpha - VoltRs[0];
 VoltdPhi[0] += fluxR_in_wb[0] * Foc_observer.Err * Foc_observer.Gain;
 flux_in_wb[0] += VoltdPhi[0] * Foc_observer.Ctrl_ts;
 
 计算电阻压降 : VoltRs[0] = Foc_observer.Rs * Foc_calc.Ialpha ,其中  Foc_observer.Rs  是电机电阻, Foc_calc.Ialpha  是α轴电流。
 计算磁通变化 : VoltdPhi[0] = Foc_calc.Valpha - VoltRs[0] ,即α轴电压减去电阻压降。
 添加误差修正 : VoltdPhi[0] += fluxR_in_wb[0] * Foc_observer.Err * Foc_observer.Gain ,根据转子磁通误差进行修正。
 更新总磁通 : flux_in_wb[0] += VoltdPhi[0] * Foc_observer.Ctrl_ts ,根据时间步长更新α轴磁通。
 
 3. 计算β轴磁通
 //calc beta axis flux
 VoltRs[1] = Foc_observer.Rs * Foc_calc.Ibeta;
 VoltdPhi[1] = Foc_calc.Vbeta - VoltRs[1];
 VoltdPhi[1] += fluxR_in_wb[1] * Foc_observer.Err * Foc_observer.Gain;
 flux_in_wb[1] += VoltdPhi[1] * Foc_observer.Ctrl_ts;
 
 计算电阻压降 : VoltRs[1] = Foc_observer.Rs * Foc_calc.Ibeta ,其中  Foc_calc.Ibeta  是β轴电流。
 计算磁通变化 : VoltdPhi[1] = Foc_calc.Vbeta - VoltRs[1] ,即β轴电压减去电阻压降。
 添加误差修正 : VoltdPhi[1] += fluxR_in_wb[1] * Foc_observer.Err * Foc_observer.Gain ,根据转子磁通误差进行修正。
 更新总磁通 : flux_in_wb[1] += VoltdPhi[1] * Foc_observer.Ctrl_ts ,根据时间步长更新β轴磁通。
 
 4. 计算定子磁通
 //calc flux in stator
 fluxS_in_wb[0] = Foc_observer.Ls * Foc_calc.Ialpha;
 fluxS_in_wb[1] = Foc_observer.Ls * Foc_calc.Ibeta;
 
 计算定子磁通 :根据电感 ( Foc_observer.Ls ) 和电流 ( Foc_calc.Ialpha ,  Foc_calc.Ibeta ) 计算定子磁通。
 
 5. 计算转子磁通
 //calc flux in rotor
 fluxR_in_wb[0] = flux_in_wb[0] - fluxS_in_wb[0];
 fluxR_in_wb[1] = flux_in_wb[1] - fluxS_in_wb[1];
 
 计算转子磁通 :从总磁通中减去定子磁通得到转子磁通。
 
 6. 计算磁通误差
 g_fluxfluxR = fluxR_in_wb[0] * fluxR_in_wb[0] + fluxR_in_wb[1] * fluxR_in_wb[1];
 Foc_observer.Err = Foc_observer.Flux * Foc_observer.Flux - g_fluxfluxR;
 
 计算转子磁通的平方和 : g_fluxfluxR = fluxR_in_wb[0] * fluxR_in_wb[0] + fluxR_in_wb[1] * fluxR_in_wb[1] 。
 更新磁通误差 : Foc_observer.Err = Foc_observer.Flux * Foc_observer.Flux - g_fluxfluxR ,即期望磁通的平方减去实际磁通的平方和。
 
 7. 计算PLL误差
 sin_theta = arm_sin_f32(Foc_observer.Theta);
 cos_theta = arm_cos_f32(Foc_observer.Theta);
 
 Foc_observer.PLL_Err = fluxR_in_wb[1] * cos_theta - fluxR_in_wb[0] * sin_theta;
 Foc_observer.PLL_Interg += Foc_observer.PLL_Err * Foc_observer.PLL_ki;
 Foc_observer.PLL_Ui = Foc_observer.PLL_Err * Foc_observer.PLL_kp + Foc_observer.PLL_Interg;
 
 计算正弦和余弦值 :使用  arm_sin_f32  和  arm_cos_f32  计算当前角度的正弦和余弦。
 计算PLL误差 : Foc_observer.PLL_Err = fluxR_in_wb[1] * cos_theta - fluxR_in_wb[0] * sin_theta 。
 更新PLL积分项 : Foc_observer.PLL_Interg += Foc_observer.PLL_Err * Foc_observer.PLL_ki 。
 计算PLL输出 : Foc_observer.PLL_Ui = Foc_observer.PLL_Err * Foc_observer.PLL_kp + Foc_observer.PLL_Interg 。
 
 8. 更新角度
 Foc_observer.Theta += Foc_observer.PLL_Ui;
 
 if (Foc_observer.Theta < 0.0f)
 {
 Foc_observer.Theta += MATH_2PI;
 }
 else if (Foc_observer.Theta > MATH_2PI)
 {
 Foc_observer.Theta -= MATH_2PI;
 }
 
 更新角度 :根据PLL输出更新角度。
 确保角度在合理范围内 :如果角度小于0,则加2π;如果角度大于2π,则减2π。
 
 9. 计算速度
 if (speed_calc_cnt < 10)
 {
 speed_acc += Foc_observer.PLL_Ui;
 speed_calc_cnt++;
 }
 else
 {
 speed_now = speed_acc / (0.001f * MATH_2PI);
 Foc_observer.speed_hz = Foc_observer.speed_hz * 0.99f + speed_now * 0.01f;
 
 speed_acc = 0.0f;
 speed_calc_cnt = 0;
 }
 
 累加PLL输出 :当计数小于10时,累加PLL输出。
 计算当前速度 :当计数等于10时,计算平均速度并更新速度估计。
 重置计数 :重置速度累加器和计数器以便下一次循环。
 
 这段代码通过一系列计算,实现了对电机α轴和β轴磁通的观测,并根据观测结果调整角度和速度。具体步骤包括计算电阻压降、磁通变化、定子和转子磁通、磁通误差、PLL误差,以及更新角度和速度。
 
 
 
 
 |