#
FOC算法的简要介绍 v2.0.2
Field oriented control (FOC) 算法的主要任务是基于用户定义的电压 uq,通过连续读取电机转子位置 a,计算出适当的相电压ua,ub 和 uc。
FOC算法在电机转子中产生磁场的相位电压,该磁场正好在转子的永磁体的磁场后面90度,创造了一个推动效应。这是一个很好的动画表示,当运行简化版的FOC即六步调制时,电机内部发生了什么。
另一种理解为什么我们需要在转子和定子磁场之间形成90度角的方法是记住导线穿过磁场时产生的电场的方程:
F = B*I*L*sin(alpha)
其中B
是磁场的强度, L
是导电流的大小, alpha
是磁场B
和电流, I
之间的角度。从这个方程中我们可以看到,为了获得最大的力 F = B*I*L
,我们需要保持alpha
角等于90度或 PI/2
弧度。
如何计算ua,ub 和uc 的恰当电压值
由于Simple FOC library 的目的是关于FOC算法的知识以及支持各种应用,两个最标准的FOC调制版本在这个库中实现。
- 正弦PWM:
SinePWM
- 空间矢量PWM:
SpaceVectorPWM
可以通过设置 motor.foc_modulation
的变量值进行配置:
motor.foc_modulation = FOCModulationType::SinePWM; // default
// or
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
正弦调制SinePWM
正弦调制法是基于两个变换方程。
逆派克变换法:
逆克拉克变换法:
以下是在中实现正弦PWM的代码:
// 使用FOC将Uq设置到电机的最佳角度
void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
// 正弦PWM调制
// 逆派克+克拉克变换
// 角度在0和360°之间的归一化
// 仅当使用_sin和_cos近似函数时才需要
angle_el = normalizeAngle(angle_el + zero_electric_angle);
// 逆派克变换
Ualpha = -_sin(angle_el) * Uq; // -sin(angle) * Uq;
Ubeta = _cos(angle_el) * Uq; // cos(angle) * Uq;
// 你克拉克变换
Ua = Ualpha + voltage_power_supply/2;
Ub = -0.5 * Ualpha + _SQRT3_2 * Ubeta + voltage_power_supply/2;
Uc = -0.5 * Ualpha - _SQRT3_2 * Ubeta + voltage_power_supply/2;
// 给硬件设定电压
setPwm(Ua, Ub, Uc);
}
空间矢量调制 SpaceVectorPWM
空间矢量调制基于两个步骤的计算:
在第一步,我们发现扇区s转子目前在。360度的角被分成6等份的60度。这个计算很简单。然后我们计算时间T0, T1 和 T2。T1 和 T2告诉我们第一阶段和第二阶段应该开多久,T0告诉我们电机上0电压应该开多久。
第二步是将T0,1,2值投影到适当的占空比Ta,b,c,这些占空比直接取决于电机当前所在的扇区。
Sector | Ta | Tb | Tc |
---|---|---|---|
1 | T1 + T2 + T0/2 | T2 + T0/2 | T0/2 |
2 | T1 + T0/2 | T1 + T2 + T0/2 | T0/2 |
3 | T0/2 | T1 + T2 + T0/2 | T2 + T0/2 |
4 | T0/2 | T1+ T0/2 | T1 + T2 + T0/2 |
5 | T2 + T0/2 | T0/2 | T1 + T2 + T0/2 |
6 | T1 + T2 + T0/2 | T0/2 | T1 + T0/2 |
下面是一个例子使用SVM表生成pwm信号的参数: s = 2, T1 = 1/8 = 0.125, T2 = 1/8 = 0.125 and T0 = 1/2 = 0.5
这里是空间矢量PWM实现的代码在 SimpleFOClibrary :
// 使用FOC将Uq设置到电机的最佳角度
void BLDCMotor::setPhaseVoltage(float Uq, float angle_el) {
// 解释SpaceVectorModulation (SVPWM)算法的视频如下
// https://www.youtube.com/watch?v=QMSWUMEAejg
// 如果负电压的变化与相相反
// 角度 +180°
if(Uq < 0) angle_el += _PI;
Uq = abs(Uq);
// 角度归一化,在0和360°之间
// 仅当使用_sin和_cos近似函数时才需要
angle_el = normalizeAngle(angle_el + zero_electric_angle + _PI_2);
// 找到我们目前所在的象限
int sector = floor(angle_el / _PI_3) + 1;
// 计算占空比
float T1 = _SQRT3*_sin(sector*_PI_3 - angle_el) * Uq/voltage_power_supply;
float T2 = _SQRT3*_sin(angle_el - (sector-1.0)*_PI_3) * Uq/voltage_power_supply;
// 两个版本
// 以电压电源为中心/2
float T0 = 1 - T1 - T2;
// 低电源电压,拉到0
//float T0 = 0;
// 计算占空比(时间)
float Ta,Tb,Tc;
switch(sector){
case 1:
Ta = T1 + T2 + T0/2;
Tb = T2 + T0/2;
Tc = T0/2;
break;
case 2:
Ta = T1 + T0/2;
Tb = T1 + T2 + T0/2;
Tc = T0/2;
break;
case 3:
Ta = T0/2;
Tb = T1 + T2 + T0/2;
Tc = T2 + T0/2;
break;
case 4:
Ta = T0/2;
Tb = T1+ T0/2;
Tc = T1 + T2 + T0/2;
break;
case 5:
Ta = T2 + T0/2;
Tb = T0/2;
Tc = T1 + T2 + T0/2;
break;
case 6:
Ta = T1 + T2 + T0/2;
Tb = T0/2;
Tc = T1 + T0/2;
break;
default:
// 可能的错误状态
Ta = 0;
Tb = 0;
Tc = 0;
}
// 计算相电压和中心
Ua = Ta*voltage_power_supply;
Ub = Tb*voltage_power_supply;
Uc = Tc*voltage_power_supply;
break;
}
// 设置硬件中的电压
setPwm(Ua, Ub, Uc);
}
我们应如何选择?
这是由 Uq = 0.5V的正弦和空间矢量调制产生的波形图像:
Sinusoidal | Space Vector |
---|---|
这两种算法之间有几个关键的区别。但就SimpleFOClibrary而言,你需要知道的就是空间矢量算法更好地使用了电源的最大电压范围。在上面的表格中,你可以看到,对于Uq = 0.5V,正弦调制产生的正弦波的幅度正好等于1,空间矢量调制还不是平静的。由空间矢量产生的“双正弦波”的幅值为 2/sqrt(3) = 1.15
,这意味着在使用相同的电源时,它可以向电机多输出15%的功率。
这意味着,当使用SinePWM
时,你的供电电压 Vpower_supply可以设置最大为 Uq = 0.5 Vpower_supply 。如果使用 SpaceVectorPWM
,你将能够设置Uq = 0.58 Vpower_supply
你应该通过改变电机参数motor.voltage_power_supply
的值来指定电源电压Vpower_supply。默认值为 12V
。如果你需要设置你的Vpower_supply为其他值,在这里更改它,FOC算法将据此调整适当的Uq (motor.voltage_q
)值。
// 电源电压
motor.voltage_power_supply = 12;
如果我不指定这个参数呢?
如果你没有指定motor.voltage_power_supply
算法仍然有效,但你motor.voltage_q
的值将不再等于实际输出电压。
当我超过最大值Uq时会发生什么?
如果你试着把电压 Uq高于Uq = 0.5 Vpower_supply 给 SinePWM
或 Uq = 0.58 Vpower_supply给SpaceVectorPWM
,它仍然会工作,但 Ua,b,c信号会饱和。
这里有一些 SinePWM
的不同Uq值的图像。
Uq = 0.5 Vpower_supply | Uq = 0.6 Vpower_supply | Uq = Vpower_supply |
---|---|---|
基本上你可以在图像上看到的是Ua,b,c是饱和的,在你超过最大值后,你实际上不再设置正弦波到你的电机。 电机的功率仍在增加,但不再是直线或平滑的。
经验法则
在现实中,电机可以看到的差异一直到Uq ~ 0.7 Vpower_supply 。在此值之后,Ua,b,c过于饱和,Uq的进一步增加不会导致电机功率的增加。 但是每一个电机都有点不同,你可以很容易地根据经验检查这些值。将电机置于电压控制中,查看电压*Uq*后,电机功率将不再有改善(它将停止加速)。
进一步阅读
有关初始化过程、实时执行和实现细节的更多信息,请访问FOC implementation docs.