1. FOC开环电压控制基础
任务目标
本案例实现电机开环电压模式下的FOC控制:给定目标电角度与电压幅值,通过SVPWM算法生成U/V/W三相占空比,验证三相电压波形与电角度的对应关系。控制对象为理想三电阻采样逆变器驱动的永磁同步电机(PMSM),不涉及电流闭环与转速反馈。
核心原理
FOC开环电压控制将定子电压矢量分解到d-q旋转坐标系,在开环状态下直接给定Vd、Vq及电角度θe,经Park逆变换得到α-β轴电压,再由SVPWM合成三相占空比。本案例固定Vd=0,仅施加Vq,使电压矢量方向始终与q轴对齐,观察三相电压随电角度变化的相位关系。
环境依赖
- Python 3.8+,仅需标准库(math、matplotlib)
- matplotlib用于波形可视化
关键完整代码
import math
import matplotlib.pyplot as plt
# ---------- 参数定义 ----------
Vdc = 24.0 # 母线电压(V)
Vq = 5.0 # q轴电压幅值(V)
Vd = 0.0 # d轴电压
theta_elec = 0.0 # 初始电角度(rad)
speed_elec = 2*math.pi*50 # 电角速度(rad/s),对应50Hz电频率
dt = 1e-4 # 仿真步长(s)
sim_time = 0.04 # 仿真时长(s),2个电周期
# ---------- SVPWM实现 ----------
def svm_alpha_beta(alpha, beta, Vdc):
"""α-β轴电压转三相占空比(SVPWM,七段式)"""
# 1. 判断扇区
v1 = beta
v2 = (math.sqrt(3)/2)*alpha - 0.5*beta
v3 = -v1 - v2
sector = 0
if v1 > 0: sector = 1
if v2 > 0: sector = sector + 2
if v3 > 0: sector = sector + 4
# 2. 计算相邻矢量作用时间
T = 1.0 # 归一化周期
x = (math.sqrt(3)*v2*T) / Vdc
y = (1.5*v1 + math.sqrt(3)/2*v2) * T / Vdc
z = (1.5*v1 - math.sqrt(3)/2*v2) * T / Vdc
if sector == 1: t1, t2 = z, y
elif sector == 2: t1, t2 = y, -x
elif sector == 3: t1, t2 = -z, x
elif sector == 4: t1, t2 = -x, z
elif sector == 5: t1, t2 = x, -y
else: t1, t2 = -y, -z
# 3. 限幅
t_sum = t1 + t2
if t_sum > T:
scale = T / t_sum
t1 *= scale
t2 *= scale
# 4. 计算占空比(七段式)
t_min = (T - t1 - t2) / 2
ta = t_min
tb = ta + t1
tc = tb + t2
if sector == 1: d1, d2, d3 = tb, ta, tc
elif sector == 2: d1, d2, d3 = ta, tc, tb
elif sector == 3: d1, d2, d3 = ta, tb, tc
elif sector == 4: d1, d2, d3 = tc, tb, ta
elif sector == 5: d1, d2, d3 = tc, ta, tb
else: d1, d2, d3 = tb, tc, ta
return d1, d2, d3
# ---------- 主仿真循环 ----------
time_points = []
duty_u, duty_v, duty_w = [], [], []
theta_points = []
t = 0.0
while t < sim_time:
theta_elec = speed_elec * t # 电角度随时间线性增加
# Park逆变换:d-q → α-β
alpha = Vd*math.cos(theta_elec) - Vq*math.sin(theta_elec)
beta = Vd*math.sin(theta_elec) + Vq*math.cos(theta_elec)
# SVPWM调制
du, dv, dw = svm_alpha_beta(alpha, beta, Vdc)
time_points.append(t)
theta_points.append(theta_elec)
duty_u.append(du)
duty_v.append(dv)
duty_w.append(dw)
t += dt
# ---------- 验证:检查相位关系 ----------
# 在θ=0处,Vq=5V,α=0,β=5V,此时U相占空比应接近50%+β/Vdc*0.5
idx_zero = min(range(len(theta_points)), key=lambda i: abs(theta_points[i] % (2*math.pi)))
print(f"θ=0时: U占空比={duty_u[idx_zero]:.3f}, V占空比={duty_v[idx_zero]:.3f}, W占空比={duty_w[idx_zero]:.3f}")
print(f"理论值: U=0.500, V=0.250, W=0.750 (Vq=5V, Vdc=24V)")
# ---------- 波形绘制 ----------
plt.figure(figsize=(10, 5))
plt.plot(time_points, duty_u, label='U相')
plt.plot(time_points, duty_v, label='V相')
plt.plot(time_points, duty_w, label='W相')
plt.xlabel('时间(s)')
plt.ylabel('占空比')
plt.title('FOC开环电压控制三相占空比波形')
plt.legend()
plt.grid(True)
plt.ylim(0, 1)
plt.show()
运行与验证
- 运行方式:将上述代码保存为
foc_openloop.py,执行python foc_openloop.py。 - 预期输出:控制台打印θ=0时刻三相占空比,应接近理论值U=0.500、V=0.250、W=0.750(允许±0.01误差)。
- 波形验证:弹出的波形图中,三相占空比为互差120°的正弦变化曲线,频率50Hz,幅值约
Vq/Vdc=0.208,中心在0.5处。 - 判定标准:若θ=0处占空比与理论值偏差小于0.02,且波形呈现三相对称正弦且相位互差120°,则验证通过。
关键说明
- 本案例使用归一化周期T=1简化SVPWM计算,实际工程中需替换为PWM周期值(如
T=1/20000秒)。 - 开环控制下电角度由程序直接给定,不依赖编码器反馈;实际电机运行时需将
theta_elec替换为转子位置。 - 占空比与相电压关系:
V_phase = (duty - 0.5) * Vdc,验证时可通过该式换算回电压幅值。