电励磁同步电机Python仿真:从变频启动到能耗制动全流程解析
2026/9/10 10:02:29 网站建设 项目流程

电励磁同步电机这东西,我前前后后折腾了大半年,确实比永磁电机有意思多了。永磁电机的磁场基本上是个“固定buff”,转子磁钢装上去就变不了,想玩点花活全靠定子电流折腾。但电励磁不同,转子磁场的强弱完全由励磁电流说了算,启动时可以调、制动时可以调、甚至正常运行时还能靠它调功率因数。这个自由度一旦打开,能玩出不少永磁电机根本做不到的操作。

而且这玩意儿有个特别“硬核”的性格:启动的时候脾气大,直接并工频电源经常给你表演一个原地抽搐,行业内管这叫“失步”或者“振荡”;但等它转起来稳定了,你要急停,把定子从电网断开接个电阻,它立刻变身成一个发电机,靠转子剩下来的动能发电,把能量硬生生耗在电阻上,转速咔咔往下掉。这种“同一台电机,两种身份切换”的过程,用Python撸一个仿真,从开机到刹车完整看一遍,比只看公式有意思十倍。

这个仿真适合谁用?搞电机控制的小白、想验证同步电机启动/制动策略的工程师、以及被Simulink许可证折腾到想换Python写原型的人。我用的办法很简单:把三相绕组的耦合关系变换到dq坐标系,状态方程用scipy的solve_ivp求解,控制逻辑做成时间分段,一次仿真把变频启动、稳态运行、能耗制动全部串起来。下面我把建模思路、参数选取、代码逻辑和踩过的坑从头到尾讲一遍。

1. 先卸下成见:电励磁同步电机凭什么比永磁好玩

1.1 磁场系统能“调”,这是玩出花样的根本

永磁同步电机转子上的磁钢在出厂那一刻,磁场强度就基本固定了。想要弱磁提速,只能往定子电流里塞负的d轴电流,把气隙磁场“压”下去。这招能用,但代价是发热大,而且磁钢本身有失磁风险,温度一高性能就会退化。

电励磁同步电机则完全不一样,转子磁场由励磁绕组和直流励磁电流共同决定。我从公式层面讲一下为什么这是一个“控制自由度”:电磁转矩在dq坐标系下表达为

T_e = 1.5 * p * (ψ_d * i_q - ψ_q * i_d)

其中转子磁链ψ_f = L_mf * i_f。因为i_f可以直接连续调节,所以气隙磁场是一个“实时可调变量”。在恒转矩区,你可以通过加大励磁电流提高单位定子电流的力矩输出;在高速区,你可以主动降低励磁电流来实现弱磁,而不用像永磁电机那样硬灌负d轴电流。

这个特性带来的实际好处很多。比如启动时可以让励磁电流渐进建立,避免转子磁场突然“砸”进气隙引发巨大冲击;制动时又可以让励磁保持不脱落,让电机稳定发电。仿真里这一条体现得特别明显:我在代码里把励磁电压设置为独立输入,所以在启动阶段能看到i_f从0上升的过程,这是永磁模型根本没有的状态变量。

1.2 启动会抽风:同步电机的经典难题

同步电机最著名的坏脾气就是“直接并工频电网启动容易抽风”。为什么?因为定子绕组接上50Hz工频电之后,瞬间产生的旋转磁场是以同步转速转动的。转子一开始静止,它的磁场和定子磁场之间存在一个不断变化的功角,产生的电磁转矩时而正时而负,平均值接近于零,转子很难转起来。尤其带着负载或者转子惯量很大的时候,电流会很大,转子却在原地剧烈振荡,这就是标题里说的“抽风”。

解决思路一般有两条路。一条是异步启动,在转子上加阻尼绕组,靠异步转矩先把转子拉起来,接近同步速后再牵入同步,这在很多工业大电机上还在用;另一条就是变频软启动,让定子旋转磁场的频率从0开始慢慢升,转子跟着磁场一起逐渐提速,中间不产生失步振荡。我在仿真里用的就是变频启动的思路,而且励磁从0开始建立,这样可以同时观察两个动态过程:励磁电流上升和转子转速跟随。

