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()

运行与验证

  1. 运行方式:将上述代码保存为foc_openloop.py,执行python foc_openloop.py。
  2. 预期输出:控制台打印θ=0时刻三相占空比,应接近理论值U=0.500、V=0.250、W=0.750(允许±0.01误差)。
  3. 波形验证:弹出的波形图中,三相占空比为互差120°的正弦变化曲线,频率50Hz,幅值约Vq/Vdc=0.208,中心在0.5处。
  4. 判定标准:若θ=0处占空比与理论值偏差小于0.02,且波形呈现三相对称正弦且相位互差120°,则验证通过。

关键说明

  • 本案例使用归一化周期T=1简化SVPWM计算,实际工程中需替换为PWM周期值(如T=1/20000秒)。
  • 开环控制下电角度由程序直接给定,不依赖编码器反馈;实际电机运行时需将theta_elec替换为转子位置。
  • 占空比与相电压关系:V_phase = (duty - 0.5) * Vdc,验证时可通过该式换算回电压幅值。