4. PMSM电机模型实现:用Python实现电机电气方程与机械方程
好,咱们进入正题。
上一章我们聊了软件在环仿真的整体框架,这一章我带你亲手把PMSM的数学模型变成能跑的Python代码。说实话,电机模型是整个仿真系统的基石——模型不准,后面做啥控制都是白搭。我在项目里吃过这个亏,所以今天咱们把电气方程和机械方程拆开了揉碎了讲。
4.1 为什么是PMSM?
永磁同步电机(PMSM)现在太常见了。电动汽车、伺服驱动、机器人关节,到处都有它的影子。它的特点是:转子是永磁体,没有励磁绕组,所以效率高、功率密度大。
但它的数学模型比直流电机复杂不少。你想想看,三相交流电进去,转子还在转,这中间有坐标变换、有反电动势、有磁链耦合。嗯,咱们一步步来。
4.2 电气方程:dq坐标系下的电压方程
我个人习惯用dq坐标系来建模。为什么?因为把交流量变成了直流量,控制起来方便多了。Park变换和Clark变换是基本功,这里不展开,直接给结论。
在dq旋转坐标系下,PMSM的电压方程长这样:
v_d = R_s * i_d + L_d * di_d/dt - ω_e * L_q * i_q
v_q = R_s * i_q + L_q * di_q/dt + ω_e * (L_d * i_d + ψ_f)
其中:
v_d, v_q— d轴和q轴电压i_d, i_q— d轴和q轴电流R_s— 定子电阻L_d, L_q— d轴和q轴电感ω_e— 电角速度ψ_f— 永磁体磁链
关键点:这里的ω_e是电角速度,不是机械角速度。两者差一个极对数:ω_e = p * ω_m。我刚开始做仿真时经常搞混,结果出来的转速曲线怎么看怎么不对。
4.3 机械方程:转起来靠它
电机不光有电,还有机械运动。机械方程描述的是转矩和转速的关系:
J * dω_m/dt = T_e - T_L - B * ω_m
参数说明:
J— 转动惯量ω_m— 机械角速度T_e— 电磁转矩T_L— 负载转矩B— 阻尼系数
电磁转矩的计算公式:
T_e = 1.5 * p * (ψ_f * i_q + (L_d - L_q) * i_d * i_q)
对于表贴式PMSM(SPMSM),L_d = L_q,公式简化为:
T_e = 1.5 * p * ψ_f * i_q
说白了,转矩和q轴电流成正比。这也是为什么我们做矢量控制时,主要控制i_q的原因。
4.4 Python实现:从方程到代码
好,理论讲完了,咱们动手写代码。我习惯用面向对象的方式封装电机模型,这样后面做仿真时调用起来方便。
import numpy as np
class PMSM:
def __init__(self, params):
# 电气参数
self.Rs = params['Rs'] # 定子电阻
self.Ld = params['Ld'] # d轴电感
self.Lq = params['Lq'] # q轴电感
self.psi_f = params['psi_f'] # 永磁体磁链
self.p = params['p'] # 极对数
# 机械参数
self.J = params['J'] # 转动惯量
self.B = params['B'] # 阻尼系数
# 状态变量
self.id = 0.0
self.iq = 0.0
self.omega_m = 0.0
self.theta_m = 0.0
def update(self, vd, vq, TL, dt):
"""
更新电机状态
vd, vq: dq轴电压
TL: 负载转矩
dt: 仿真步长
"""
# 电角速度
omega_e = self.p * self.omega_m
# 电流微分方程(电气方程)
did_dt = (vd - self.Rs * self.id + omega_e * self.Lq * self.iq) / self.Ld
diq_dt = (vq - self.Rs * self.iq - omega_e * (self.Ld * self.id + self.psi_f)) / self.Lq
# 更新电流
self.id += did_dt * dt
self.iq += diq_dt * dt
# 电磁转矩
Te = 1.5 * self.p * (self.psi_f * self.iq + (self.Ld - self.Lq) * self.id * self.iq)
# 机械方程
domega_dt = (Te - TL - self.B * self.omega_m) / self.J
# 更新转速和位置
self.omega_m += domega_dt * dt
self.theta_m += self.omega_m * dt
return self.id, self.iq, self.omega_m, self.theta_m
我的小技巧:仿真步长dt不要设太大。我一般用1e-5到1e-4秒。步长太大,数值积分会发散,结果直接飞掉。步长太小,仿真跑得慢。你根据实际需求折中一下。
4.5 验证模型:跑一个空载启动
模型写好了,得验证一下。咱们来个最简单的场景:电机空载启动,看看转速响应。
# 电机参数
params = {
'Rs': 0.958, # 欧姆
'Ld': 0.00525, # 亨利
'Lq': 0.00525, # 亨利(表贴式)
'psi_f': 0.1827, # 韦伯
'p': 4, # 极对数
'J': 0.003, # kg·m²
'B': 0.0001 # N·m·s/rad
}
motor = PMSM(params)
# 仿真参数
dt = 1e-5
total_time = 0.5
steps = int(total_time / dt)
# 给定电压(开环)
vd = 10.0
vq = 10.0
TL = 0.0
# 记录数据
time = []
speed = []
for i in range(steps):
id, iq, omega_m, theta_m = motor.update(vd, vq, TL, dt)
if i % 1000 == 0: # 每1000步记录一次
time.append(i * dt)
speed.append(omega_m * 60 / (2 * np.pi)) # 转成RPM
# 打印最终转速
print(f"最终转速: {speed[-1]:.2f} RPM")
注意:开环启动时,如果电压给得太猛,电流会很大。我曾经有一次忘了限制电压,结果仿真电流飙到几百安培,虽然不会烧硬件,但仿真结果完全失真。建议加个电流限幅。
4.6 模型扩展:考虑饱和与温度
实际电机不是理想模型。温度高了,电阻会变大。电流大了,电感会饱和。如果你要做高精度仿真,这些都得考虑。
我常用的做法是:
- 电阻温度修正:
R_s(T) = R_s0 * (1 + α * (T - T0)) - 电感饱和:查表法,根据
i_d, i_q查对应的L_d, L_q - 磁链变化:温度升高,永磁体磁链会下降
这些扩展不难,就是在update()函数里加几个查表或计算步骤。但要注意,查表会拖慢仿真速度。如果你做实时仿真,得权衡一下精度和速度。
4.7 常见坑点总结
最后,我把自己踩过的坑列出来,你写代码时注意一下:
- 符号搞反:电压方程里
ω_e * L_q * i_q的符号,不同教材可能不一样。你得根据自己定义的dq轴方向来确认。 - 单位换算:电角速度和机械角速度别搞混。我见过有人直接用机械角速度算反电动势,结果模型完全不对。
- 数值稳定性:欧拉法简单,但步长大了容易发散。如果发现仿真结果震荡,试试减小步长,或者改用龙格-库塔法。
- 初始条件:电机启动时电流为0,但如果你直接给一个阶跃电压,电流会跳变。建议加个软启动,让电压慢慢上升。
好了,这一章的内容就到这。你把这个PMSM模型跑通了,后面做电流环、速度环仿真就有基础了。下一章咱们聊怎么用这个模型做闭环控制仿真。