完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一,什么是FOC
FOC(Field Oriented Control)是采用数学方法实现三相电机的力矩与励磁的解耦控制。 主要是对电机的控制电流进行矢量分解,变成励磁电流Id和交轴电流Iq ,励磁电流主要是产生励磁,控制的是磁场的强度(励磁就是控制定子的电压使其产生的磁场变化,改变直流电机的转速,改变励磁同样起到改变转速的作用。),而交轴电流是用来控制力矩。 二,FOC的框图和模块划分 从框图上可以分成下面的几个部分: 1. 电机的d-q模型:clark变换,park变换,park逆变换。 2. 外部的对象:三相逆变驱动器(3-phase inverter)(通常指三相全桥驱动电路)和电机(直流无刷电机BLDC) 3. 空间矢量脉冲调制模块:SVPWM 4. PI调节器:基于小信号控制理论,把电流差值转换成电压的调节器。 5. 给定的Iq_ref和Id-ref: 需要说明的地方: 1. FOC算法是电机控制算法的一部分,具有可替代性,比如DTC。而整体的电机控制算法是基于小信号控制理论的。 2. FOC算法可用于异步电机,直流无刷电机,永磁同步电机。 3. 给定的Iq_ref和Id-ref要根据电机相关模型和参数计算得出。 4. 该算法受物理定律,软件框架,软件相应速度等限制。 三,各个模块的简介 1. 电机数学模型-坐标变换:clark和park变换。 坐标轴变换-clark变换: 坐标轴变换-park变换: 下面的公式,x可以是电压也可以是电流 park 正变换: park逆变换: 2. SVPWM模块: 3. 如何给定的Iq_ref和Id-ref(内嵌式永磁同步机模型): 在AP32013i_Inverter_TC27xC_1_22中英飞凌给出是MTPA-电压极限圆-MTPF的方法,如下; A-B:MTPA(Maximum-torque-per-ampere) C:保持要求扭矩时的减弱磁场 D:弱磁在极限转矩时 E-F:MTPF(Maximum-torque-per-flux) 程序如下: Ifx_MotorModelPmsmF32_Data *p = &model-》params; float32 deltaL = p-》ld - p-》lq; float32 fluxM = p-》fluxM; sint16 n; float32 p_1_5 = 1.5 * p-》polePair; float32 iq_mtpa, id_mtpa; cfloat32 idqRef; float32 T_ref = input-》ref.torque; /* Actual torque (estimated) -------------------------------------------------------*/ output-》torque = p_1_5 * model-》foc.idq.imag * (fluxM + model-》foc.idq.real * deltaL); { /* MAXIMUM TORQUE PER AMPERE (MTPA) ------------------------------------------- */ float32 Tn_ref, Tn_f; float32 deltaL_sq, fluxM_sq; float32 Iq_n, Iq_n_3; float32 f_n, df_n; Tn_ref = (T_ref 《 0) ? (-T_ref / p_1_5) : (T_ref / p_1_5); deltaL_sq = deltaL * deltaL; Tn_f = Tn_ref * fluxM; Iq_n = Tn_ref / (p_1_5 * fluxM); if (Iq_n 》 0) { for (n = 0; n 《 3; n++) { Iq_n_3 = Iq_n * Iq_n * Iq_n; f_n = (Iq_n * (Iq_n_3 * deltaL_sq + Tn_f)) - (Tn_ref * Tn_ref); df_n = (4 * Iq_n_3 * deltaL_sq) + Tn_f; Iq_n = Iq_n - (f_n / df_n); } } iq_mtpa = Iq_n; fluxM_sq = (fluxM * fluxM); id_mtpa = (fluxM - __sqrtf(fluxM_sq + (4 * deltaL_sq * Iq_n * Iq_n))) / (-2 * deltaL); } if (model-》fieldWeakeningEnabled) { /* FIELD-WEAKENING ------------------------------------------------------------ */ // Maximum flux from nominal DC voltage, rotation speed and correction-feedback */ float32 absSpeed = __absf(model-》electricalSpeed) + 1.0e-9; float32 fluxMaxAbs = model-》vdc / (IFX_SQRT_THREE / IFX_FOCF32_VDQ_THRESHOLD) / absSpeed; float32 fluxMax = __maxf(fluxMaxAbs + model-》foc.fw.fbValue, 0.0); model-》fluxMax = fluxMax; float32 fluxMax_sq = fluxMax * fluxMax; // Q-axis flux float32 Lq = p-》lq; float32 Ld = p-》ld; float32 fluxQ = Lq * iq_mtpa; float32 fluxQ_sq = fluxQ * fluxQ; // Calculate Id_fw from the following conditions: // fluxQ_sq + fluxD_sq 《= fluxMax_sq // (Lq*Iq)^2 + (fluxM + Ld*Id)^2 《= fluxMax_sq // Id 《= -fluxPM /Ld + sqrtf(fluxMax_sq - fluxQ_sq)/Ld; float32 id_fw; float32 deltaFlux_sq = fluxMax_sq - fluxQ_sq; id_fw = (deltaFlux_sq 》 0) ? ((-fluxM + __sqrtf(deltaFlux_sq)) / Ld) : (-fluxM / Ld); float32 deltaId = id_fw - id_mtpa; if (deltaId 《 0) { // We are in field-weakening, check whether torque should be reduced float32 idqLimit = Ifx_FocF32_getIdqLimit(&model-》foc); id_fw = __maxf(id_fw, -idqLimit); iq_mtpa = (T_ref 《 0) ? -iq_mtpa : iq_mtpa; float32 iq_fw = iq_mtpa; float32 fluxD = ((Ld * id_fw) + fluxM); float32 fluxD_sq = fluxD * fluxD; deltaFlux_sq = fluxMax_sq - fluxD_sq; iq_fw = (deltaFlux_sq 》 0) ? (__sqrtf(deltaFlux_sq) / Lq) : 0; float32 deltaIq = (-iq_mtpa * deltaId * deltaL) / ((id_fw * deltaL) + fluxM); float32 iq_corr = iq_mtpa + deltaIq; boolean reducedTorque = (iq_corr 《 iq_fw); iq_fw = reducedTorque ? iq_corr : iq_fw; //if (reducedTorque) __debug(); iq_fw = (iq_fw 《 iq_mtpa) ? iq_fw : iq_mtpa; iq_fw = __minf(__sqrtf(__sqrf(idqLimit) - __sqrf(id_fw)), iq_fw); idqRef.real = id_fw; idqRef.imag = (T_ref 《 0) ? -iq_fw : iq_fw; model-》fw = idqRef; } else { idqRef.real = id_mtpa; idqRef.imag = (T_ref 《 0) ? -iq_mtpa : iq_mtpa; } } else { idqRef.real = id_mtpa; idqRef.imag = (T_ref 《 0) ? -iq_mtpa : iq_mtpa; } /* Transfer the current references to current controller (FOC) block ---------------*/ input-》ref.current = idqRef; 四,关于调试: (一),测试相电流采样电路的功能。 1、不接电机,连续采样相电流,此时采样值为相电流为0时的值,此时值应该比较稳定,变化不大,如果变化比较大,说明有问题。 2、接上电机,给U相设置占空比为5%,V、W占空比为0,此时可以用万用表测量取样电阻上的电压值,应该已经有值。再用adc采样相电流,计算相电流采样极性和大小是否正常。根据正电压产生正电流的电动机原则,U相电流应该是正的,V、W两相电流应该是负的,且V、W两相电流应基本相同。若正负号不对,需要进行调整。 (二)、测试变换程序的正确性。矢量控制的核心其实就在Clark与Park变换上,通过这两个变换实现了直轴与交轴的解耦。如果使用的是官方的库,可以不管本步骤。如果是自己写的,需要通过仿真测试等手段,确保程序的正确性。 (三)、调试SVPWM模块。通过SVPWM模块可以把FOC的控制结果转换为定时器6个通道的占空比,从而驱动三相逆变模块控制定子绕组产生旋转磁场,拖动转子旋转。为了验证SVPWM模块的功能,需要使用上图中的6、7即反park变换和SVPWM模块,产生开环的旋转磁场。 1、把FOC其他部分注释掉,只保留反park变换和svpwm函数。 2、反park变换的输入参数有3个:Vq、Vd、Angle,将Vq=0,Vd设置为一个较小的值,Angle=0,然后接电机上电,此时svpwm会有输出,电机有力,转子被锁定在当前电角度位置。如果没有力,说明Vd值太小了。同时可以查看CH1、CH2、CH3的波形和svpwm的标准波形做对比。比如,处于svpwm的扇区1,那么CH1、CH2、CH3上的波形关系如下: 你可以在仿真模式下,把CH1、CH2、CH3通道的比较值加入watch窗口,然后手动改变Vd的值。改变Vd的值,3个通道的比较值也会跟着改变。 3、将Angle由0开始,每次增加30°左右,此时电机会跟着旋转,且每次旋转的角度应该是相同的,记录下这个旋转方向,这就是此系统固有的正方向。此时还可以验证电机的极对数,若Angle重复增加N个周期后电机回到起始点(可用记号笔进行标注),电机的极对数即为N。 (四)、整定d轴、q轴PID参数。 1、把电流采样模块、clark变换、park变换、PID控制器加入。 2、此时系统的输入参数有3个:PID控制器的参考量IQREF、IDREF和Angle。设置Angle=0,IQREF=0,IDREF设置为一个较小值(可以与上面的Vd一样)。 3、d轴和q轴都有PID控制器,将两个PID的参数都设置为0。之后保持q轴的PID为0,然后整定d轴的参数(整定的过程中,可以给电机上电观察效果,目的是使电流采样值经过clark、park变换后的Iq、Id值接近于IQREF、IDREF)。d轴整定完后,把q轴的PID参数设置为相同即可。 (五)、使用编码器输出角度替代Angle值 (六)、验证电流闭环 我们先来验证d轴,将IqRef设置为0,IdRef设置为一个合适的正值,此时电机是不会旋转的,用手转动电机也是可以转动的,只是不同于自由转动状态,此时旋转电机时会感到阻力较大,有一个力始终在维持电机处于当前位置。 验证q轴时同理将IdRef设置为0,IqRef设置为一个合适的值即可。需要注意的是,因为启动电流明显大于稳态电流,如果IqRef的值设置得过小,电机无法旋转起来,而增大IqRef,使电机可以旋转起来后,电机会一直加速到最高转速。为保证安全,需要对输出电压占空比进行限幅。 将IqRef设置为正值时电机应该正转,设置为负值时电机应该反转,且正反转速应该是相同的。此时还可以进一步观察转速采样结果,如果和实际情况符合的话就可以进行下一步了。 总结:本文简述了FOC的各个模块和调试方法。 |
|
|
|
只有小组成员才能发言,加入小组>>
2384 浏览 0 评论
8906 浏览 4 评论
36474 浏览 19 评论
4980 浏览 0 评论
24297 浏览 34 评论
1374浏览 2评论
1627浏览 1评论
2017浏览 1评论
1441浏览 0评论
385浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 20:38 , Processed in 1.255325 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号