搞电机控制的人迟早都会撞上那堵看不见的墙——基速。额定转速以内,电流和电压都宽裕,想怎么控就怎么控;可一旦用户甩过来一句“我要再快30%”,就会发现反电动势已经顶到逆变器能输出的最高电压,再往上提频率,电流环就开始往下掉,转矩跟着崩,严重一点直接过流炸模块。这时候几乎所有方案都会走到同一个屋子里:弱磁。
很多人一听“弱磁”两个字,第一反应是把磁铁弄没。实际当然不是这么玄,本质是在定子电流里注入一个和转子磁链方向相反的去磁分量,把气隙磁链“压”下去,给电压腾出空间,让电机在基速以上还能继续升速。这个操作说起来就一句话,难的是“这个去磁分量到底怎么算”。查表法标定量大,电压环PI法动态慢,而我今天要拆的,是思路最直接、代码最好落地的一种——直接计算法弱磁控制策略。
这篇文章会从电压极限的物理本质讲起,把直接计算法的数学推导一步步写清楚,再给出一套可以直接嵌进FOC中断里的C代码,最后聊聊实机调试时那些文档里不会写的坑:磁链温漂、母线电压跌落、PI退饱和、退出弱磁时的震颤。篇幅不短,但每一步都是能直接上机的干货。
1. 基速墙的本质:电压极限椭圆才是真正的天花板
1.1 从反电动势说起
永磁同步电机在dq同步旋转坐标系下的稳态电压方程是:
ud = Rs*id - ωe*Lq*iq uq = Rs*iq + ωe*(Ld*id + ψf)式中id、iq是直轴交轴电流,Ld、Lq是直轴交轴电感,ψf是永磁磁链,ωe是电角速度。低速时,电阻压降Rsid、Rsiq还占一定比例;到了高速弱磁区,电阻压降相比于反电动势项ωeψf和ωeL*i就小到可以忽略,工程上几乎都会把Rs丢掉,方程简化为:
ud ≈ -ωe*Lq*iq uq ≈ ωe*(Ld*id + ψf)注意看,这两项全都跟ωe成正比。转速每升高一点,ud、uq的幅值就跟着往上涨,而逆变器的输出电压能力是硬的物理约束:母线电压Udc就摆在那里,SVPWM线性调制区最多只能输出幅值为Udc/√3的相电压。超过这个值,你的调制波就会被削顶,电流波形畸变,谐波电流失控。这就是“基速墙”的来源——不是转矩不够,是电压真的不够用了。
1.2 电压圆是怎么画出来的
把上面两个电压方程平方相加,得到电压矢量幅值的关系:
ud² + uq² = ωe²[(Ld*id + ψf)² + (Lq*iq)²]如果要求电压幅值不超过逆变器最大输出umax,那么:
(Ld*id + ψf)² + (Lq*iq)² ≤ (umax/ωe)²这个式子在id、iq平面上画出来是一个椭圆。椭圆中心在(-ψf/Ld, 0),半轴分别是(umax/ωe)/Ld和(umax/ωe)/Lq。转速越低,椭圆越大;转速越高,椭圆越小,一路往里缩。只要电流工作点落在椭圆内部,电压就是够用的;一旦工作点跑到椭圆外面去了,电流环就心有余而力不足。
所谓弱磁,用几何语言说就是:转速升高导致椭圆收缩之后,把工作点拽回椭圆内。要做到这一点,最有效的方向就是让id变得更负。因为id负向增加会让(Ld*id + ψf)这一项变小——直轴磁链被“抵消”了一部分,uq随之降下来,电压圆内部的空间就回来了。这就是去磁的本质,也是“弱磁”这个名字的真正来源。
1.3 “直接计算法”要解决的核心问题
现在问题变得很具体:转速升到椭圆缩小到一定程度后,id指令到底该给多少?iq指令又该给多少?传统做法是加一个电压外环PI,把“电压误差”积分成额外id补偿量;直接计算法的思路则完全不同——既然电机模型摆在这里,电压极限的数学表达式也摆在这里,那就直接把方程解出来,让工作点一步到位落到约束允许的位置。
这个“位置”不是随便找个椭圆内的点就行。为了在基速以上还能保持输出能力,我们要让工作点同时踩在电流极限圆和电压极限圆上,这样本周期总共能用到的电压全部用完、电流也全部用完,才能在该转速下输出最大转矩。这才是“突破基速还能保持输出能力”的真正含义:电压受限了,但每一伏特、每一安培都不浪费。
2. 直接计算法的数学骨架:把电流极限和电压极限联立求解
2.1 表贴式电机的闭式解推导
先看最常见的表贴式永磁同步电机(SPMSM),Ld=Lq=Ls,此时电压极限从椭圆退化成圆,电流极限则是标准的电流圆:
id² + iq² = imax² (Ls*id + ψf)² + (Ls*iq)² = ρ²其中ρ=umax/ωe,量纲是磁链(Wb)。两个圆方程联立,可以直接消元。把第二个方程展开:
Ls²*id² + 2Ls*ψf*id + ψf² + Ls²*iq² = ρ²利用id²+iq²=imax²,第一项和最后一项合起来就是Ls²*imax²,于是:
Ls²*imax² + 2Ls*ψf*id + ψf² = ρ²整理一下,id的闭式解就出来了:
id* = (ρ² - ψf² - Ls²*imax²) / (2*Ls*ψf)iq跟着取电流圆上的剩余量:
iq* = ± sqrt(imax² - id*²)这个公式绝对是我个人认为弱磁策略里最漂亮的一个解析结果。不存在任何积分器、调节器、增益参数,每周期输入实时转速和母线电压,输出就是当前速度下“电压极限和电流极限同时满用”的最优工作点。这一行公式,就是直接计算法弱磁控制策略的核心玩法。
注意这个id的符号判定。低速时ρ很大,id算出来是正的,说明电压圆还没收缩到需要弱磁的程度,此时什么都不干,维持正常的MTPA指令(表贴式电机的MTPA就是id=0)。只要转速升高到id*变成负值,就说明进入了弱磁区,立刻让工作点跳到这个解析点。所以这个公式天然就带一个“进入判断”,不需要额外的切换条件。
2.2 一个具体参数下的计算示例
公式光摆出来不够直观,我带一组实际参数算一遍。假设一抬表贴式电机,Udc=310V,极对数p=4,ψf=0.055Wb,Ls=1.2mH,电流极限imax=15A。那么:
- umax = 310/√3 ≈ 179V
- 基速 ωe = 179 / sqrt(0.055² + (0.0012*15)²) ≈ 3091 rad/s,对应转速约7380rpm
- 目标转速拉到10000rpm时,ωe = 2π100004/60 ≈ 4188.8 rad/s
- ρ = 179 / 4188.8 ≈ 0.0427 Wb
- id* = (0.0427² - 0.055² - 0.018²) / (20.00120.055) ≈ -11.56A
此时iq* = sqrt(15² - 11.56²) ≈ 9.56A。跟基速时的iq=15A相比,转矩降到了约64%,但速度提了35%,功率基本保持住,这就是恒功率区的效果。再算一个极限:当id被压到-15A、iq=0时,转速极限ωe = 179/(0.055-0.018) ≈ 4838 rad/s,对应约11550rpm。超过这个速度连零转矩都维持不住,控制器应该直接限速。
这个例子告诉我们几个重要信息:弱磁不是无限度的,它受制于电流极限与磁链/电感的配合。ψf/(Ls*imax)这个比值决定了弱磁能力的上限,比值越小,能跑越高的转速,但代价是基速附近的转矩密度下降。选型的时候如果客户要求很高转速攀升比,电机本身的弱磁率就要足够大,光靠控制算法是帮不了忙的。
2.3 凸极电机怎么处理
内嵌式永磁同步电机(IPMSM)Lq>Ld,电压极限是个真正的椭圆,两个约束联立后方程不再有前面那种简单线性解,严格推导会得到一个含四次项的方程。工程上我通常不追求闭式解,而是做一个实时一维搜索。
思路很简单:固定id,从电压圆方程解出iq_voltage = sqrt(ρ² - (Ld*id+ψf)²)/Lq;再从电流圆解出iq_current = sqrt(imax² - id²)。两个iq都是id的函数,找它们在id负方向上的交点,就是同时满足两个极限的工作点。用一个for循环从id=0往负方向迭代,最多循环十来次,在当前Cortex-M级别的MCU上,每周期耗时也就是几个微秒:
float id_lo = -imax, id_hi = 0.0f; for (int i = 0; i < 12; i++) { float mid = 0.5f * (id_lo + id_hi); float iq_v = sqrtf(rho*rho - powf(Ld*mid + psif, 2)) / Lq; float iq_c = sqrtf(imax*imax - mid*mid); if (iq_v >= iq_c) id_hi = mid; // 电压圆还够大,弱磁可以再深一点 else id_lo = mid; // 电压圆不够大,需要往回退 }二分法每轮收敛一半区间,12轮精度足够。这篇后续代码以表贴式为主,但如果你在调IPMSM,把这个迭代块替换掉闭式解那行就行,其余框架完全通用。
3. 代码落地:在FOC中断里嵌入弱磁模块
3.1 模块接口设计
直接计算弱磁模块最好设计成独立的小单元,只跟电流环交换指令,不碰底层PWM和采样。我习惯这样组织数据:
typedef struct { float Ld; // 直轴电感 H,表贴式 = Ls float Lq; // 交轴电感 H float psif; // 永磁磁链 Wb float imax; // 电流极限 A(峰值) } MotorParam_t; typedef struct { uint8_t weak_enable; // 当前是否处于弱磁区 float id_ref; // 修正后的 d 轴电流指令 float iq_ref; // 修正后的 q 轴电流指令 float rho; // 电压圆半径,磁链量纲 Wb float umax; // 实际使用的电压极限 V } WeakMag_t;接口按“输入电角速度、母线电压、当前MTPA指令,输出弱磁修正后的指令”这种思路来。注意一点:电流变量全程使用峰值约定,且与Park变换采用等幅值形式。很多弱磁公式在非等幅值变换下系数完全不同,代码移植时先确认约定再套公式,否则算出的id能偏出一倍。
再看逆变器电压极限。SVPWM在线性调制区输出最大相电压幅值是Udc/√3,这是弱磁设计里最安全、最保守的取值。如果用了过调制,母线电压利用率能再往上凑一点,但谐波和PI调节难度都会上去。我的习惯是弱磁基准始终以Udc/√3为准,宁可留一点电压裕度也不要让电流环在非线性区磨。这个选择在后面讲母线电压跌落时还会提到。
3.2 解析弱磁核心函数
核心计算函数就这么一点,直接把它挂在速度环或者电流环中断里,每周期调用:
void weak_mag_compute(MotorParam_t *motor, WeakMag_t *wk, float we, float id_mtpa, float iq_mtpa) { if (we < 1e-3f) we = 1e-3f; // 防止除零 wk->umax = motor->Udc * 0.57735027f; // 采样值经过滤波后使用 wk->rho = wk->umax / we; float rho2 = wk->rho * wk->rho; float psif2 = motor->psif * motor->psif; float lim = motor->Ld * motor->imax; float id_w = (rho2 - psif2 - lim * lim) / (2.0f * motor->Ld * motor->psif); if (id_w >= 0.0f) { // 电压空间足够,未进入弱磁区,直接透传 MTPA 指令 wk->weak_enable = 0; wk->id_ref = id_mtpa; wk->iq_ref = iq_mtpa; } else { // 进入弱磁区,以解析点为基准 wk->weak_enable = 1; float id_ref = id_w; if (id_ref < -motor->imax) { id_ref = -motor->imax; // 电流极限兜底 } wk->id_ref = id_ref; float iq_max = sqrtf(motor->imax * motor->imax - id_ref * id_ref); wk->iq_ref = (iq_mtpa >= 0.0f) ? iq_max : -iq_max; } }这段代码本身没什么花活,该算的都算了,该判的也都判了。不过直接这么扔进工程里,跑起来大概率会在基速附近抖得像筛子。问题出在哪?出在三个地方:id指令跳变、退出弱磁时的切换震颤、以及电流环赶不上参考导致的电压饱和。下面逐个解决。
3.3 限幅、平滑与切换保护
第一个问题是斜率。弱磁解析公式算出的id_ref是目标值,但电流环跟踪需要时间。如果上一周期id还是0,这一周期直接给-8A,电流环无论如何都会在瞬间饱和。更麻烦的是退出弱磁时,id_ref跳回0,电磁转矩瞬间恢复一大截,整个机械系统会像被踢了一脚。所以id指令变化必须加平滑。
工程上的标准做法是一阶低通或者斜坡限速。我习惯用一阶低通,系数根据速度环执行周期选。如果弱磁计算放在1kHz速度环里执行,alpha取0.05左右比较稳;放在10kHz电流环里执行,alpha可以取0.01到0.02。核心代码如下:
// 一阶低通平滑,alpha 依执行频率选取,值越小越平滑 wk->id_ref += alpha * (id_target - wk->id_ref); // 为保证电流幅值不超限,iq 与 id 联动 float iq_allowed = sqrtf(motor->imax * motor->imax - wk->id_ref * wk->id_ref); wk->iq_ref = (iq_mtpa >= 0.0f) ? iq_allowed : -iq_allowed;注意这里把id和iq绑定在同一个电流圆上:id变了,iq跟着变,而不是让iq保持原值。这种做法能保证任何时候电流幅值都不越界,但代价是转矩和速度之间存在耦合。弱磁区的动态响应天然比恒功率区慢,这是物理约束,滤波只是让它别抖。
第二个问题是基速附近的反复横跳。id_w在0附近小幅波动时,弱磁标志位可能一会儿置1一会儿清0,系统会周期性地切入切出。我的对策是加一个小的滞环:id_w小于-0.5A才进入弱磁,id_w大于+0.5A才退出,避免在临界点上来回切换。
3.4 与电流环PI的配合(抗积分饱和)
弱磁区最容易埋的雷是电流环PI积分饱和。想象一下:id指令忽然变到-10A,但逆变器电压已经满了,实际id根本充不到这么负,PI积分器发现误差一直在,持续往上积分,最后积分器顶到上限位置。等到转速稳定或指令回调时,积分器要从很深的位置慢慢退出来,这段时间内电流环会有一个大超调,甚至直接触发硬件过流保护。
处理办法没有银弹,但有两板斧很有效。第一板斧是给电流环PI的积分器设一个与工况相关的动态上限。比如iq环的piout限幅值,在弱磁区不要给满,留出20%的裕量给d轴电压,因为弱磁区ud和uq都要占用电压矢量的空间。第二板斧是在弱磁模块里直接监视uq、ud的幅值,一旦发现电压参考值接近umax且长时间无法跟踪参考电流,就把对应电流环PI的积分器清零或缩半。这个动作比任何参数调整都更能救场。
4. 从仿真到实机:参数漂移、母线电压与退磁风险
4.1 永磁磁链的温度漂移
直接计算法有一个绕不过去的软肋:它吃参数。公式里的ψf和Ld一旦跟实际电机不符,算出来的id_ref就偏。
最典型的是ψf随温度漂移。钕铁硼永磁体的剩磁温度系数大约是-0.12%/K,常温25℃标定的ψf,到90℃可能已经跌了8%。偏小8%意味着什么呢?带入id*公式看,ρ²和ψf²相减,ψf实际变小,公式用大的ψf算出来的id会更深。这个方向是偏保守的,不会立刻出大问题,但会白白牺牲转矩和功率。反过来最怕的是低温大电流场景,ψf标定值偏低,算出的id不够负,电压压不住,电流环失控转速上不去。
所以凡是做产品,我都会在代码里加一个简单的温度补偿表。测功台标定出ψf随绕组温度的变化曲线后,用一个查表加插值的方式实时修正ψf。没有温度传感器的话,至少要留一个参数辨识口,用电机停机状态的直轴电感测量或在线磁链观测器做一个慢速校准,别让ψf就这么死板地躺在常量里。
4.2 母线电压波动必须实时采集
另一个坑是Udc。前面代码里我专门写了注释:“采样值经过滤波后使用”。这不是废话,是血泪教训。
急加速时母线电容上的电压会明显跌落,某些恶劣工况能掉10%以上。如果你在弱磁计算里用固定的310V,而实际母线只剩280V,那么实际电压圆比计算用的电压圆小一圈,电流环在弱磁区会持续追不上参考,表现出来就是电机一顿一顿、转速波动,严重时触发母线欠压保护。
对策很简单:每个控制周期直接采样Udc,做一阶低通滤波后喂给weak_mag_compute。滤波时间常数不要太大,几毫秒量级就够——太慢了反而跟不上母线动态,最好跟电流环采样频率匹配。用实时Udc算出umax,电压圆半径自然跟着收缩膨胀,系统运行点就会自动适应母线波动。
4.3 实机调试时怎么观察弱磁是否正常
有示波器在手的时候,我一般分三步确认弱磁状态。
第一步,看电压幅值。进入弱磁区后,ud²+uq²的合成电压幅值应该稳定贴在umax附近,像电流环在“顶”着电压天花板走。如果电压明显低于umax,说明id_ref给深了,白白损失了转矩;如果电压高于umax,那说明指令已经超出逆变器能力,电流波形里一定有割顶畸变。
第二步,看id和iq的轨迹。在id-iq平面上,工作点应该沿着电流圆和电压圆的交点走。转速越高,id越负,iq越小。如果看到id大幅振荡而不是平滑加深,优先检查平滑系数和电流环带宽是不是不匹配。
第三步,关键时刻做一次阶跃加速,观察转速过冲。弱磁区动态响应慢是物理特性,但过冲过大说明切入动作太生硬。此时把平滑alpha调小,或者把切入的滞环窗口调大,转速曲线就会漂亮很多。
实机还有一个比较隐蔽的现象:机械振动导致角度编码器误差,会让坐标变换里的dq轴“虚转”,表现为弱磁区id、iq均值正常但波形上叠加明显的交流纹波。这种情况控制算法怎么改都没用,先把角度采样和机械装配问题解决。
4.4 直接计算法、电压环PI、查表法怎么选
这套直接计算法不是万能的,实际产品里三种弱磁路线各有位置,我列一个对比表:
| 方案 | 参数依赖 | 动态响应 | 标定工作量 | 适用场景 |
|---|---|---|---|---|
| 直接计算法 | 高,依赖ψf/Ld精度 | 快,理论上无延迟 | 低,公式即轨迹 | 参数已知、需要对阶跃响应快的驱动器 |
| 电压环PI法 | 低,对参数漂移不敏感 | 慢,受PI带宽限制 | 低,但要调多组PI | 参数可能漂移的通用变频器 |
| 查表法 | 无,直接查表 | 快,无在线计算 | 极高,全工况标定 | 量产车载驱动、控制芯片没余量的场景 |
个人经验是:先分清你到底怕不怕参数漂移。如果电机跟驱动器是固定搭配,电机本体参数有铭牌可查,那直接计算法性价比最高,代码干净、响应快、还可以跟在线参数辨识结合起来实时更新ψf。如果是通用型驱动器,今天带这个电机明天带那个电机,参数漂移幅度不可控,那用电压环PI法更稳妥,毕竟它不跟你较真电机模型。
查表法的场景是那些死磕效率和NVH的车载项目,全套标定做下来虽然贵,但能保证所有工况下轨迹最优,直接计算法求的是“两个极限圆交点”,在某些低电感高凸极比的电机上,这个点跟严格的MTPV轨迹还有一点差距,要求极限性能的话需要用更精细的迭代。
最后再分享一个实用小技巧。直接计算法最容易给人惊喜的地方,是它可以当“前馈”跟电压环PI法混着用——用解析公式算出一个基础的id_ref作为前馈,再用电压误差PI做增量补偿。这种混搭既保留了直接计算法的快速性,又用PI吸收了参数偏差异带来的稳态误差,是我做某些要求高动态响应的驱动器时最常用的最终方案。如果你正在被弱磁区的动态响应折磨,可以先试这个方向。