1. FOC控制框图总览

任务目标

本案例用一张完整的FOC控制框图,把从电流采样到电机驱动的信号链路一次性讲清。你需要能指出每个模块的输入/输出是什么、为什么放在这个位置,以及信号在静止abc坐标系 → 静止αβ坐标系 → 旋转dq坐标系 → 电压矢量 → PWM脉冲之间的变换路径。

FOC完整控制框图

FOC 双闭环控制框图(电流内环 + 速度外环) 速度PI ω_ref → iq_ref − ω_ref 速度反馈 id PI id_err → vd iq PI iq_err → vq − id_ref=0 − iq_ref 反Park变换 dq → αβ vd,vq,θ → vα,vβ SVPWM αβ → 占空比 扇区判断+矢量合成 vα,vβ 三相逆变器 6路PWM → 三相电压 PWM PMSM 三相绕组 产生转矩 ia,ib,ic Clarke变换 abc → αβ Park变换 αβ → dq 电流采样 ia, ib(ic = −ia−ib) iα,iβ id_fb iq_fb 编码器 θ, ω θ(用于Park/反Park) 速度计算 dθ/dt → ω 正向信号流 反馈信号流

信号流向与各模块功能

模块输入输出核心作用
速度PIω_ref 与 ω_fb 的误差iq_ref外环:速度误差经PI调节产生q轴电流给定,控制转矩大小
id/iq PIid_ref(=0)/iq_ref 与 id_fb/iq_fb 的误差vd, vq内环:电流误差经PI调节产生dq轴电压给定
反Park变换vd, vq, θvα, vβ将旋转dq系电压变换到静止αβ系
SVPWMvα, vβ6路PWM占空比判断扇区、计算矢量作用时间,合成期望电压矢量
三相逆变器PWM信号三相电压加至电机功率放大,将直流母线电压按PWM规律施加到电机绕组
Clarke变换ia, ib(ic由基尔霍夫定律推算)iα, iβ三相静止abc → 两相静止αβ
Park变换iα, iβ, θid, iq两相静止αβ → 旋转dq,得到直流量便于PI控制

关键理解点

  • 坐标变换的目的:Clarke+Park把正弦变化的ia/ib/ic变成直流量id/iq,使PI调节器能实现无静差控制;反Park+SVPWM再把dq电压指令还原为三相PWM。
  • id_ref=0控制:表贴式PMSM常用此策略,让所有电流用于产生转矩(iq),id保持为0以最大化转矩电流比。
  • 角度θ的关键作用:θ同时用于Park变换(电流反馈)和反Park变换(电压给定),角度不准会直接导致dq轴耦合失控。
  • 双闭环结构:内环电流环带宽高(响应快),外环速度环带宽低(响应慢),内外环配合实现转速精确控制。
// 当前案例缺失代码:FOC控制框图总览(仅补充绘图与信号流定义)
// 使用Python matplotlib绘制框图,并标注信号流向

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyArrowPatch

fig, ax = plt.subplots(figsize=(14, 6))
ax.set_xlim(0, 16)
ax.set_ylim(0, 6)
ax.axis('off')

# 模块位置定义 (x, y, w, h)
blocks = {
    'iq_ref': (0.5, 3.2, 1.2, 0.8),
    'id_ref': (0.5, 1.5, 1.2, 0.8),
    'PI_q':   (2.5, 3.2, 1.2, 0.8),
    'PI_d':   (2.5, 1.5, 1.2, 0.8),
    'InvPark':(4.8, 2.35, 1.4, 1.0),
    'SVPWM':  (7.0, 2.35, 1.4, 1.0),
    'Inverter':(9.3, 2.35, 1.4, 1.0),
    'Motor':  (11.8, 2.35, 1.4, 1.0),
    'Clarke': (14.2, 2.35, 1.2, 1.0),
    'Park':   (14.2, 0.8, 1.2, 1.0),
}

# 绘制方块
for name, (x, y, w, h) in blocks.items():
    rect = mpatches.FancyBboxPatch((x, y), w, h,
                                   boxstyle="round,pad=0.05",
                                   edgecolor='black', facecolor='lightblue', linewidth=1.5)
    ax.add_patch(rect)
    ax.text(x + w/2, y + h/2, name, ha='center', va='center', fontsize=9, fontweight='bold')

# 信号线(箭头)
def arrow(p1, p2, color='black', style='-|>', lw=1.5):
    ax.add_patch(FancyArrowPatch(p1, p2, arrowstyle=style, mutation_scale=15,
                                 color=color, linewidth=lw))

# 参考电流 -> PI
arrow((1.7, 3.6), (2.5, 3.6))  # iq_ref -> PI_q
arrow((1.7, 1.9), (2.5, 1.9))  # id_ref -> PI_d

# PI -> 逆Park
arrow((3.7, 3.6), (4.8, 3.0))  # Vq
arrow((3.7, 1.9), (4.8, 2.6))  # Vd

# 逆Park -> SVPWM
arrow((6.2, 2.85), (7.0, 2.85))  # Valpha, Vbeta

# SVPWM -> 逆变器
arrow((8.4, 2.85), (9.3, 2.85))  # PWM

# 逆变器 -> 电机
arrow((10.7, 2.85), (11.8, 2.85))  # 三相电流

# 电机 -> Clarke (反馈)
arrow((13.2, 2.85), (14.2, 2.85))  # ia, ib, ic

# Clarke -> Park (反馈)
arrow((14.8, 2.35), (14.8, 1.8))  # i_alpha, i_beta

# Park -> 反馈到PI (误差)
arrow((14.8, 0.8), (14.8, 0.3))
ax.plot([14.8, 3.7], [0.3, 0.3], color='black', linewidth=1.5)
arrow((3.7, 0.3), (3.7, 1.5))  # iq_fb -> PI_q
arrow((3.7, 0.3), (3.7, 1.5))  # id_fb -> PI_d (实际分两路,此处简化)

# 标注信号名称
ax.text(2.1, 3.8, 'iq_ref', fontsize=8, color='blue')
ax.text(2.1, 1.7, 'id_ref', fontsize=8, color='blue')
ax.text(4.2, 3.1, 'Vq', fontsize=8, color='red')
ax.text(4.2, 2.3, 'Vd', fontsize=8, color='red')
ax.text(6.6, 3.0, 'Vα,Vβ', fontsize=8, color='red')
ax.text(8.8, 3.0, 'PWM', fontsize=8, color='red')
ax.text(11.0, 3.0, 'ia,ib,ic', fontsize=8, color='red')
ax.text(13.6, 3.0, 'ia,ib,ic', fontsize=8, color='green')
ax.text(15.0, 1.5, 'iα,iβ', fontsize=8, color='green')
ax.text(15.0, 0.4, 'iq,id反馈', fontsize=8, color='green')

plt.tight_layout()
plt.show()

验证路径

本案例为框图讲解,无代码执行。验证方式:对照框图,从电机端逆着信号流方向走一遍——采样ia/ib → Clarke → Park → 与给定比较 → PI → 反Park → SVPWM → 逆变器 → 电机,能完整说出每个环节的输入输出即视为掌握。