需要说明的是,变频启动的过程并不等于“无脑升频”。如果频率斜坡太陡,旋转磁场的加速度超过了电机能产生的加速转矩,转子就会跟不上,功角不断拉大,最后照样失步。真实项目中会设计加速度限制曲线,仿真里我定为2秒从0升到50Hz,算是比较温和的斜坡。

1.3 能耗制动:停机变成发电机运行

能耗制动是我个人觉得最有趣的一段。把同步电机定子从电网断开,然后在定子绕组上接一组三相电阻,同时保持励磁电流不断掉,这时候转子的机械能通过电磁感应,在定子绕组里感应出三相对称电动势,电流流过制动电阻,把动能变成热量,转子就被一个阻力矩拽住了。

能量流的方向在这里完全反过来了:原本电机从电网吸收电能,把电能转成机械能;制动时转子把动能转成电能,电能耗在电阻上。这就是“同一台电机瞬间变成发电机”的原因。能耗制动的好处是结构简单、低速时停车效果明显,尤其适合电机会被负载倒拖、需要快速准确停机的场合;缺点是能量全被浪费成热量了,比回馈制动的效率低,但胜在可靠、便宜。

仿真的关键时刻也正是这里。切换到制动模式后,定子电压方程里外接电源消失,取而代之的是制动电阻的端电压关系:u_d = -R_b * i_d,u_q = -R_b * i_q。转子转速越高,感生电流越大,制动转矩越大;随着转速降低,制动电流和转矩一起衰减。结果就是转速曲线呈现一个近似指数衰减的过程,不会像机械刹车那样“咣”一下停住,而是越到后面越温柔。

2. Python建模:从三相电机到微分方程

2.1 模型简化:用dq轴换掉三相绕来绕去的量

要让Python解同步电机的动态过程,直接把三相绕组的电压、磁链、互感全部展开,方程会非常啰嗦,而且数值求解容易出问题。更常规的做法是走Park变换,把三相静止坐标系里的量搬到一个和转子一起旋转的dq坐标系里。这样好处很明显:原本随时间周期性波动的三相电流,在dq坐标系下会变成近似直流量的id和iq,微分方程从一个“长周期振荡系统”变成更容易算的“准静态系统”。

我采用的模型把电机当作隐极机处理,即L_d = L_q = L_s。这样做有两个原因:一是代码简洁,电磁转矩表达变成T_e = 1.5 * p * L_mf * i_f * i_q,非常直观;二是对于凸极效应不明显的电机,误差在工程仿真范围内完全可以接受。如果你要仿真凸极同步电机,后续只需要把L_d和L_q拆开,再补一个磁阻转矩项1.5 * p * (L_d - L_q) * i_d * i_q进去就行。

状态变量一共有五个:定子d轴电流id、q轴电流iq、励磁电流if、机械角速度wm、机械角度thm。对应的微分方程如下:

di_d/dt = (u_d - R_s * i_d + ω_e * L_s * i_q) / L_s di_q/dt = (u_q - R_s * i_q - ω_e * (L_s * i_d + L_mf * i_f)) / L_s di_f/dt = (u_f - R_f * i_f) / L_f dω_m/dt = (T_e - B * ω_m) / J dθ_m/dt = ω_m

其中ω_e = p * ω_m,T_e = 1.5 * p * L_mf * i_f * i_q。这一组方程把整个电机的电磁和机械动态全包进来了,后续所有“好玩的事情”,包括变频启动时的功角变化、能耗制动时的能量消耗,都从这个方程组里跑出来。

2.2 参数怎么定:让仿真结果不脱离现实

参数太随意的仿真只是画个曲线做心理按摩。我用的电机参数是参考一台小功率同步电机放大简化出来的,核心原则是让额定电压、额定转速、励磁电流和转矩水平互相自洽。下表是我实际使用的参数:

参数数值说明
极对数 p2额定频率50Hz时同步转速1500r/min
定子电阻 R_s0.8 Ω定子铜耗相关
定子电感 L_s12 mH隐极模型,Ld=Lq
励磁电阻 R_f5 Ω励磁回路电阻
励磁电感 L_f0.5 H励磁时间常数0.1s
定励磁互感 L_mf0.25 H决定气隙磁场强弱
转动惯量 J0.1 kg·m²模拟负载轴系惯量
阻尼系数 B0.005 N·m·s摩擦与风阻
励磁电压 u_f25 V稳态励磁电流5A
制动电阻 R_b2 Ω能耗制动负载

