1. 内容整体设计与思路拆解
做感应电机故障检测的仿真,很多人第一步就栽在思路上——上来就急着搭模型、敲代码,结果后面的路越走越乱。我在带项目的时候,经常看到有同学把电机模型搭得花里胡哨,但故障特征根本提取不出来,原因就是整个仿真的底层逻辑没理顺。
1.1 为什么选 Matlab/Simulink 这条仿真路线
感应电机故障检测,本质上做的是“信号采集—特征提取—状态判别”这么一条链路。如果在真实电机上做实验,成本高、周期长,而且故障复现非常麻烦——定子绕组匝间短路一旦操作不当,电机当场就烧了。相比之下,Matlab/Simulink 这种图形化建模环境有天然的工程落地优势。
一大好处是电机本体模型可以直接用模块搭建,不需要手写微分方程组。Simulink 里内置了异步电机模块,拖出来填参数就能跑;还可以配合 Simscape 电气模块做更精细的非线性建模。另一大好处是故障注入非常灵活——既可以在电路层面人为改变阻抗参数来模拟绕组短路,又可以通过信号层面叠加特征谐波来模拟轴承磨损,这种“污染-重建”的灵活性,仿真环境天生就有。
我一个很强烈的体会是:Simulink 特别适合做“特征互动”分析。比如互调效应——定子短路加转子断条同时发生时,特征频率并不是简单叠加,而是会出现和差频率成分。这种复杂的耦合效应,在真实实验中极难主动制造,但在仿真模型里可以精确控制故障程度和注入时刻,把特征耦合的过程一步步拆开看。
1.2 整体方案的核心流程拆解
整个仿真方案,我习惯画成五个环节来推进,每个环节负责一个明确的可交付物:
| 环节 | 核心任务 | 交付物 |
|---|---|---|
| 电机建模 | 搭建感应电机的电气-机械耦合模型 | 转速、转矩、三相电流输出 |
| 故障注入 | 在不同位置设置故障参数或信号源 | 故障状态下的电流/振动信号 |
| 数据采集 | 设计采样率、采样时长、数据导出通道 | 结构化数据集(时间×三相电流等) |
| 特征提取 | 对信号做频谱分析和特征参量计算 | 特征频率幅值、相位差、能量占比 |
| 故障判别 | 基于阈值或分类器输出诊断结论 | 故障类型、严重程度 |
这里最关键的,也是我踩过最多坑的一点:故障信号的数据量一定不能省。很多人搭完模型,仿真时间只跑 0.1 秒,FFT 的频率分辨率根本不够,故障特征频率和基波频率差不了几 Hz,谱上糊成一团,啥都看不清。这一环节直接决定后面所有工作的成败。
2. 仿真环境搭建与电机模型构建
2.1 MATLAB/Simulink 环境准备
环境准备看起来是件简单事,但细节上确实有些讲究。首先是版本选择——R2020b 之后 Simulink 的异步电机模块参数界面变化比较大,如果你参考的是老教材上“Machines”库截图,可能对不上号。我自己用下来,比较稳定可靠的组合是 MATLAB R2022a 搭配 Simulink + Simscape Electrical,这套组合对电机模型的参数化支持已经非常成熟。
其次是工具箱。你要确保安装了以下功能组件:
- Simulink:核心环境,跑模型必备。
- Simscape Electrical:里面的 Specialized Power Systems 库自带异步电机模型。
- Signal Processing Toolbox:后面做 FFT、功率谱分析要用到。
- Statistics and Machine Learning Toolbox:如果计划做分类器对比,这个必须有。
这里有一个很实用的技巧:在命令行窗口输入powerlib,可以打开电力系统模块库浏览器,新版 MATLAB 会直接弹出来一个分类清晰的库面板。我刚接触的时候傻乎乎地在 Simulink 库浏览器里一个个翻,找了半天也没找到异步电机模块,后来才意识到直接输入命令才是最快的方式。
2.2 感应电机模型的核心原理
感应电机的数学模型,说白了就是一组电压方程加磁链方程,再加上电磁转矩和机械运动方程。稳态下可以用等效电路来分析,但做故障检测必须用动态模型,因为你关心的是电流波形上的谐波畸变,那是在瞬态过程中体现出来的。
dq 坐标系下的电压方程是这样的(我写成 Simulink 模块配置时看得最顺眼的形式):
uds = Rs * ids + d(fluxds)/dt - w * fluxqs uqs = Rs * iqs + d(fluxqs)/dt + w * fluxds这个方程组在 Simulink 里不需要你亲手搭——直接用Asynchronous Machine SI Units模块就行。但你必须理解 dq 变换的意义:三相交流量通过 Park 变换落到旋转坐标系下,会变成直流量,这样控制和分析都简单得多。故障检测时用的“信号特征频率”,转换到 dq 坐标系下仍然会体现为特定频率的脉动,这一点在做故障特征分析时千万别搞混。
2.3 参数设置与额定工况确定
我以一台上电星形连接的 7.5 kW 感应电机为例,常用参数如下:
| 参数项 | 数值 | 备注 |
|---|---|---|
| 额定功率 | 7.5 kW | 常见工业小功率 |
| 额定电压 | 400 V | 线电压有效值 |
| 额定频率 | 50 Hz | 电网工频 |
| 定子电阻 Rs | 0.7384 Ω | 实测或查手册 |
| 转子电阻 Rr | 0.7402 Ω | 已折算至定子侧 |
| 定子漏感 Lls | 0.003045 H | —— |
| 转子漏感 Llr | 0.003045 H | —— |
| 互感 Lm | 0.1241 H | —— |
| 转动惯量 J | 0.0343 kg·m² | —— |
| 极对数 p | 2 | —— |
仿真时电机通过三相断路器接入 380V/50Hz 电源,负载转矩设定为额定转矩的 80%,启动过程大概 1.5 秒稳定。这个参数组合里有一个关键点——互感 Lm 一定要填准,它决定了励磁电流的大小,进而影响定子电流的整体幅值。我见过有人把 Lm 填小了一个数量级,仿真出来的电流偏大 4 倍不止,后面做故障特征分析,基波幅值本身就错了,还找半天原因。
3. 故障注入与信号采集设计
3.1 典型故障的建模方式
这是仿真搭建之旅中最核心的环节。我要给你拆四种最常见的感应电机故障,以及它们在 Simulink 里的实现思路。
定子绕组匝间短路是最常见的故障类型,约占电机故障的 30%。建模思路是在电机定子某一相绕组上并联一个小阻抗支路,相当于短路了一部分匝数。Simulink 里可以通过三个单相变压器来模拟三相绕组抽头,然后在抽头位置接一个可变电阻和电感。短路匝数占比控制在 3%~15% 之间,比例再大电机会直接过流跳闸。
转子断条故障的建模思路是改变转子电阻的对称性。正常电机的三相转子电阻是平衡的,发生断条时,故障相的等效电阻会比另外两相大 1.5~2 倍。在 Simulink 的转子电阻参数里,可以设置为分段函数,用阶跃信号在指定时刻把其中一相电阻拉高。
轴承故障的特征是会在定子电流中感应出特定频率的谐波。这个不需要改变电机参数,更简单的做法是在电流测量信号后加法器,注入对应频率的正弦波。轴承外圈故障特征频率约为f_v = f_r * 0.4 * N_b,其中 N_b 是滚动体个数。举个例子:转速 1450 rpm(转频约 24.2 Hz)、滚动体 9 个时,外圈故障频率约 87 Hz。在基波电流上叠加这个频率的小幅值正弦成分,就模拟出了轴承早期故障信号。
气隙偏心故障和轴承故障类似,特征频率是转频的多倍与电网频率的调制组合。这里也直接用信号注入法,叠加到电流波形上。
3.2 故障注入点的设计原则
在模型里放故障注入点,要遵循一个原则:尽量在电气层面做,不要只在信号层面做。为什么这么说?信号层面叠加谐波,虽然省事,但忽略了故障对电机电磁场的反馈影响,比如定子短路不仅产生负序电流,还会导致转矩脉动,进而引起转速波动,又反过来影响电流波形。电气层面做故障注入,这种“故障-响应”的闭环耦合关系就能真实再现。
当然,纯电气层面建模也有两难:Simulink 自带的异步电机模块内部结构是封装好的,没法直接改三相绕组间的短路连接。我的做法是混合方案:
- 定子绕组短路:用外接阻抗回路 + 单相变压器抽头模拟。
- 转子断条:改转子电阻参数 + 阶跃信号触发。
- 轴承故障 / 气隙偏心:信号注入法。
这样既保住了电气耦合的核心故障,又能在特征阶段精确控制注入谐波的幅值频率,两边的好处都占了。
3.3 数据采集与采样设置
采集环节容易被低估,这里我给出我实测稳定的配置:
% 仿真参数设置 sim_time = 5; % 仿真时长 5 秒(含启动 1.5 秒) sample_rate = 10000; % 采样率 10 kHz sample_time = 1/sample_rate;仿真结束后把电流信号导出到工作区。这里有一条核心经验:稳态分析前必须截去启动过渡段。电机直接启动的瞬态电流可以达到额定电流的 6~8 倍,这段数据如果不剔除,频谱分析里全是巨大的低频分量,故障特征频率被压得完全看不出来。我的做法是在采样脚本里用条件表达式把仿真时间大于 2 秒的数据才存下来。
% 信号采集后处理 t = simout.time; ia = simout.signals.values(:,1); mask = t >= 2.0; % 去掉前 2 秒启动过程 t = t(mask); ia = ia(mask);要注意的是一个叫“警报器”的坑。Simulink 里一排 Scope 模块,看起来输出的波形都对,但导出到工作区后时间轴对齐错位。我后来统一用带Time Vector输出的To Workspace模块,把所有信号挂到同一个时钟上,问题才彻底解决。
4. 信号处理与特征提取
4.1 电流信号预处理
原始电流信号一上来不能直接做频谱分析。先做均值去除——因为电流波形里有直流偏置,直接做 FFT 会在零频处产生一个巨大的尖峰,而且会影响低频段的分辨率。去除方法很简单:
ia = ia - mean(ia);然后做带通滤波。电网频率 50 Hz,基波分量幅值很大,但我关注的故障特征频率主要集中在 0~500 Hz 这个频段,所以用了一个五阶巴特沃斯带通滤波器,上下截至频率分别设为 5 Hz 和 600 Hz。这个滤波器的关键参数我用designfilt来生成并观察幅频响应曲线后确认:
filt = designfilt('bandpassiir', ... 'FilterOrder', 5, ... 'HalfPowerFrequency1', 5, ... 'HalfPowerFrequency2', 600, ... 'SampleRate', 10000); ia_f = filtfilt(filt, ia); % 零相位滤波,避免相位偏移filtfilt做零相位滤波,能避免相位偏移对后面相位特征计算的影响。这一点小而关键——我踩过一次用普通filter滤波的坑,做完后信号相位整体偏移了,基于相位差做故障判别时完全出错。
4.2 频谱分析与特征频率识别
预处理完,用 Welch 功率谱密度估计来提取频谱。选 Welch 而不是直接 FFT 的原因是:它能把长信号分段加窗后平均,显著降低频谱噪声,让特征峰更突出。
[pxx, f] = pwelch(ia_f, hann(4096), 2048, 4096*2, 10000);这里有几个设置讲究:
- 窗长选 4096 点,对应时间分辨率 0.4096 秒,频率分辨率约 2.44 Hz。这个分辨率对故障检测来说比较合适——转子断条特征频率与转频差值通常在 2~5 Hz 之间,分辨率再粗就分不出来了。
- 重叠率选 50%,即 2048 点,保证频谱平滑效果,又不至于过度平滑把窄带特征抹掉。
- DFT 点数设为窗长的 2 倍(8192 点),做零填充,让频谱看起来更细腻。
画出频谱后,怎么判断有没有故障?我的经验是先看基波频率(50 Hz)附近的边频带。定子绕组短路时,会在基波两侧产生 ±100 Hz 的边频;转子断条时,产生 (1±2s)f 频率的边频分量,其中 s 是转差率。用上面参数算一下:转差率约 0.033,断条故障特征频率为 (1-2×0.033)×50 = 46.7 Hz 和 (1+2×0.033)×50 = 53.3 Hz。这两个边频和基波的频率差只有 3.3 Hz,所以频率分辨率必须足够小。
4.3 特征参数的选取与计算
单纯看频谱峰值不够,我建议提取一组多维特征参数,方便后面做阈值判别或机器学习输入:
基波幅值 I1:反映负载和整体工况。
负序分量幅值 I2:三相电流做对称分量变换,取负序部分的均方根值。定子绕组短路时负序分量显著增大。
特定边频带能量比:把 (1±2s)f 附近 ±1 Hz 范围内的功率谱密度积分,除以基波频段积分,得到一个无量纲比值。这个比值对转子断条非常灵敏。
零序分量幅值:零序电流在定子短路时会显著增加,但健康状态下应该接近零。
计算负序分量需要把三相电流通过对称分量变换矩阵:
% 对称分量变换 a = exp(1j * 2 * pi / 3); T_inv = 1/3 * [1 1 1; 1 a a^2; 1 a^2 a]; ABC = [ia_f, ib_f, ic_f]; seq = T_inv * ABC.'; % seq(1)零序, seq(2)正序, seq(3)负序 I_neg = rms(abs(seq(3,:)));这组特征在工程上非常经典:负序分量对定子故障敏感,边频能量比对应转子故障,两者联合基本能做到故障类型的初步区分。
5. 故障检测算法搭建与结果分析
5.1 基于阈值判别的诊断规则
拿到特征参数后,第一步建议用阈值规则做快速判别,它的特点是逻辑透明,方便排查验证。我自己的经验总结出四层判断规则:
- 负序幅值 I2 大于健康基线均值加 3 倍标准差,判为定子故障候选;
- 边频能量比 R_sideband 大于阈值 0.02,判为转子故障候选;
- 若两个指标同时超标,进一步检查零序幅值,排除两者同时发生的可能;
- 若所有指标都在正常范围内,判为健康状态。
阈值不能拍脑袋定。健康状态下的仿真需要跑 20 次不同负载水平,把这个条件下的特征均值取好,再算标准差,然后按“均值 + 3σ”来定阈值。我一开始拍脑袋设了个 0.05 的边频能量比阈值,结果转子轻度断条(断 1 根)时的特征值只有 0.035,白白漏报了一次故障,后来改成统计基线的“3σ”原则才算靠谱。
5.2 信号级交互界面设计
做仿真不能只自己能看到结果。我搭建了一个简单的交互界面,通过 App Designer 把三段核心功能串起来:
- 故障类型选择下拉框(健康 / 定子短路 / 转子断条 / 轴承故障);
- 故障严重程度滑块(比如短路线匝占比 3%~15%,断条数 1~3 根);
- 一键仿真按钮,联动 Simulink 模型运行并自动回传特征参数。
这个界面的价值不是炫技,而是批量化做故障灵敏度分析。比如我想知道转子断条 1 根和断 2 根时,边频能量比会有多大差异,只需要滑块拖两次,跑出来的数据自动记录在表格里。这种做法比改一次参数跑一次模型效率至少提升 5 倍。
核心按钮的回调函数逻辑大致是这样:
% 按钮回调:运行仿真 function run_sim(app) set_param('motor_fault_model', 'StopTime', '5'); % 把界面参数传到模型工作区 assignin('base', 'fault_type', app.FaultTypeDropDown.Value); assignin('base', 'severity', app.SeveritySlider.Value); sim('motor_fault_model'); % 调用特征提取脚本 extract_features; % 更新结果显示 app.MeanNegLabel.Text = num2str(features.I_neg); end界面上同时绘制三相电流波形和频谱图,每次仿真结束自动刷新。这种“改参数-看结果”的循环方式,强烈建议保留,它让分析思路和模型结构彻底分离开,改参数不再意味着动模型。
5.3 结果可视化的呈现技巧
Simulink 自带 Scope 适合看时序波形,但做故障检测分析,我更推荐把数据拉到 MATLAB 脚本里统一出图。一图三行布局是我常用的呈现方式:
第一行显示三相电流随时间变化;第二行显示电流频谱(重点关注特征频率附近区间的放大视图);第三行显示特征的二维散点图,比如负序幅值对边频能量比,不同颜色代表不同故障类型。
数据可视化有一个我反复踩坑得来的经验:放大区间一定要标得足够清楚。比如转子断条的 46.7 Hz 特征频率,如果不设置 xlim 到 [40, 60],那么整张频谱图上它的峰值和基波峰比起来微不足道,肉眼根本看不出来,别人看图也找不到重点。我每次都会在图标题里把特征频率的理论值和实测值同时标出来,差异一目了然。
figure; tiledlayout(3,1); % 第一行 电流波形 nexttile; plot(t, ia_f); xlim([2,2.2]); % 第二行 频谱 nexttile; plot(f, pow2db(pxx)); xlim([0,200]); grid on; xline(46.7, '--r', '故障特征频率 46.7Hz');6. 常见问题与排查技巧实录
6.1 仿真速度慢到怀疑人生
仿真跑 5 秒,实际要等十几分钟,这个问题我见了太多回。第一排查点是powergui模块的仿真类型设置,如果你用的模块库是 Specialized Power Systems,必须把求解器设置为离散模式(discrete),步长设 1e-5 秒,而不是默认的连续模式。连续模式下 Simulink 要解刚性微分方程,步长自适应会频繁降到极小值,速度自然提不起来。
第二个排查点是信号数据存储。我见过模型里连了十几个 Scope,每个 Scope 都在以最高仿真步长记录全波形数据,这相当于每个信号都在写硬盘,速度能快才怪。统一改用To Workspace模块加降采样处理,只在需要分析的时刻(比如稳态区间 2~5 秒)记录数据,仿真速度立竿见影。
还有一个容易忽略的:Simulink 模型在回环运行时,工作区变量会不断累积,多次仿真后内存里堆了大量历史数据。每次sim()后执行一次clear关键变量,能省不少内存开销。
6.2 数据对不齐:采样时间冲突
有一次我同时用 10 kHz 采样率的电流采集模块和 100 Hz 的控制信号模块,最后导出的两路数据点数不同,时间序列没法对齐。原因很简单:不同模块的采样率不一致,输出到工作区的时间向量长度不同。
解决思路有两个:第一,所有数据记录模块统一用同一个采样时间,我常用 10 kHz;第二,如果确实有不同采样率的需求,用resample函数在离线阶段把数据统一到同一时间轴。需要注意,resample可能会导致边界效应,前后各截掉几十个点保证数据质量。
6.3 特征频率找不到,原因在哪里
这类问题按以下顺序排查最省时间:
是不是数据截取区间包含了启动过程?启动过程转速剧烈变化,转差率s不是常数,理想的特征频率公式完全不适用。先确保从 t = 2 秒后取数据。
是不是频率分辨率不够?窗长 4096 点,采样率 10 kHz,分辨率约 2.44 Hz,而断条特征频率偏离基频只有 3.3 Hz,图上看起来像基波峰旁边的一个小鼓包。这种情况把窗长加到 8192 点,分辨率将到 1.22 Hz,峰值分离度明显提升。
是不是故障程度太轻?断 1 根的边频幅值可能只有基波的 0.5%,在幅值线性坐标下完全看不见,改用分贝坐标(
pow2db)后,小峰值才能凸显出来。这一步被很多人忽略,我在用分贝坐标后才发现,原来“看不出来”的信号早就在那里了。还有一个小概率问题:故障特征频率被滤波器压掉了。如果带通滤波器的上截至频率设得太低,比如 100 Hz,那 149 Hz 的定子故障边频分量会被直接滤除,怎么找都找不到。每次设计完滤波器,建议看一眼幅频响应曲线,确认目标频段确实在通带内。
6.4 结果复现性问题的避坑建议
仿真结果在不同机器上不一致,大多数人第一反应是模型有问题,其实大概率是默认求解器参数差异。我建议在模型配置里把所有关键参数固化下来:求解器类型、相对容差、仿真步长类型和步长值、采样时间。这样别人拿到你的文件时,sim出来的结果就完全一致。
另外务必加上模型版本检查。Simulink 模型在跨版本打开时,即使模块参数不变,底层求解器算法细节也可能变化。我在 README 里明确记录模型创建版本和验证版本,这和写仿真代码时的随机种子有异曲同工之妙。
7. 结束前的三个实用建议
主体内容到这里,核心链路已经完整:从电机建模到故障注入,从信号处理到特征提取,再到检测算法和仿真加速技巧。最后分享三点我在整个搭建过程中感受最深的心得。
第一,仿真模型要分层。底层的电机模型保持干净,故障注入单独放一个子系统,信号采集和特征提取放到脚本里。这样做的好处是:你换一种故障类型时,不需要动仿真模型本身,只需要换一个注入模块的配置。所有做实验的人都知道,改动越小,出错概率越小。
第二,建一个专门存放特征数据的目录。每次仿真后自动把特征和参数存成表格,按日期进行编号管理。这样积累一个月后,你手里就有了一套自己的“故障特征数据库”。这比临时跑一次记一次要高效得多,也方便做阈值基线分析和模型验证。
第三,不要迷信模型越复杂越好。能表达故障特征的最简模型就是好模型。很多初学者把电机模型搭得非常细致,考虑齿槽效应、磁饱和、铁损等一大堆因素,导致仿真速度慢了几个数量级,但故障特征频率的计算结果和简单模型相差不到 3%。先跑通,再加复杂度,否则只是在浪费时间。
最后再分享一个调试小技巧。当你在仿真中发现异常波形时,不要急着改模型。先给每个关键节点都加上显示模块,依次检查从三相电压、三相电流到故障注入信号、特征提取输入全部环节的数据形态。我见过太多人盯着最终输出找问题,结果问题出在波形记录器的采样率配置上,前后折腾了一整天。信号链路是逐级传递的,定位故障时也一级一级游走排查,才能快速锁定问题所在。