1. 为什么我把目光锁定在“数据驱动 + 兰姆波”这条路上
结构健康监测(SHM)在航空航天领域不是新概念,但这些年确实到了必须往前再推一步的节点。机翼蒙皮、机身壁板、尾翼结构,这些部位长期承受交变载荷,容易出现疲劳裂纹、冲击损伤、分层、腐蚀等隐患。传统做法是定检周期内用无损检测手段逐段扫查,效率低、成本高,更关键的是没有办法做到“原位”和“连续”评估。所谓原位,就是结构在哪服役就在哪检测,不需要拆解、不需要大规模停机;所谓连续,就是希望能从结构服役的全过程中持续获取状态信息,一有异常就能报警,而不是等到例行检修才发现问题。
在这个背景下,基于压电传感器阵列、激励并接收兰姆波(Lamb Wave)的结构健康监测方法,成了很多团队的优先选择。兰姆波是板状结构中传播的超声导波,它沿着结构传播距离远,对板内分层、表面裂纹、冲击损伤都比较敏感,而且压电元件可以做得很小、很薄,能够埋入或粘贴在结构表面,不显著增加重量。可以说,兰姆波和SHM天然适配。
但仅仅把兰姆波信号采回来还不够。早期方法大多依赖物理模型反演或者人工分析波包,碰到真实结构就头疼:几何形状复杂、材料参数不确定、环境温度波动、传感器一致性差,任何一项都会让理论解和实测信号对不上。我做过的几个模拟项目里,光是温度引起波速变化,就能让同一损伤的到达时间差出好几个采样点,按纯物理模型去反演位置,误差大到没法用。所以后来我彻底转向了数据驱动路线——不再把全部希望寄托在精确建模上,而是让算法从大量兰姆波响应数据中自己学习“信号特征与损伤状态”之间的映射关系。
这套方案的好处很直观:数据驱动模型不需要你精确知道结构内部的每一处细节,只要训练数据覆盖足够多的损伤工况和环境变化,模型就能在端到端的层面把“损伤在哪、损伤多重”这两个问题一起回答出来。而且Matlab环境下实现起来非常顺手:信号工具箱负责预处理,统计和机器学习工具箱负责特征提取与建模,整个流程一条线跑通,非常适合做方案验证和参数迭代。
这篇文章就是围绕这个主题整理的。适合三类人:一是准备做SHM课题的同学,二是航空结构运维相关方向想引入自动化监测手段的工程师,三是已经采集了一批导波数据、正发愁怎么用机器学习榨干信号价值的同行。我会按自己的实际踩坑过程,把数据怎么处理、特征怎么提、模型怎么训、代码怎么写,一步步都说清楚。
2. 兰姆波响应背后的信号逻辑:搞清楚再写代码
2.1 兰姆波的本质与模态困惑
兰姆波是在具有自由边界条件的板类结构中传播的弹性导波,本质上是纵波和横波在板上下表面反复反射、干涉叠加之后形成的稳定波场。它在板内存在两类基本模态:对称模态(S0、S1...)和反对称模态(A0、A1...),各类模态还有阶数之分。阶数出现的条件与激励频率和板厚的乘积(频厚积)有关,频厚积低于某一阈值时,板内只存在S0和A0两个基阶模态;一旦频厚积超过阈值,高阶模态就会“冒出来”。
做损伤检测时我们通常希望激励频率足够高,这样波长短、对小损伤更敏感,但又不能高到激发过多高阶模态,否则信号里一堆模态混在一起,后续处理和特征提取的复杂度会直线上升。我在项目中常用的做法是把频厚积控制在基阶模态区间内,例如2mm厚的铝板,激励频率选在100kHz到300kHz之间,这样结构内主要传播S0和A0两个模态,时域波形更容易解读。
2.2 为什么“选定位置”的稀疏传感阵列能实现原位评估
很多刚接触SHM的人有个误区,觉得要在结构上密密麻麻贴满传感器才能监测损伤。实际工程中,重量、布线、成本都是硬约束,大规模密布传感器并不现实。更合理的思路是稀疏阵列——在结构关键区域边界或者几个关键节点布置少量压电元件,采用“一发多收”或“多发多收”的模式轮流激励和接收。
这里面的物理依据是损伤散射:当入射兰姆波遇到裂纹、分层或冲击凹坑时,损伤区域相当于一个“二次波源”,会把一部分波能量散射到各个方向。布置在选定位置的接收传感器,除了收到直达波,还会收到损伤散射波。散射波包相对直达波的到达时间和幅值,就携带了损伤位置和严重程度的信息。我们不需要扫描整块板,只需要从选定的几个接收位置提取这些差异,就可以反推损伤状态。这与昆虫触角感知气流方向一个道理,不靠数量取胜,靠的是多个通道之间的相对信息差异。
2.3 从原始波形到可用特征,中间要做什么
数据驱动方法里,模型的输入可以是一整段波形,也可以是人工设计的特征。直接把整段波形喂给深度学习模型当然可行,但在样本量有限、可解释性要求高的SHM场景中,我更喜欢先用特征工程压缩信号,再交给轻量级机器学习模型。
预处理阶段有三件事必不可少:一是滤波去噪,兰姆波信号往往叠加工频干扰、电磁噪声和环境振动噪声,带通滤波是标配,滤波器通带根据激励频率设置,例如中心频率200kHz、带宽40%左右;二是时间零点对齐,激励信号发出时刻必须与采集起始时刻严格同步,否则所有时间段信息都是错的;三是截取有效时间窗,只保留从激励开始到边界回波之前的时段,避免把边界反射当损伤散射。
特征提取阶段,常见组合包括直达波峰峰值、散射波包峰值、散射波到达时间(TOF,Time of Flight)、波包能量、频谱质心、短时傅里叶变换后特定频带能量等。这些特征各有物理意义:到达时间直接关联传播路径长度,与位置信息强相关;散射波能量和峰值幅值往往随损伤程度增加而增大;频谱质心的偏移则能反映损伤对高频分量的吸收与散射。多个特征组合,就构成了描述结构状态的“指纹”。
3. 数据驱动建模:这是从“波形”到“损伤答案”的核心一跳
3.1 数据驱动方法到底在学什么
抛开复杂名词,数据驱动方法做的事非常直白:建立输入特征向量到输出标签的映射关系。在这个项目里,输入是选定位置处的兰姆波响应特征,输出是损伤位置坐标和损伤程度。模型要学的就是这条映射关系——它既不需要你列一堆偏微分方程去求解波场,也不需要你精确给出板边界的反射系数,它只需要在大量标注样本中找到特征与损伤之间的统计规律。换句话说,物理规律以隐式编码的方式被模型吸收在权重里了。
选型时我的经验是第一轮先跑简单的线性/树模型,比如SVM、随机森林、梯度提升树。这些模型训练快、泛化能力不差,还能输出特征重要性,帮我们判断“哪些特征才是真的有效”。如果树模型已经能在验证集上达到亚厘米级的定位精度,就没必要非上深度学习。只有在特征与损伤之间呈现高度非线性、且样本量足够大时,再考虑多层感知机或卷积神经网络直接吃原始波形。
3.2 标签设计与样本组织
我们要同时输出损伤位置和程度,这在机器学习框架里对应多输出回归问题。输出向量可以设计成[x坐标,y坐标,损伤指数],其中损伤指数可以用等效裂纹长度、凹坑深度或剩余强度百分比来归一化。需要注意的是,不同物理量的量纲差异很大,训练前必须先对每个输出维度独立做标准化,否则量级大的输出维度会主导损失函数,模型学了半天,位置准了、程度却偏了。
训练数据的来源有两种主流路径:仿真生成和实验标定。仿真可以用有限元软件(如某通用有限元软件)或者分布源方法模拟兰姆波在板内的传播和损伤散射,批量计算不同损伤位置、不同损伤程度、不同激励频率下的响应,自动化生成上千组样本;实验标定则在真实板结构上人为设置损伤——粘贴质量块、开槽、钻孔、制造冲击凹坑,再逐点测量。经验上最稳妥的组合是“仿真预训练 + 少量实验微调”。纯仿真训练容易让模型在真实结构上遇到分布漂移,纯实验训练又往往因为样点太少而严重过拟合。两者结合,效率和准确率都能兼顾。
3.3 评价指标怎么定,才有工程参考价值
做模型评估时,不要只盯着总体准确率。这个场景里我们至少要汇报四个指标:平均定位误差——计算预测损伤位置与真实损伤位置的欧氏距离;定位命中率——比如误差小于10mm的样本占比;损伤程度估计的相对误差;以及泛化性能——把同一位置不同温度条件下采集的数据作为独立测试集,看模型是否仍然稳。
我吃过一次亏:训练集和测试集来自同一批次实验数据,评估出来的定位误差小于5mm,看起来乐观得很。但后来换了一块新板子,同样位置设置同样的损伤,预测误差直接翻到20mm往上。问题就出在训练时没有对板间差异做泛化处理。正确的做法是按板分组划分数据,同一块板的样本只能全部落在训练集或者全部落在测试集,这样才能验证模型对“未见过板”的适应能力。
4. Matlab代码实现与实操流程:从数据到结论的完整链路
4.1 代码整体架构设计
Matlab的优势在于集成度高,数据读取、信号处理、特征计算、模型训练、结果可视化都在同一个编程环境下完成,不用来回切换语言。我建议把整个工程拆成五个模块:
- 数据导入模块:读取各传感器通道的时域波形,检查信号长度和采样率一致性。
- 预处理模块:滤波、去均值、时间对齐、时间窗截取。
- 特征提取模块:计算每一条通道的TOF、峰值、能量、频谱特征。
- 模型训练模块:划分数据集、训练回归模型、调参。
- 评估与可视化模块:绘制损伤位置散点图、误差直方图、特征重要性排序图。
模块化之后有一个很实用的好处:更换传感器布局、换激励频率或者换另一块结构,只需要改数据导入和参数配置,不需要重写模型代码。我每次换结构,大概半小时就能把新数据跑通。
4.2 核心代码块解析
% 读入单次激励下4个接收通道的兰姆波响应 % data: [numSamples x numChannels],fs为采样率 fs = 5e6; % 5MHz采样率 t = (0:size(data,1)-1)/fs; channels = size(data,2); % 带通滤波,通带设置在激励频率附近 % 激励频率200kHz,带宽80kHz fc = 200e3; BW = 80e3; for ch = 1:channels data(:,ch) = bandpass(data(:,ch), ... [fc-BW/2 fc+BW/2], fs, 'ImpulseResponse','fir'); % 去直流分量 data(:,ch) = data(:,ch) - mean(data(:,ch)); end这段代码的关键在于bandpass函数的选择。对兰姆波信号来说,FIR滤波器相位线性度好,波形失真小,有利于保持到达时间的准确性;IIR滤波器虽然阶数低、计算快,但相位非线性会拉伸或压缩波包,导致TOF估计误差。我最早图省事用了IIR,结果特征提取阶段怎么调都差几个样本点,换成FIR之后问题立刻消解。
特征提取部分,TOF的计算需要指定阈值。通常的做法是先对信号取包络(用希尔伯特变换),然后从激励起始时刻开始搜索,找到包络超过一定比例的峰值点作为波包到达时刻。阈值选10%附近比较稳,太小容易受到噪声影响触发误检,太大会漏掉微弱散射波。
% 提取散射波峰特征 for ch = 1:channels env = abs(hilbert(data(:,ch))); % 希尔伯特包络 % 直达波出现在约50us附近,截取60us之后作为散射波段 idx_scatter = t > 60e-6 & t < 200e-6; scatter_peak(ch) = max(env(idx_scatter)); scatter_tof(ch) = t(find(env == max(env(idx_scatter)),1)); % 散射波能量:包络平方的积分 scatter_energy(ch) = trapz(t(idx_scatter), ... env(idx_scatter).^2); end这里有几个细节值得注意。直达波位置可以通过理论估算:波速和传播距离已知,到达时间大约等于距离除以群速度;如果激励频率选定在200kHz、2mm铝板,S0模态群速度大约在5.4mm/us左右,A0模态约3.1mm/us,50us对应的是大约150mm到270mm的传播路径。实际项目中直接用一条健康基准信号先测出直达波的精确时段,再在其后截取散射波区段,比用理论值更靠谱。
模型训练代码很简洁,Matlab的fitrgp(高斯过程回归)、fitrensemble(集成回归树)、fitrsvm(支持向量回归)都能直接调用。我通常先跑fitrensemble,因为它对特征尺度不敏感,不需要大量调参就能给出一个不错的基线:
% 特征矩阵: 每行一个样本,列为各通道特征 % Ftrain: [nTrain x nFeatures],Ytrain: [nTrain x 2] % 第一列为x坐标,第二列为损伤指数 mdl_x = fitrensemble(Ftrain, Ytrain(:,1), ... 'Method','LSBoost','NumLearningCycles',150); mdl_sev = fitrensemble(Ftrain, Ytrain(:,2), ... 'Method','LSBoost','NumLearningCycles',150);拟合完成后,用predict在测试集上推理,再用perfcurve画累计误差分布。整个过程包含数据导入、预处理、特征提取和模型训练,我在一台主流配置笔记本上跑500个样本,不到3分钟就能出结果。
4.3 参数选择与调试心得
有几个参数不是我第一次跑就选对的,完全是被现实教训之后才记住的。第一个是激励频率。前面说过要根据板厚选择,频厚积不要超过基阶模态截止点,但实际中还要避开传感器自身的谐振频率区间,否则收发信号严重变形。第二个是采样率,至少要达到激励频率的10倍,推荐20倍以上。采样率太低,波包峰值定位的分辨率直接受限,TOF误差会被放大成厘米级的位置误差,后面算法再好也救不回来。第三个是激励周期数。“窗数”太高会让波包变宽、时间分辨率变差;太低则激励能量不足。比较常用的是5个周期的汉宁窗调制正弦脉冲,兼顾能量集中和时间分辨率。
我在一个模拟结构上试过不同周期数对定位精度的影响,3周期时散射波包太窄、能量不足,直接波之后很难稳定识别散射峰;9周期时TOF提取倒是容易了,但两个相邻损伤产生的散射波在时域上严重重叠,位置解算精度反而下降。5周期是比较好的平衡点。
5. 常见问题与排查技巧实录
5.1 模态混叠让波峰识别失灵
兰姆波多模态同时传播会让包络提取出来的“峰值”含义混乱。如果你发现同一通道相邻两次实验的信号波形明显不一致、波包数量对不上,十有八九是高阶模态被激发了。解决路径:降低激励频率(但也不能太低,否则对微小损伤不敏感);或者把激励和接收都换成S0模态偏好较强的传感器组合,因为不同模态对不同方向的应变敏感度不同,可通过选择传感器贴装方向来压制不需要的模态。
还有一个更彻底的思路是加空间滤波——布置两个距离很近的传感器,对两路信号做差分或合成,利用不同模态波长不同这个特性,在空间上对模态进行选择。这个技巧在实验条件允许时效果显著,但会增加通道数量,工程上需要权衡。
5.2 温度漂移必须单独处理
温度每升高一摄氏度,兰姆波群速度大约会变化0.1%到0.3%,积少成多之后,损伤散射波到达时间的偏移足以让模型定位误差扩大数倍。处理方式有三种,按照从简单到复杂的顺序:一是训练数据里覆盖不同温度,让模型自己学会温度不变性特征;二是在特征层面引入温度补偿,例如以健康状态下直达波到达时间为参考,对散射波TOF做归一化,消除温度引起的整体时移;三是额外引入温度传感器,把温度信号作为辅助特征输入模型。
我实测下来,第二种方法性价比最高,计算量增加极小,效果非常明显。核心步骤很朴素:先测一条当前温度下健康状态的直达波到达时间作为参考,再用每条损伤信号的散射波TOF减去这个参考值,很多由温度引起的公共时移就被消掉了。
5.3 样本不均衡让模型“偏心”
损伤位置样本如果不均匀,比如某些区域实验条件难实现、样本特别少,模型会对样本密集区域更“自信”、稀疏区域预测误差大。缓解办法有两个:一是仿真数据补足稀疏区域的样本,二是对损失函数加样本权重,给稀疏区域样本更高的权重,强制模型对它们同样重视。经验上后者更适合已经有一部分实测数据、不想完全依赖仿真的场景。
5.4 过拟合的典型信号
训练集误差很低、测试集误差很高是最典型的过拟合信号。我遇到的另一个隐蔽信号是训练集和测试集的数据分布不完全独立——比如测试板是训练板“翻个面”再测的,看起来是新数据,实际上边界条件和传感布局几乎相同,泛化性能被高估。做严格验证时,务必保证分区粒度是“板级”或“实验批次级”,而不是简单随机抽取样本。
6. 从这套方法往外延展还能做什么
这套“特征提取 + 数据驱动回归 + 稀疏布局”的框架,边界远不止板类结构的损伤定位。我对它进一步扩展的方向有两个:一是从二维平面板结构推广到曲率较大的曲面结构,比如机身舱门圆角区域或翼身连接过渡区,此时兰姆波的传播路径不再是简单直线,特征设计上需要引入“最短传播路径”描述,或者直接改用深度学习模型自动提取空间不变特征;二是从静态损伤识别走向疲劳累积损伤趋势预测,把一个监测周期内连续采集的多次兰姆波响应建模成时间序列,用递归网络或状态空间模型预测剩余寿命。
回到这套方法本身,每一次采集到的兰姆波响应,其实都是结构当前状态的一次“快照”。数据驱动模型的本质,就是在大量快照中把结构物理状态的指纹抽取出来。物理知识决定了我们该看什么信号、在哪里传感、用什么频率激励;数据驱动方法则负责把信号中的复杂耦合关系吃透。两者不是替代关系,而是前后衔接的关系。把物理直觉放在前面做约束,把算法能力放在后面做映射,这就是我认为在这个领域最合理的工程方法论。
最后分享一个写作之外的实操体会:这个项目里最容易卡住的环节,通常不是代码,而是数据标注的一致性。实验数据里每一条样本的损伤位置和程度标签必须经过两个人独立复核,否则标签噪声带来的误差会无可避免地进入训练模型,而且极难排查。好的SHM结果建立在高质量的数据管线之上,这一点在多轮项目迭代中反复被验证。