2. 电流环带宽与PI参数关系仿真

任务目标

建立FOC电流环PI控制器模型,通过频域分析明确Kp、Ki与电流环闭环带宽的关系,并求解满足指定带宽(如1kHz)的参数组合。

核心原理

表贴式PMSM在d-q轴解耦后,电流环被控对象近似为一阶惯性环节:G(s) = 1/(Ls + R)。采用PI控制器C(s) = Kp + Ki/s时,电流环开环传递函数为:

Gol(s) = (Kp·s + Ki) / (s·(Ls + R))

令Kp = L·ωc,Ki = R·ωc(ωc为期望带宽角频率),可将开环传递函数零极点对消,得到闭环传递函数:

Gcl(s) = ωc / (s + ωc)

此时电流环等效为一阶低通滤波器,带宽fbw = ωc/(2π)与PI参数呈线性关系。本案例通过仿真验证该关系,并求解指定带宽下的参数。

仿真环境与依赖

  • Python 3.8+,需安装:numpy、matplotlib、scipy、control
  • 安装命令:pip install numpy matplotlib scipy control

关键完整代码

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
import control

# 电机参数(示例:小型PMSM)
L = 0.001  # 定子电感 1mH
R = 0.5    # 定子电阻 0.5Ω

# 指定目标带宽
f_bw_target = 1000  # 1kHz
wc_target = 2 * np.pi * f_bw_target

# 按零极点对消法计算PI参数
Kp = L * wc_target
Ki = R * wc_target
print(f"目标带宽: {f_bw_target} Hz")
print(f"Kp = {Kp:.4f}, Ki = {Ki:.1f}")

# 构建被控对象和控制器
G_plant = control.tf([1], [L, R])  # 1/(Ls+R)
C_pi = control.tf([Kp, Ki], [1, 0])  # Kp + Ki/s

# 开环与闭环传递函数
G_ol = control.series(C_pi, G_plant)
G_cl = control.feedback(G_ol, 1)

# 频域分析:计算闭环幅频响应
freq = np.logspace(1, 5, 500)  # 10Hz ~ 100kHz
mag, phase, omega = control.freqresp(G_cl, freq * 2 * np.pi)
mag_db = 20 * np.log10(abs(mag))

# 寻找-3dB截止频率(即带宽)
idx_3db = np.argmin(np.abs(mag_db + 3))
f_bw_actual = freq[idx_3db]
print(f"实测-3dB带宽: {f_bw_actual:.1f} Hz")

# 验证零极点对消后的等效一阶系统
G_equiv = control.tf([wc_target], [1, wc_target])  # wc/(s+wc)
mag_eq, _, _ = control.freqresp(G_equiv, freq * 2 * np.pi)
mag_eq_db = 20 * np.log10(abs(mag_eq))

# 绘制波特图对比
plt.figure(figsize=(10, 6))
plt.semilogx(freq, mag_db, 'b-', linewidth=2, label='PI控制闭环')
plt.semilogx(freq, mag_eq_db, 'r--', linewidth=2, label='理想一阶系统')
plt.axhline(-3, color='gray', linestyle=':', linewidth=1)
plt.axvline(f_bw_target, color='green', linestyle='--', label=f'目标带宽 {f_bw_target}Hz')
plt.xlabel('频率 (Hz)')
plt.ylabel('幅值 (dB)')
plt.title('电流环闭环幅频特性')
plt.legend()
plt.grid(True, which='both', alpha=0.3)
plt.xlim(10, 100000)
plt.ylim(-40, 5)
plt.tight_layout()
plt.savefig('current_loop_bode.png', dpi=150)
plt.show()

# 参数扫描:验证Kp、Ki与带宽的线性关系
print("\n--- 参数扫描验证 ---")
for f_bw_scan in [500, 1000, 2000, 4000]:
    wc_scan = 2 * np.pi * f_bw_scan
    Kp_s = L * wc_scan
    Ki_s = R * wc_scan
    C_s = control.tf([Kp_s, Ki_s], [1, 0])
    G_cl_s = control.feedback(control.series(C_s, G_plant), 1)
    mag_s, _, _ = control.freqresp(G_cl_s, freq * 2 * np.pi)
    mag_s_db = 20 * np.log10(abs(mag_s))
    idx = np.argmin(np.abs(mag_s_db + 3))
    print(f"目标: {f_bw_scan}Hz → Kp={Kp_s:.3f}, Ki={Ki_s:.1f} → 实测带宽: {freq[idx]:.1f}Hz")

运行方式

  1. 将上述代码保存为 current_loop_bandwidth.py
  2. 在终端执行:python current_loop_bandwidth.py

验证方法与判定标准

  • 参数计算验证:程序输出的Kp、Ki应满足Kp = L·ωc,Ki = R·ωc,且ωc = 2π×1000 ≈ 6283 rad/s,即Kp ≈ 6.283,Ki ≈ 3141.6
  • 带宽匹配验证:程序输出的"实测-3dB带宽"应接近1000Hz(误差<5%),证明零极点对消法正确
  • 波特图验证:生成的current_loop_bode.png中,蓝色实线(PI控制闭环)与红色虚线(理想一阶系统)应基本重合,绿色竖线(目标带宽)与-3dB交点对应
  • 线性关系验证:参数扫描结果中,目标带宽与实测带宽应近似一致(误差<5%),证明Kp、Ki与带宽呈线性比例关系

常见问题

  • 带宽偏差较大:检查电机参数L、R是否与实际一致;若L/R时间常数较大,需确认零极点对消条件成立
  • 高频段幅频曲线不重合:这是正常现象,因为实际系统在高频受采样延迟和PWM死区影响,本仿真未建模这些环节
  • 修改目标带宽:直接修改f_bw_target变量即可,程序会自动重新计算Kp、Ki并验证