这里有两个参数关系到“仿真是否真实”。第一个是励磁回路时间常数L_f / R_f = 0.1s,意味着励磁电流从0到5A需要大约0.5s左右才能基本稳定。启动的前0.5s里转子磁场其实还没有完全建立,所以电磁转矩是慢慢上来的,这个现象我在仿真结果里看得一清二楚。第二个是制动电阻R_b,它决定了制动初始电流的大小。R_b太小制动猛但容易过流,太大则制动拖沓,我选了2Ω,在额定相电压幅值310V下,初始制动电流被限制在几十安培级别,曲线比较典型。

2.3 全过程的控制切换:启动、稳态、制动

仿真不是从头到尾只有一个公式,而是要模拟一个完整工况:0到2秒变频启动,2到2.5秒稳定运行,2.5秒后切换能耗制动。这相当于一台实际电机控制器里的模式切换逻辑,只是我在Python里用时间判断临时拼了一下。

启动阶段,我让定子电压频率从0Hz线性升到50Hz,电压幅值也按比例从0爬到额定值,同时叠加一个5V的低频补偿,用来克服定子电阻压降。这一段的目的是让旋转磁场像一个“领跑员”一样带着转子从静止跑到同步转速。稳态阶段频率固定在50Hz,电压幅值限制在额定值附近,此时只有很小的空载电流和功率损耗。制动阶段把定子外接电压撤掉,改用“u_d=-R_bi_d、u_q=-R_bi_q”来模拟定子绕组接电阻的状态,励磁电压保持25V不断,让转子磁场在这段时间里继续担任“发电机励磁”的角色。

模式切换在代码里用函数mode(t)来判断,本质上就是一个简单的状态机。真正的电机控制里这套逻辑会用更严谨的“状态机+限幅保护”来做,但作为Python原型演示,这种写法足够清楚。

3. 核心仿真代码怎么一步步写出来

3.1 电机本体:solve_ivp解状态微分方程

整个仿真我用的是scipy.integrate.solve_ivp,相比自己写欧拉法或龙格库塔,它自带变步长和误差控制,遇到启动瞬间电流变化剧烈的时候不会轻易发散。电机本体的右侧函数负责把前面那组微分方程返回给求解器:

import numpy as np from scipy.integrate import solve_ivp import matplotlib.pyplot as plt p = 2 Rs = 0.8 Ls = 0.012 Rf = 5.0 Lf = 0.5 Lmf = 0.25 J = 0.1 B = 0.005 R_b = 2.0 V_f = 25.0 U_rate_amp = 380 * np.sqrt(2) / np.sqrt(3) f_rate = 50.0 T_ramp = 2.0 def electric_rhs(t, x): i_d, i_q, i_f, wm, thm = x u_d, u_q, u_f = control_voltage(t, x) we = p * wm di_d = (u_d - Rs * i_d + we * Ls * i_q) / Ls di_q = (u_q - Rs * i_q - we * (Ls * i_d + Lmf * i_f)) / Ls di_f = (u_f - Rf * i_f) / Lf Te = 1.5 * p * Lmf * i_f * i_q dwm = (Te - B * wm) / J dthm = wm return [di_d, di_q, di_f, dwm, dthm]

这里有一个很多人忽略的细节:定子电感L_s和励磁互感L_mf不是随便填的。启动瞬间电流变化率di/dt = u/L,如果L取得太小,比如1mH,那在额定电压下di/dt会大到离谱,步长被迫切得很小,求解速度慢还容易数值振荡。我用的12mH是一个比较折中的值,既能让动态清晰可见,又不会让求解器痛苦不堪。

3.2 坐标变换与变频启动逻辑

启动阶段最需要写清楚的其实是“三相电压怎么变成dq电压”。因为在转子dq坐标系下,外界输入是三相电压源,必须先做Park变换。这里最容易写错的就是θ_e和θ_r的差:θ_r是转子电气角度,等于p乘以机械角度,由机械角度状态变量不断积分得到;θ_e是定子电压相量角度,由频率积分得到。两者之间的差就是功率角的变化来源。

