结构振动测试做久了,你会发现一个很常见的尴尬场景:桥上车来车往、楼里人走人停、风机叶片在风里转着,你想知道这些结构的频率、阻尼比和振型,但总不能为了做一次模态试验,把桥封了、把楼清了、把风机停机。于是就只能靠环境激励下的"被动"测量——用加速度传感器长期测响应,再从响应里把模态参数一点点挖出来。这条路最主流的算法就是随机子空间识别(SSI),而它又分成数据驱动和协方差驱动两个派别。这篇文章我就围绕MATLAB环境下这两类随机子空间方法的程序实现,把原理、代码、稳定图筛选、实测坑点以及跨领域复用一次讲透。内容适合刚接触运行模态分析(OMA)的研究生,也适合做结构健康监测、设备状态评估的工程师——看完你能直接照着搭一套可用的识别流程。
1. 为什么环境激励下的模态识别绕不开随机子空间
1.1 有驱动与无驱动试验的本质差别
传统试验模态分析(EMA)思路很简单:用力锤或者激振器给结构一个已知的激励,同时测激励力和响应,然后算频响函数,再拟合出模态参数。这个方法在实验室里非常成熟,但在实际工程结构上往往行不通——桥梁、高层建筑、风电塔筒、大型旋转设备,要么没法施加足够的激励能量,要么运营状态下根本不允许中断工作。
运行模态分析(OMA)换了个思路:激励不知道,也不需要知道,只测响应。这样做的代价是,系统辨识问题从"已知输入求输出"变成了"纯输出辨识",数学上要难不少。随机子空间识别就是解决这个问题的代表性方法,它能在环境激励近似为白噪声的假设下,仅利用加速度、速度或位移响应,把结构的固有频率、阻尼比和振型估计出来。
环境激励虽然不是严格的白噪声,但城市交通、脉动风、地脉动这类宽带随机激励,在结构主要模态所在的频段内,能量谱往往是平滑的、缓变的。这个前提让 SSI 有了用武之地。反过来说,如果激励里混入了明显的窄带成分——比如旋转机械的转频谐波、风机齿轮箱的啮合频率——那就得先做处理,这个我放到后面专门讲。
1.2 随机子空间的数学直觉:把未知激励"藏"进状态空间
随机子空间的底层是线性时不变系统的状态空间模型:
x(k+1) = A·x(k) + w(k) y(k) = C·x(k) + v(k)
其中 x 是状态向量,y 是实测响应,A 是离散系统矩阵,C 是输出矩阵,w 和 v 分别是过程噪声和测量噪声。结构的所有动力学信息——频率、阻尼、振型——全都编码在 A 和 C 里。系统的极点是 A 的特征值,振型则可以通过 C 与 A 的特征向量组合得到。
关键问题是:A 和 C 不能直接测,只能从 y 的时间序列里估计。SSI 的思路是先把响应数据组装成一个大矩阵(协方差驱动用 Toeplitz 矩阵,数据驱动用 Hankel 矩阵),然后通过 SVD 降维,把隐藏在数据里的低阶状态空间模型"挤"出来。SVD 在这里做的实际上是数据压缩和去噪:它把测量数据分解成信号子空间和噪声子空间,我们只保留和系统阶次对应的最大奇异值部分。
打个生活化的比方:你把一群人关在一间屋子里,只记录他们进出的脚步声(响应),不知道他们在里面聊什么(激励)。但通过分析脚步声的统计规律,你能判断屋里大概有几拨人(模态阶数)、每拨人的语气节奏(频率)、散场快慢(阻尼)以及他们通常坐在哪个区域(振型)。SSI 就是这套"听声辨人"的算法化版本。
2. SSI-COV与SSI-DATA:两套路线的原理差异与适用边界
2.1 SSI-COV:从相关函数搭Toeplitz矩阵
协方差驱动随机子空间(SSI-COV)的核心是先用响应数据估计输出之间的协方差序列,再把这些协方差按时间延迟组装成块 Toeplitz 矩阵,然后做 SVD。它的基本操作流程如下。
第一步,估计协方差序列。假设有 l 个测点、N 个采样点,对时间延迟 τ 计算:
R(τ) = E[ y(k+τ) · y(k)^T ]
实际计算时用有限样本平均代替期望,τ 的范围取 1 到 i,i 就是前面说的块行数(block rows),它的取值直接影响识别质量,后面会专门分析。
第二步,组装 Toeplitz 矩阵。把 R(1)、R(2)……R(i) 排成一个 i×i 的块矩阵,每一行块往右移一个延迟:
T = [ R(i) R(i-1) ... R(1) R(i+1) R(i) ... R(2) ... ... ... ... R(2i-1) ... ... R(i) ]
第三步,对 T 做 SVD 分解,取前 n 阶(n 为系统阶次)截断,得到系统矩阵:
A = S1^(-1/2) · U1^T · T · V1 · S1^(-1/2) C = U1 的前 l 行 · S1^(1/2)
最后对 A 做特征值分解,把离散特征值 λ 转换到连续域 μ = ln(λ)·fs,再由 μ 计算频率、阻尼比,由 C 和特征向量合成振型。
这段流程用 MATLAB 写出来并不长,核心代码就是协方差循环加一次 SVD:
function [fn, zeta, phi] = ssi_cov(y, fs, i, n) % y : l×N 加速度响应矩阵,l为通道数,N为采样点数 % fs: 采样率(Hz) % i : 块行数 % n : 系统阶次 [Nch, N] = size(y); y = y - mean(y, 2); % 零均值化 % 1. 计算协方差序列 R(1) ... R(i) R = zeros(Nch, Nch, i); for tau = 0:i-1 R(:, :, tau+1) = y(:, 1:N-tau) * y(:, tau+1:N)' / (N-tau); end % 2. 组装块Toeplitz矩阵 T = zeros(Nch*i, Nch*i); for k = 1:i for m = 1:i T((k-1)*Nch+1:k*Nch, (m-1)*Nch+1:m*Nch) = R(:, :, abs(k-m)+1); end end % 3. SVD截断,估计系统矩阵 [U, S, V] = svd(T, 'econ'); U1 = U(:, 1:n); S1 = S(1:n, 1:n); V1 = V(:, 1:n); A = S1^(-0.5) * U1' * T * V1 * S1^(-0.5); C = U1(1:Nch, :) * S1^(0.5); % 4. 从系统矩阵提取模态参数 [Psi, Lam] = eig(A); mu = log(diag(Lam)) * fs; % 连续域特征值 fn = abs(mu) / (2*pi); % 固有频率 zeta = -real(mu) ./ abs(mu); % 阻尼比 phi = C * Psi; % 未归一化振型 end这段代码我故意保持了"能看懂"的简洁版本,没有加稳定图循环和异常保护。实际工程版本里,SVD 截断之前通常还要看一眼奇异值分布,确认选取的 n 没有截到噪声平台上。
2.2 SSI-DATA:用QR投影避免相关函数的统计损失
数据驱动随机子空间(SSI-DATA)号称"直接干活"。它不先去算协方差,而是把响应数据排成块 Hankel 矩阵,把矩阵分成"过去"和"未来"两个大块,然后对这两个块做 LQ 分解(即 QR 的变体),用"未来"数据在"过去"数据上的投影,得到可观测矩阵的估计。这个投影操作相当于数据驱动版的协方差统计,但它在数值上更稳健,尤其适合短数据记录。
SSI-DATA 的典型 MATLAB 流程如下:
function [A, C] = ssi_data(y, i, n) % y : l×N 响应矩阵 % i : 块行数(Hankel矩阵用,通常比COV大一些) % n : 系统阶次 [Nch, N] = size(y); y = y - mean(y, 2); % 1. 构造块Hankel矩阵,前i块为过去Yp,后i块为未来Yf H = zeros(2*i*Nch, N-2*i+1); for k = 1:2*i H((k-1)*Nch+1:k*Nch, :) = y(:, k:N-2*i+k); end Yp = H(1:i*Nch, :); Yf = H(i*Nch+1:2*i*Nch, :); % 2. 对[Yp;Yf]做LQ分解:对转置QR,再转置回来得到L [~, R] = qr([Yp; Yf]'); L = R'; % 3. 取L21块并做SVD,获得可观测矩阵 L21 = L(i*Nch+1:2*i*Nch, 1:i*Nch); [U, S, ~] = svd(L21, 'econ'); O = U(:, 1:n) * sqrt(S(1:n, 1:n)); % 可观测矩阵估计 % 4. 从可观测矩阵恢复A、C Nshift = Nch; % 状态维度为 i*Nch 时可向后移一块 A = O(1:end-Nshift, :) \ O(Nshift+1:end, :); C = O(1:Nch, :); end注意第 4 步里 A 的估计方式是:可观测矩阵"整体下移一个块行"后,与原来的关系由系统矩阵 A 联系。这是 SSI-DATA 里最巧妙也最容易写错的地方,很多人第一次实现时在这里栽跟头——状态向量维度和块行数的对应关系必须严格匹配。我在代码里省略了一些矩阵尺寸对齐细节,如果你照抄发现 A 维度对不上,回头检查一下 O 的行数是不是 (2i-1)·Nch 的整数倍关系,多半就是这个原因。
2.3 什么时候用COV,什么时候用DATA
这两套方法的工程取舍,我根据自己的实测经验整理成一张表:
| 对比维度 | SSI-COV | SSI-DATA |
|---|---|---|
| 核心数据 | 协方差序列(压缩后统计量) | 原始响应时间序列 |
| 计算量 | 较小,矩阵规模取决于 i 与通道数 | 较大,Hankel 矩阵更大,QR 分解重 |
| 短数据表现 | 协方差估计偏差明显 | 相对稳健,能榨出更多信息 |
| 噪声敏感性 | 对测量噪声敏感 | 经投影加 SVD,噪声抑制更好 |
| 实现难度 | 代码短,逻辑直观 | 矩阵分块、投影关系复杂 |
| 实际使用频率 | 常用,适合快速摸底 | 更推荐,识别精度通常更高 |
这里要给个忠告:别把 COV 和 DATA 当成"谁取代谁"的关系。我在实际项目里的习惯是两套程序都跑一遍,把它们识别出来的频率放在同一张稳定图里对比。如果两条路线的频率差了超过 1.5%,那基本不是算法选择的问题,而是数据本身有毛病——可能是漂移没去干净、某个通道同步出了岔子、或者局部传感器信号饱和。两法互验是我排查数据质量的第一板斧。
3. MATLAB从零搭一个能跑的SSI识别程序
3.1 输入数据准备:去趋势、滤波、降采样
SSI 对数据质量其实相当挑剔,越是"纯算法信仰者",越容易在第一步就翻车。我收到的实测数据,第一件事永远不是塞进 SSI,而是先做三步预处理。
第一步去趋势。加速度计低频漂移和温漂非常常见,不做处理的话,协方差里会混入一个低频慢变分量,识别出的第一阶模态可能被污染。我用 detrend 函数去除线性趋势,必要时再加一个截止频率 0.1~0.3 Hz 的高通滤波,把残余漂移压掉。
第二步抗混叠滤波与降采样。结构模态关心的频率段通常很低,桥梁在 0.1~10 Hz,高层建筑在 0.05~1 Hz,风机叶片在 0.2~20 Hz。如果原始采样率是 2000 Hz,直接拿全数据算 SSI,矩阵规模巨大,计算时间感人。正确做法是先用低通抗混叠滤波器把高频噪声滤掉,再 decimate 降到目标频率段的 3~5 倍。比如关心 20 Hz 以内的模态,采样率取 50~100 Hz 就够,同时对 24 小时连续监测数据做分段处理,每段 30 分钟到 1 小时。
第三步剔除坏道和异常段。任何一个通道在某一时段掉了线、出现过冲或者饱和削波,这会污染整个协方差矩阵。我的做法是先画一遍所有通道的时域和频谱总览,把明显异常的通道和时段直接裁掉,而不是靠算法硬扛。
3.2 核心矩阵组装与SVD降维顺序
回到 SSI 程序本身,我最想强调的一点是:参数 i 和阶次 n 的选取是耦合的,必须一起考虑。块行数 i 至少要覆盖你关心模态的两倍以上,一般工程上取 i 在 20~60。如果 i 太小,协方差矩阵包含的时间信息不够,低阶模态会认不准;如果 i 太大,协方差高阶延迟项已经淹没在噪声里,Toeplitz 矩阵后几行块全是噪声,反而让 SVD 的低秩近似变差。我用过一个经验规则是 i 取关心最高模态阶数的 3~5 倍,并且不超过总采样点数 N 的十分之一到五分之一。比如预计系统有 15 阶有效模态,i 取 50 左右,N 在 10000 点以上。
SVD 降维的具体顺序也有讲究。先做完整 SVD,画出奇异值分布,你会发现典型图像是前面若干个奇异值很大、后面一串逐渐衰减的"平台"。系统的有效阶次应该截在奇异值开始进入平台的位置,而不是机械地取某个固定值。实在看不出来,就用稳定图上稳定极点数目的峰值来辅助定阶,这是后话。
在组装 Toeplitz 矩阵的时候,我习惯用一个优化技巧:不要用双重循环逐块填充,而用 MATLAB 的 toeplitz 函数直接生成块索引矩阵,再一次性赋值。通道数少的时候无所谓,通道数到了 16 路、32 路时,嵌套循环的开销不可忽视。代码优化后同一批数据从跑 3 分钟缩到 20 秒,这个差距在需要调参试跑的时候非常影响效率。
3.3 从系统矩阵到频率、阻尼比、振型的换算细节
识别出系统矩阵 A 之后,提取模态参数的公式要注意离散域和连续域的区别。我们辨识出来的是离散状态空间模型的 A,它的特征值 λ 是离散域极点在 z 平面的位置。结构真正的极点在拉普拉斯 s 域,换算关系是:
λ_c = ln(λ) / Δt = ln(λ) · fs
然后频率和阻尼比就是:
fn = |λ_c| / (2π) ζ = -Re(λ_c) / |λ_c|
这里的坑在于:MATLAB 的 eig 函数返回的特征值顺序不是固定的,而且复数特征值会成共轭对出现。必须按虚部绝对值排序,同时主动丢弃实部为正的"不稳定极点"——那通常对应数值噪声,物理上真实结构不会出现负阻尼到需要发散的极点。
振型提取稍微绕一点。离散系统特征向量矩阵 Ψ 满足 A·Ψ = Ψ·Λ,对应的连续域振型是 C·Ψ。但 C 本身是观测矩阵的估计,它包含的是"测点处的响应幅值分布"。多个测点之间的振型可能存在整体缩放和相位差,所以拿到原始振型后第一件事是归一化——我把每个振型向量的最大绝对值归一化到 1,然后再算 MAC。
MAC(Modal Assurance Criterion)是验证振型质量的标准指标:
MAC(a, b) = |a^H · b|^2 / (|a|^2 · |b|^2)
其中上标 H 表示共轭转置。同一阶模态在不同设定下的 MAC 应该接近 1,不同阶模态之间的 MAC 应该远小于 0.3。我在程序里会同时计算"识别振型与仿真振型"的 MAC 和"相邻阶次识别振型"的 MAC,前者验证正确性,后者用来挑稳定极点。
4. 稳定图:把"阶次选择"变成看得见的聚类
4.1 为什么要画稳定图
SSI 面临一个尴尬的现实:你不知道系统的真实阶次,只能给一个上界,比如 60 阶。于是程序会在 n = 2、4、6……60 的每个设定下都做一次识别,每阶次得到 n/2 个极点(共轭对算一个)。真实模态对应的极点在所有阶次设定下会稳定重复出现,而噪声产生的数学极点则会随阶次变化到处漂移。把每个阶次识别出的频率画在一张以"阶次为纵轴、频率为横轴"的图上,稳定极点排成一条竖线,像一柱香;虚假极点则散落各处,这就是稳定图命名的由来。
我自己的体会是:稳定图不仅是一个工具,更是一种思维模式。它把"定阶"这个抽象问题转化为"找聚类"这个直观问题。你不需要提前知道系统有几阶模态,只需要让程序把所有候选极点都摆出来,然后人眼或者算法去挑那些"稳固"的列。
4.2 稳定判定标准怎么设
稳定极点的定义是:在相邻两个阶次设定下(比如 n=40 和 n=42),识别出的某对极点的频率、阻尼比和振型都足够接近。常用的判定标准我用了一组自己调过很久的阈值:
| 判定项 | 阈值 | 说明 |
|---|---|---|
| 频率偏差 | |f(n+Δ)-f(n)| / f(n) ≤ 1% | 频率是识别最稳的参数,阈值可以严 |
| 阻尼比偏差 | |ζ(n+Δ)-ζ(n)| ≤ 0.005 | 阻尼误差大,用绝对偏差更实用 |
| MAC | ≥ 0.95 | 振型一致性,低于 0.98 会漏掉弱模态 |
| 连续稳定次数 | ≥ 3 | 至少 3 个连续阶次都稳定才算"真" |
阻尼比的判定最容易踩坑。很多新手把阻尼比的相对偏差定到 10% 以内,结果真实模态也被筛掉了——因为阻尼比本身辨识结果的离散性就有 20%~30%。所以我建议阻尼比用绝对偏差 0.005,也就是 0.5%。一个阻尼比 2% 的模态,识别的离散范围在 1.5%~2.5% 之间都算正常,用相对 10% 就太苛刻了。
4.3 自动挑点的爬坡逻辑
人工看图挑稳定极点固然可靠,但数据量一上来——比如 24 小时监测每小时一段、每段画一张稳定图——就得写自动筛选程序。我的自动化逻辑分三步。
第一步,把所有阶次识别出的极点收集起来,带上阶次标签和参数。第二步,按频率升序排列,用贪心算法做聚类:每个极点看它后面是否连续 N 个阶次都有对应稳定极点,满足就记录为一个候选模态。第三步,在每个候选聚类内取中位数作为最终参数估计,中位数比均值更能抵御个别离群点。
写自动筛选的时候,务必注意"合并相邻聚类"的问题。如果两个真实模态靠得很近——比如频率差只有 3%~5%——它们对应的稳定列在图上会连成一片,贪心算法可能把它们误认成同一阶。这时候我的兜底办法是检查每个聚类内部的 MAC:把聚类内代表性极点两两算 MAC,如果组内存在 MAC 低于 0.9 的两派,强制拆成两个模态。
4.4 我的筛选经验:先看频率与MAC,阻尼只作参考
自动稳定图跑通之后,还有一个经验层面的东西必须写下来:频率是最可信的识别结果,误差通常在 1% 以内;振型次之,MAC 能到 0.95 就很不错;阻尼比是最脆弱的,实测阻尼比的误差超过 30% 都不要惊讶。所以在最终汇报和写报告时,我总会把频率和振型作为主结果,阻尼比只作为参考指标,并且在文档里注明"阻尼比辨识结果受环境激励强度、幅值非线性影响,本报告数值仅供参考"。
阻尼比之所以难认,是因为它本质上是极点在复平面上的实部,而实部在系统辨识里是比虚部弱得多的信号。虚部对应振荡频率,哪怕噪声,频率依然能被稳定测出;实部对应衰减速率,需要很长的时间序列才能积累出统计显著性。这个道理解释了为什么稳定图上阻尼比的判定标准必须放宽,也解释了为什么有些人拿短数据段算阻尼比会得到负值——纯粹是统计涨落。
5. 实测踩坑记录:采样、阶次、噪声,三个最常翻车的地方
5.1 采样率与抗混叠:低频结构最容易犯错
我第一次做现场实测时犯过一个典型错误:某大型结构关心的是 0.5~4 Hz 的模态,我图省事用了 256 Hz 采样,数据量巨大,SSI 跑得非常吃力。后来意识到,模态分析不是采样率越高越好,关键是满足奈奎斯特频率后留出足够余量,更重要的是采样之前的模拟抗混叠滤波。如果现场采集设备没有硬件抗混叠滤波,任何高于 fs/2 的成分都会折叠到低频段,在稳定图上表现为一堆规律的虚假极点——它们不散乱,反而稳定得很,专门干扰判断。
正确做法是:确定关心频段上限 fmax 后,采样率设在 4~5 倍 fmax。比如关心 20 Hz 以内,用 100 Hz 采样;关心 5 Hz 以内,用 25 Hz 采样。同时保证系统里有截止频率约 0.4~0.5 倍采样率的抗混叠滤波器。处理已有数据时,先用低通滤波再 decimate,不要直接抽点。
5.2 块行数i的取值:过小欠统计,过大致病态
前面提到块行数 i 的经验取值,这里展开说一个具体翻车案例。某模拟系统一共 5 阶模态,最高频率 12 Hz,采样率 100 Hz,N = 20000 点。我图省事把 i 设成 10,结果低频两阶模态完全没识别出来。原因很简单:i 太小导致 Toeplitz 矩阵只包含很短的时间延迟信息,而低频模态的特征时间尺度长,需要更大的延迟窗才能捕捉到。把 i 改到 30 后,5 阶模态全部出现。
反过来,i 也不能无脑大。i 取 100 的时候,R(100) 这个协方差延迟只用了不到 N/100 个样本点去估计,统计误差爆炸,Toeplitz 矩阵的低频块全被噪声主导。而且在 SSI-DATA 里,i 直接决定 Hankel 矩阵块数,i 过大时 LQ 分解规模和内存占用快速上升,算一次要十几分钟,调参效率极低。我的教训是:i 宁可先取一个中间值——比如 30~50——然后观察识别结果对 i 的敏感度。如果结果随 i 变化明显,说明这段数据本身有问题,别指望调参能救。
5.3 非白噪声与传感器同步问题
结构上的激励不可能是理想白噪声。如果某个频段上有强窄带激励——比如附近有固定频率的机器、风机叶片通过频率、桥上行人步频——SSI 会把它们也当成模态识别出来,并且因为它们的能量强,反而更"稳定",很容易骗过稳定图的筛选。我的判断技巧是:把识别的频率和频谱峰值逐一对照,再结合结构有限元模型的理论频率范围。属于已知激励频率的极点(比如电机转频 25 Hz)直接从结果里剔除,并在报告里注明来源。
另一个容易被忽略的是通道间同步误差。无线传感器网络做模态测试时,各节点时钟不同步,哪怕只差 5~10 毫秒,对高频模态的相位影响就很大,MAC 直接崩掉。这不是算法能修正的,必须在采集端解决。我通常在传感器部署前先做一次同步校准测试:把所有传感器绑在同一个振动台上敲一下,看各通道之间的一致性。
6. 多领域迁移:桥梁、建筑、设备、叶片怎么复用同一套代码
6.1 桥梁索力与整体模态:一个直接见效的场景
桥梁是 SSI 应用最成熟的领域之一。斜拉桥的拉索索力可以通过弦理论公式由频率反算:
T = 4·ρ·L²·f² / n²
其中 T 是索力,ρ 是单位长度质量,L 是索长,f 是第 n 阶固有频率。实际项目里不需要人工激励,只要在索上贴一个加速度计,测几分钟环境振动,SSI 就能把索的前几阶频率识别出来,索力精度可以做到 5% 以内。这个精度对长期健康监测完全够用。我做过的某斜拉桥监测项目里,索力变化趋势和温度、交通量的相关性非常清晰,这是传统人工激振法完全做不到的。
桥梁整体模态识别时,测点布置要覆盖主梁和桥塔,空间分辨率决定了高阶模态的识别上限。SSI 对测点数量其实不敏感,6 个点就能识别前 5 阶整体模态,但要得到清晰的扭转模态,同一截面至少需要两个竖向测点,这个细节在布点阶段就要想清楚。
6.2 建筑与风电结构:低频段与大阻尼并存的情况
高层建筑的前几阶频率可能低到 0.1 Hz,对应的周期是 10 秒量级,采样率降到 5~10 Hz 都够。但低频结构有一个麻烦:环境激励的能量的低频段可能不足,信噪比差。我的经验是加长观测时间,至少连续测 30 分钟以上,让低频模态在协方差里积累出足够的统计置信度。
风机塔筒和叶片运行时,结构自身处于旋转状态,激励包含强烈的周期性成分,而且叶片阻尼比通常较高(3%~8%),识别难度比常规建筑大。处理风电数据时,我会特别小心叶片通过频率(3P、6P 这些)对稳定图的污染。连线分析时先做频谱图,把已知的旋转谐波频率标出来,识别结果如果落在谐波频率附近,先怀疑是谐波而非结构模态,再用两个不同转速工况下的数据交叉验证——真实结构频率不随转速明显变化,谐波则严格跟随转速。
6.3 旋转机械中的谐波污染
旋转设备(泵、风机、电机机组)的结构模态测试同样可以用 SSI,但谐波污染是所有方法绕不开的主题。转频及其倍频在频谱上是离散尖峰,它们对应的极点在稳定图上同样非常"稳定",而且能量往往高于附近的结构模态。处理办法我试过两类:一类是时域梳状滤波,把已知转频整数倍频率滤掉再做 SSI;另一类是在多个不同转速下分别识别,用"频率是否跟随转速"来区分谐波和结构极点。后者更可靠,因为它利用的是物理本质,而不是滤波器近似的干净程度。
6.4 先仿真自检:3自由度系统验证再上真机
调试 SSI 程序最忌讳直接拿现场数据试,因为你不知道哪里出了问题。我的固定套路是先造一个三自由度弹簧-质量-阻尼系统,给定质量和刚度参数,算出理论频率和振型,用白噪声激励做数值仿真,得到响应后,把响应喂进 SSI 程序,把识别结果和理论值对比。
一个典型仿真算例我放在这里作为参考:三个固有频率分别是 2.01 Hz、5.36 Hz、8.87 Hz,阻尼比分别设 2%、1.5%、1%。采样率 100 Hz,N = 20000 点,i = 40。SSI-COV 识别的结果是 2.03 Hz、5.38 Hz、8.85 Hz,误差都在 1% 以内;振型 MAC 全部超过 0.98;阻尼比辨识结果在 1.7%~2.3%、1.2%~1.8%、0.8%~1.4% 之间波动,明显离散但方向正确。这个结果每次都让我对"频率可信、阻尼仅供参考"的判断更有底气。
仿真自检还有一个额外收益:可以在真实数据之外,人为加入不同强度的噪声,画出"误差随噪声增大而恶化"的曲线,从而知道自己程序对信噪比的容忍底线。这个底线数值对现场测试很有指导意义——如果某个通道的信噪比已经低于底线,就得考虑换传感器量程或者换测点位置。
说到底,SSI 这套方法的价值不在于算法本身多复杂,而在于它能从看起来很"脏"的实测数据里,稳定地挤出结构最本质的动力学信息。我做了这么多年振动测试,最深的体会是:算法和程序只是工具的一半,对数据质量的敬畏、对物理机制的判断,才是另一半。每次拿到一批新数据,我先不问"用什么算法",而是问"这批数据是怎么测的、哪里可能有问题",想清楚这两件事再跑程序,识别的成功率会高出一个量级。