def ramp_freq(t): if t < T_ramp: return f_rate * t / T_ramp return f_rate def theta_e_ramp(t): if t < T_ramp: return 2 * np.pi * (0.5 * (f_rate / T_ramp) * t**2) base = 2 * np.pi * (0.5 * (f_rate / T_ramp) * T_ramp**2) return base + 2 * np.pi * f_rate * (t - T_ramp) def control_voltage(t, x): i_d, i_q, i_f, wm, thm = x theta_r = p * thm if t < 2.5: U_mag = U_rate_amp * (ramp_freq(t) / f_rate) + 5.0 U_mag = min(U_mag, U_rate_amp) te = theta_e_ramp(t) va = U_mag * np.cos(te) vb = U_mag * np.cos(te - 2 * np.pi / 3) vc = U_mag * np.cos(te + 2 * np.pi / 3) u_d = 2.0 / 3.0 * (va * np.cos(theta_r) + vb * np.cos(theta_r - 2 * np.pi / 3) + vc * np.cos(theta_r + 2 * np.pi / 3)) u_q = 2.0 / 3.0 * (-va * np.sin(theta_r) - vb * np.sin(theta_r - 2 * np.pi / 3) - vc * np.sin(theta_r + 2 * np.pi / 3)) else: u_d = -R_b * i_d u_q = -R_b * i_q return u_d, u_q, V_f

坐标变换里的系数2/3是幅值不变约束下的标准Park变换系数。如果你用功率不变约束版本,系数会变成sqrt(2/3),相应的电压、电流数值都会等比变化,但转矩最终结果一致。我习惯用幅值不变版本,因为直接在dq上对比电压幅值比较直观。

3.3 能耗制动和结果图形输出

把微分方程和控制逻辑接起来之后,一次完整仿真从0秒算到5秒,转速、电流、转矩曲线就都有了。我习惯把转速单位从rad/s转成r/min,电角速度和机械角度也顺手整理一下,然后画成三个子图:转速、电流、转矩,方便对照看物理过程。

t_span = (0, 5) x0 = [0.0, 0.0, 0.0, 0.0, 0.0] sol = solve_ivp(electric_rhs, t_span, x0, t_eval=np.linspace(0, 5, 10000), method='LSODA', rtol=1e-6, atol=1e-8) t = sol.t i_d = sol.y[0] i_q = sol.y[1] i_f = sol.y[2] wm = sol.y[3] speed = wm * 60.0 / (2 * np.pi) Te = 1.5 * p * Lmf * i_f * i_q fig, axs = plt.subplots(3, 1, figsize=(10, 8), sharex=True) axs[0].plot(t, speed) axs[0].set_ylabel('speed (r/min)') axs[1].plot(t, i_d, label='i_d') axs[1].plot(t, i_q, label='i_q') axs[1].plot(t, i_f, label='i_f') axs[1].set_ylabel('current (A)') axs[1].legend() axs[2].plot(t, Te) axs[2].set_ylabel('torque (N·m)') axs[2].set_xlabel('time (s)') plt.tight_layout() plt.show()

制动电阻的关系式u_d = -R_bi_d和u_q = -R_bi_q,我多说一句:这是从三相坐标系下u_a = -R_bi_a、u_b = -R_bi_b、u_c = -R_b*i_c直接Park变换过来的结果,不是拍脑袋近似。只要三相电流之和为零(无中线),这个dq形式就是严格成立的。

4. 从仿真结果看物理现象

4.1 启动过程:励磁建立、转速跟随、电流峰值

跑完仿真后先看转速曲线,前0.5秒转速爬得比较慢,这个现象值得多看一眼。原因不是电磁转矩不够,而是励磁电流还在建立阶段。我给的励磁回路时间常数是0.1s,理论上5倍时间常数也就是0.5s左右励磁电流才能到稳态值,所以在0.2秒时即使速度跟得上,转矩也非常小,差不多只有稳态的30%左右。

等到励磁电流基本建立,后面的启动就会顺利很多,转速曲线跟着频率斜坡一路爬升到1500r/min,不会出现剧烈的正负转矩交替。这是变频启动和直接并网最大的区别,转子不会像遇到一个“忽左忽右拉扯的对手”那样原地抽风。如果在仿真里把频率斜坡时间压缩到0.5s以下,你可能看到转速跟不上给定斜坡、功角持续拉大、q轴电流冲到很大甚至数值发散,这就是失步的“数值版”体现。

启动过程中的d轴电流和q轴电流都会有一个明显的峰值,这是电流在建立旋转磁场和稳定功角的过程中自然产生的。峰值电流的幅度和电压幅值、线圈电感、斜坡时间都有关系。如果你希望限制启动电流,可以在控制逻辑里加电流限幅:当iq超限时压低电压幅值,或者放缓频率斜坡,这是工程上更完整的做法。

4.2 制动过程:电感电流和能量消耗

切换到能耗制动之后,转速曲线最直观的变化是开始平滑下降。制动开始的一瞬间,因为转子转速还在1500r/min附近,感应电动势很大,所以定子电流会先冲出一个峰值。这里我用的制动电阻是2Ω,初始冲击电流不算特别夸张,但如果你把R_b设置成0.5Ω,电流峰值会成倍上涨,曲线会非常吓人。反过来如果把R_b调到20Ω,你就会看到转速下降明显变慢,因为制动转矩近似正比于磁链和电流,电流又被大电阻死死压住。

从能量角度讲,制动过程中转子动能全部转化成了定子绕组电阻R_s和制动电阻R_b上的热量。电机本质上就是一个临时运行的发电机,转子磁场的旋转切割定子绕组,产生感应电动势,电流把能量耗散掉。所以我在前面强调:能耗制动时励磁电源千万不能断。一旦励磁电流归零,转子磁场消失,定子感应电动势也就没了,制动转矩会直接掉到接近零,只剩摩擦慢慢把转速磨下来,这在实际设备里可能造成严重的安全隐患。

曲线里还有一个容易被忽略的细节:制动阶段的q轴电流是负的。原因很简单,原本电机运行模式下的q轴电流为“电磁转矩×速度”的方向,制动时转子还要继续转,但电磁转矩已经变为阻力矩,方向自然反了过来。这个负号在仿真代码里不是什么特殊设置,只要把定子电压换成电阻压降,方程自动就会解出这个负电流,物理上非常自洽。

4.3 踩坑记录与问题排查速查

仿真写多了就知道,这个模型看着简单,但实际运行起来的坑不少。我把自己调参过程中遇到的问题整理成了一张表,以后你自己跑的时候可以直接对照。

现象可能原因处理方式
启动阶段转速剧烈振荡频率斜坡太快,攻角拉大导致失步增加T_ramp,降低升频速度
启动电流峰值过大电压低频补偿给得太高,或Ls偏小降低补偿电压,适当增大Ls
制动时转速下降极慢制动电阻R_b太大,或者励磁电流太小减小R_b,确认V_f稳定保持
制动开始时电流尖峰巨大R_b过小,定子绕组过流增大R_b,或加入电流限幅
solve_ivp报错或步长过小参数不匹配导致高频数值振荡改用LSODA方法,提高rtol精度
励磁建立慢影响启动L_f/R_f太大减小L_f或提高V_f

这里特别要提一下数值求解器的选择。solve_ivp默认的RK45在很多分段切换模型里会频繁调整步长,遇到快速电流变化时效率不高。我实测下来method='LSODA'在这个模型上表现最好,它自动在刚性和非刚性之间切换,启动和制动这两个阶段都能稳定处理。如果你发现仿真跑到模式切换瞬间突然变得很慢,大概率就是求解器在硬啃一个快速动态过程,不要慌,等它冲过去就好了。

最后分享一个小技巧

如果你自己试着改参数,我建议第一个改的就是制动电阻R_b。把2Ω改成1Ω跑一遍,再改成4Ω跑一遍,对比转速衰减曲线,你会对“制动转矩感生电流决定”这句话有非常直观的体会。这个体验比读十遍公式都管用。

另外,能耗制动的仿真还能继续扩展。比如把励磁电压在制动时改成“先增磁再制动”,你会发现制动效果更强;或者把固定电阻换成可控斩波电阻,就是经典的动力制动斩波器思路了。这台电机的“可玩性”才刚刚打开,剩下的就看你能不能让Python陪你一起折腾下去了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询