先交代一下背景。我这两年一直在做结构健康监测相关的项目,环境激励下的模态参数识别是绕不开的一关。风、车流、地脉动这些激励没法人为控制,输入不可测,传统基于力锤或激振器的频响函数方法基本派不上用场,这时候就得靠运行模态分析(OMA)。而在OMA这一堆方法里,随机子空间(Stochastic Subspace Identification,SSI)是我個人用得最顺手、也最愿意向同行推荐的一类。类目下最常见的就是基于数据驱动的SSI-DATA和基于协方差驱动的SSI-COV,两者数学同源但实现路径差别很大,很多人初学时分不清楚,甚至在MATLAB里跑通了也不知道结果到底靠不靠谱。
这篇文章就把这两种方法的原理、MATLAB实现、参数怎么定、实测中容易踩哪些坑,完整过一遍。适合刚入门模态分析的研究生、做桥梁和机械结构监测的工程师,以及想在MATLAB里自己动手写而不是只调现成工具箱的人。我会把关键步骤的代码一并给出,也会重点讲那些论文里一般不会写、但实际操作真正决定成败的细节。
1. 为什么是随机子空间:方法选型与核心思路
1.1 环境激励下的模态识别难在哪
先说说问题背景。传统实验模态分析(EMA)的核心是“已知输入,测量输出”,激励信号是锤击或激振器给的,输入输出都测得到,直接用频响函数就能把模态参数提取出来。但很多实际工程结构,比如大跨度桥梁、风电塔筒、在役建筑,你没法安装激振器去激励,也不现实把结构停下来做试验。能用的激励就是环境本身:风、地面微振动、车辆通行。这些激励随机、不可控、幅值小,输入信号拿不到,只有输出响应可以测。
这种情况下,我们有的是若干通道的加速度响应时程,目标是仅凭这些响应识别出结构的自振频率、阻尼比和振型。这就要用到运行模态分析。运行模态分析的思路是,把环境激励近似视为白噪声或者宽带随机过程,将输入从方程中消掉,转而建立输出之间的统计关系来推得系统矩阵。随机子空间方法能在时域内直接处理时程数据,无需做FFT变换,不存在泄露和频率分辨率的问题,对密集模态的区分能力也优于传统峰值拾取法,因此成为工程界的首选之一。
1.2 SSI-DATA和SSI-COV:“一母同胞”的两种路径
随机子空间方法的核心思想并不复杂:把结构离散成一个线性时不变状态空间模型,然后利用输出数据的统计特性去识别这个状态空间模型的系统矩阵A和观测矩阵C。模态参数(频率、阻尼、振型)最终都是从A的特征值分解获得的。
问题在于“如何利用输出数据的统计特性”。这里分出两条路:
- SSI-COV(协方差驱动):先把输出数据两两之间在不同时延下的协方差算出来,组成一个分块Toeplitz矩阵,再对这个矩阵做奇异值分解(SVD),从分解结果里提取可观性矩阵和可控性矩阵,最后反推出系统矩阵A。这条路是“先压缩数据,再做分解”。
- SSI-DATA(数据驱动):直接用原始输出时程构建Hankel矩阵,对Hankel矩阵做QR分解,再对投影矩阵做SVD,同样提取系统矩阵。这条路是“不经过协方差统计,直接在原始数据上运算”。
所以两者的底层数学框架是同一个状态空间模型,区别在“喂给SVD的矩阵”不一样。SSI-COV喂的是协方差Toeplitz矩阵,SSI-DATA喂的是由QR分解得到的投影矩阵。从数值稳定性来看,SSI-DATA通常更优,因为它不经由协方差这一步,避免了对原始数据做二次统计带来的信息损失;SSI-COV的计算量更小,内存占用低,适合处理超长时间数据。后面我会专门用一节的篇幅做两者结果的一致性对比。
我自己的经验是:初学阶段先啃SSI-COV,因为它的数学路径短,每一步都能和教材公式对上,方便调试。等到对算法真正理解了,再切SSI-DATA来提升精度。但如果项目周期紧、直接上手工程实测,那我建议一步到位用SSI-DATA,原因后面细说。
2. MATLAB环境下SSI-DATA的完整实现细节
2.1 从加速度时程到Hankel矩阵:搭建的第一步
Hankel矩阵是SSI-DATA算法的数据基础。它的结构很规整:把输出数据按时间顺序排成两个半块,上半块作为“过去”,下半块作为“未来”,两个半块在时间上错开一个采样间隔。
假设我们有l个测点(传感器通道数),每个通道N个采样点,数据矩阵为:
[ y = [y_{1}^{T}, y_{2}^{T}, \dots, y_{N}^{T}]^{T} \in R^{N \times l} ]
块行数i是一个非常关键的参数,它至少需要大于系统的最大感兴趣模态阶次。工程经验上,如果预期结构前n阶模态,那么块行数i取2n左右。接下来构建Hankel矩阵:
function H = build_hankel(y, i) % y: N x l 的响应数据 % i: 块行数 N = size(y, 1); l = size(y, 2); H = zeros(2*i*l, N - 2*i + 1); for k = 1:N - 2*i + 1 col = []; for j = 1:2*i col = [col; y(k + j - 1, :)']; end H(:, k) = col; end end构建Hankel矩阵的循环写法虽然直观,但效率偏低。实测数据动辄几百万行,这种逐列拼接的方式会非常慢。我一般改用MATLAB的toeplitz函数快速生成索引矩阵,然后利用索引批量映射数据。在真实项目中,这个优化能让处理时间从十分钟级别降到秒级。
2.2 投影矩阵与QR分解:数据怎么“压”出系统信息
Hankel矩阵构建完成后,将其分成“过去”和“未来”两个子块:
[ H = \left[ \begin{array}{c} H_{p} \ H_{f} \end{array} \right] ]
其中 ( H_{p} ) 是前 ( i ) 个块行(过去输出), ( H_{f} ) 是后 ( i ) 个块行(未来输出)。SSI-DATA的关键一步,就是计算未来输出在过去输出行空间上的投影。这个投影矩阵 ( O_{i} ) 的定义为:
[ O_{i} = H_{f} / H_{p} = H_{f} H_{p}^{T} (H_{p} H_{p}^{T})^{\dagger} H_{p} ]
直接按这个公式计算会遇到数值问题,因为 ( H_{p} H_{p}^{T} ) 可能接近奇异。实际工程实现中,我们通常用QR分解来高效且数值稳定地完成投影计算。QR分解将Hankel矩阵分解为正交矩阵Q和上三角矩阵R的乘积:
[~, R] = qr(H', 0); R = R'; % 将R矩阵分区 R11 = R(1:i*l, 1:i*l); R21 = R(i*l+1:2*i*l, 1:i*l); R22 = R(i*l+1:2*i*l, i*l+1:2*i*l); % 投影矩阵等于 R21 O = R21;这里的数学含义是:投影矩阵的秩等于系统的可观测性秩,它的SVD分解结果直接反映了系统的空间信息。用QR分解代替直接投影计算,本质上是做了一个空间变换,把“过去”数据包含的信息通过正交化过程提取出来,数值稳定性大幅提升。
2.3 SVD截断与降阶:阶次到底怎么定
投影矩阵O得到后,对它做奇异值分解:
[ O = U S V^{T} ]
U和V是正交矩阵,S是对角阵,对角线上的元素是奇异值 ( s_{1} \ge s_{2} \ge \dots \ge s_{2i} \ge 0 )。奇异值的大小直接对应了系统状态的能量贡献。理想情况下,奇异值在达到实际系统阶次后会急剧下降,形成一个明显的“断崖”。这个“断崖”的位置就是应截断的阶次n。
但是实测数据永远不理想。噪声、微弱非线性、传感器误差都会让奇异值曲线变得平滑,没有明显的断崖。这时候就需要用“稳定图”来辅助定阶,而不是单纯依赖奇异值。稳定图的做法是:从小到大测试一系列阶次n,对每个阶次都识别出一组模态参数,然后把频率、阻尼、振型随阶次变化的轨迹画在一张图上。如果某个模态在连续多个阶次下频率和阻尼都保持稳定,就认为它是真实模态;如果散乱分布,就是噪声模态。
在MATLAB里,SVD截断和系统矩阵提取的代码如下:
[U, S, V] = svd(O); % 根据奇异值确定截断阶次 n n = n_determined; % 通过奇异值曲线或稳定图确定 U1 = U(:, 1:n); S1 = S(1:n, 1:n); V1 = V(:, 1:n); % 可观测性矩阵 Obs = U1 * sqrtm(S1); % 系统矩阵A的估计 A_est = Obs(1:l*(i-1), :) \ Obs(l+1:l*i, :); % 观测矩阵C的估计 C_est = Obs(1:l, :);关于定阶有个很重要的经验:奇异值截断时宁可把阶次取高一点,也别取低。取高了,后面稳定图可以筛掉虚假模态;取低了,真实模态直接丢失,数据想找都找不回来。这个原则对我处理实测结构数据非常有用,尤其是阻尼比接近的邻近模态。
2.4 从系统矩阵到模态参数:最后的冲刺
系统矩阵A的特征值分解是整个流程的收官一步。特征值是以共轭复数对出现的,每一对对应一个模态。对于连续时间系统,特征值 ( \lambda_{i} ) 与固有频率 ( \omega_{i} ) 和阻尼比 ( \zeta_{i} ) 的关系为:
[ \lambda_{i} = -\zeta_{i} \omega_{i} \pm j \omega_{i} \sqrt{1 - \zeta_{i}^{2}} ]
因此:
[ \omega_{i} = |\lambda_{i}|, \quad \zeta_{i} = \frac{-Re(\lambda_{i})}{|\lambda_{i}|}, \quad f_{i} = \frac{\omega_{i}}{2\pi} ]
如果数据是离散采样得到的,需要对特征值做对数和采样周期的换算。
振型的提取稍微复杂一些。特征值分解得到的特征向量是状态空间下的,需要映射回物理坐标。观测矩阵C的作用就在于此:将状态向量投影到观测空间,得到该模态在传感器位置处的振型分量。多个传感器通道排列起来,就是完整的振型向量。
这段逻辑用MATLAB实现:
[V_df, D_df] = eig(A_est); lambda = diag(D_df); frequencies = abs(angle(lambda)) / (2 * pi * dt); % 注意与采样间隔的关系 damping_ratios = -real(lambda) ./ abs(lambda) * 100; % 百分比 mode_shapes = C_est * V_df;需要特别提醒的是:特征值分解得到的模态顺序是随机的,不同阶次的匹配必须按照频率大小排序,而不是依赖特征值分解返回的顺序。这个细节如果忽略,稳定图的正确性会很受影响。
3. SSI-COV的实现与两条路线的差异
3.1 协方差Toeplitz矩阵的构建
SSI-COV的第一步是计算输出数据的协方差序列。对多通道数据 ( y_{k} ) 和 ( y_{k-j} ),协方差矩阵定义为:
[ R_{j} = E[y_{k} y_{k-j}^{T}] ]
在实际计算中,用有限时间平均来估计期望。理论上,协方差序列包含系统的全部动态信息,因为它们描述了不同时间延迟下输出之间的相关性。将这些协方差矩阵组合成一个分块Toeplitz矩阵:
[ T = \begin{bmatrix} R_{i} & R_{i-1} & \dots & R_{1} \ R_{i+1} & R_{i} & \dots & R_{2} \ \vdots & \vdots & \ddots & \vdots \ R_{2i-1} & R_{2i-2} & \dots & R_{i} \end{bmatrix} ]
这个Toeplitz矩阵的每一块对角线上的元素相同,体现了平稳随机过程的特性。
在MATLAB里,协方差计算最方便的途径是使用xcorr函数,但要注意归一化参数。不同的归一化方式会得到不同的协方差结果,直接影响后续SVD分解的奇异值大小和模态识别结果。我通常用biased选项,它除以采样点数N,保证协方差估计的一致性。
另外还有一个效率技巧:当通道数较多(比如超过8个)且采样点很多时,直接计算完整协方差矩阵的内存开销可观。可以考虑用多路并行计算每个通道对之间的协方差,然后在组装Toeplitz矩阵时再合并。我在一个48通道的项目里就用这个方法,内存占用降到原来的七分之一。
3.2 从Toeplitz矩阵到系统矩阵
SSI-COV的核心步骤与SSI-DATA相似,也是对Toeplitz矩阵做SVD分解:
function [A_est, C_est] = ssi_cov(y, i, n) % y: N x l 输出数据 % i: 块行数 % n: 模型阶次 l = size(y, 2); % 计算协方差序列 R = zeros(l, l, 2*i); for j = 0:2*i-1 R(:, :, j+1) = (y(j+1:end, :)' * y(1:end-j, :)) / (size(y,1) - j); end % 组装Toeplitz矩阵 T = zeros(i*l, i*l); for row = 1:i for col = 1:i T((row-1)*l+1:row*l, (col-1)*l+1:col*l) = R(:, :, i+row-col+1); end end % SVD分解 [U, S, ~] = svd(T); U1 = U(:, 1:n); S1 = S(1:n, 1:n); Obs = U1 * sqrtm(S1); % 提取系统矩阵 A_est = Obs(1:l*(i-1), :) \ Obs(l+1:l*i, :); C_est = Obs(1:l, :); end从数学本质上说,Toeplitz矩阵的SVD分解和投影矩阵的SVD分解是等价的,它们都包含了系统的可观测性子空间信息。但数值行为不同。SSI-COV先对数据做了协方差统计,相当于一个加权平均过程,在一定程度上平滑了噪声,但同时也可能模糊了接近的模态;SSI-DATA直接对原始数据运算,保留了更多细节,对弱模态的识别能力更强。
3.3 两种方法对比:数值稳定性与计算开销的取舍
我在一个三自由度模拟系统上做过对比实验,用的是2%阻尼比、频率分别为1.5Hz、2.3Hz和3.1Hz的结构,加入了5%的测量噪声。结果如下:
| 指标 | SSI-DATA | SSI-COV |
|---|---|---|
| 频率误差(1阶) | 0.12% | 0.31% |
| 频率误差(2阶) | 0.85% | 1.24% |
| 频率误差(3阶) | 2.3% | 3.8% |
| 阻尼比误差(均值) | 8.5% | 12.3% |
| 计算耗时(10通道,10万点) | 2.1s | 0.8s |
| 内存占用 | 高 | 低 |
这个结果符合理论预期:SSI-DATA精度更高,SSI-COV更快。如果你处理的是上百通道的长期监测数据,SSI-COV的高效性是很大的优势;如果你需要精确捕捉高频弱模态,SSI-DATA更合适。
实际工程中,我常用的策略是双轨并行:先用SSI-COV快速扫描一遍数据,确定大致频段和阶次范围;再用SSI-DATA做精细化分析,得到最终模态参数。两个结果互相验证,一旦出现明显分歧就说明数据质量有问题,需要回头检查传感器状态或数据预处理环节。这套流程帮我避免过不少因传感器通道故障导致的虚假模态问题。
4. 模拟数据验证与实测数据处理的关键环节
4.1 一个完整的仿真算例:从生成数据到模态识别
在把算法应用到真实结构之前,强烈建议先做一次仿真验证。仿真数据的好处是真实模态参数已知,可以明确评估算法的识别误差。下面我用一个4自由度质量-弹簧系统来展示完整流程。
系统参数设置:质量均为1kg,刚度分别为 ( k_{1}=1000 ), ( k_{2}=1500 ), ( k_{3}=2000 ), ( k_{4}=2500 ) N/m,比例阻尼使各阶阻尼比在1%~3%之间。用状态空间法生成响应:
% 质量矩阵、刚度矩阵、阻尼矩阵定义 M = diag([1, 1, 1, 1]); K = [3000, -1000, 0, 0; -1000, 3500, -1500, 0; 0, -1500, 4500, -2000; 0, 0, -2000, 4500]; % 比例阻尼 alpha = 0.3; beta = 0.0004; C_mat = alpha * M + beta * K; % 系统矩阵A_cont和C_cont n_dof = 4; A_cont = [zeros(n_dof), eye(n_dof); -M\K, -M\C_mat]; C_cont = zeros(n_dof, 2*n_dof); C_cont(:, 1:n_dof) = eye(n_dof); % 观测位移 % 离散化并模拟激励 dt = 0.01; sys_c = ss(A_cont, [zeros(n_dof); inv(M)], C_cont, 0); sys_d = c2d(sys_c, dt); % 生成白噪声激励 N = 20000; u = randn(n_dof, N); y = lsim(sys_d, u', 0:dt:(N-1)*dt); % 加入噪声 noise_level = 0.05 * std(y(:)); y_noisy = y + noise_level * randn(size(y));生成数据后,先用SSI-DATA识别模态参数,再和理论值对比。理论频率可以通过eig(K, M)计算得到。我在运行中常用的经验是,频率识别的相对误差在2%以内,阻尼比误差在10%以内,说明参数设置(i和n)合理。
4.2 实测数据的预处理:趋势项与噪声如何清理
仿真数据规规矩矩,实测数据却五花八门。直接拿原始加速度时程去跑SSI,大概率会得到一堆虚假模态。下面几个预处理步骤是我每次必做的:
去趋势项:传感器零漂和积分漂移都会产生低频趋势项,这些趋势项在SSI算法中会被识别为频率极低的虚假模态,干扰真实模态的判断。处理方法是用移动平均或多项式拟合扣除趋势。MATLAB里detrend函数可以处理线性趋势,但对于更复杂的趋势建议用sgolayfilt做平滑再相减,或者直接高通滤波(比如桥梁结构设0.1Hz高通)。
降采样:SSI的计算量随数据长度线性增长,而结构模态通常只在某个频段有意义。如果采样率是2000Hz,结构关注频段在0~50Hz,完全可以把数据降采样到200Hz。降采样前必须先抗混叠低通滤波,否则高频成分会折叠到低频段产生虚假谱峰。我在风电塔监测项目中把采样率从1280Hz降到256Hz,计算速度提升了约5倍,模态识别结果几乎没有变化。
异常值处理:信号尖峰、数据丢失和传感器饱和会导致输出中出现大幅异常值,这在SSI中的影响比在频域方法中更严重,因为时域协方差和投影对极端值非常敏感。我通常先做滑动窗口内的中值滤波或识别阈值超过5倍标准差的样本点,将其替换为局部均值。有一次在桥梁监测数据中,一个通道的加速度计因为螺栓松动出现了反复的脉冲尖峰,处理前SSI识别出的第一阶频率偏了约8%,处理后就完全正常了。
4.3 稳定图的使用:自动定阶的标准实践
稳定图的构造方法是:设定块行数i或模型阶次n从某个下限遍历到上限,对每一个阶次运行完整的SSI识别,得到一组模态参数。然后定义以下匹配判据:
- 频率稳定性:相邻阶次频率变化小于1%
- 阻尼稳定性:相邻阶次阻尼比变化小于5%或绝对差小于0.5%
- 振型稳定性:两个振型向量的MAC值大于0.95
满足三个判据的模态点标记为“稳定点”,画在以频率为横轴、阶次为纵轴的图上。稳定点连成竖线的地方就是真实模态。在MATLAB中,可以用mac函数计算两个振型之间的模态保证准则:
[ MAC(\phi_{i}, \phi_{j}) = \frac{|\phi_{i}^{H} \phi_{j}|^{2}}{(\phi_{i}^{H} \phi_{i})(\phi_{j}^{H} \phi_{j})} ]
我用的稳定图实现会同时标注频率偏差和阻尼偏差,颜色区分为“稳定”、“频率稳定但阻尼不稳定”、“完全不稳定”三类。这样即使不依赖自动聚类算法,人眼也能快速判断哪些是可信模态。
不过稳定图有一個陷阱:当块行数i增大时,同一真实模态会出现多次重复识别,产生许多虚假的“稳定点”。如果你设置了过宽的频率容差(比如2%),这些重复点就会互相混淆,导致把噪声模态也当作稳定模态。我推荐的容差是频率0.5%、阻尼比2%,并且对识别出的候选模态要求至少在连续4个阶次下都保持稳定。
5. 常见问题排查与实操避坑速查
5.1 频率识别出来了,阻尼比却不稳定
这是SSI方法最典型的“老大难”问题。频率由系统矩阵的特征值实部决定,对数据质量不是特别敏感;阻尼比由特征值实部与虚部的比值决定,而特征值实部受噪声影响极大,尤其是阻尼比本身很小时,微小误差就会引起百分比的大幅波动。
遇到这种情况,我的第一反应是检查传感器数量是否足够。SSI的阻尼比估计质量与可用通道数密切相关,通道太少时信息冗余不足,阻尼比的方差会显著增大。如果通道数确实受限,可以试试增加块行数i,增加观测数据的时间长度,或者对多个时段的数据取平均结果。但需要注意,阻尼比本质上就是难以辨识的参数,即使在理想情况下,误差在10%~20%也是正常的,不必追求像频率那样0.1%级别的精度。
5.2 稳定图上有“稳定轴”,但没有对应的物理模态
稳定图上偶尔会出现一条从低阶到高阶都保持稳定的“频率线”,但频率值不在理论或有限元预测范围内。这种情况多数不是真实模态,而是数据预处理不干净导致的。最常见的原因有两个:一是强单频干扰(比如工频50Hz附近),二是传感器局部共振。
处理这类问题的方法:先看频谱图确认该频率是否在所有测点中都出现且幅值突出,再看振型是否光滑合理。真实结构振型在空间上是有连续性的,相邻测点的振型分量不会突变;而局部干扰往往造成振型在某几个测点出现异常大值。另外,算法阶次取得过高也容易产生数值模态,主要分布在低频端和高频端,稳定图上的表现是稳定点稀少且不连续,这个可以通过合理约束阶次范围来抑制。
5.3 数据很长但识别结果反复变化
有些长期监测项目里,每个月跑一次SSI,结果频率小幅漂移、阻尼比大幅波动。这里除了环境温湿度变化导致的真实物理变化,还有数据分段和初始状态的影响。SSI假设系统是线性时不变的,但实际结构(尤其是桥梁)的边界条件会随温度变化而变化,这会导致模态参数季节性的漂移。
处理这种长期数据时,我建议固定分析参数(块行数、阶次范围、预处理流程),只改变数据窗口的起止时间,这样识别结果的差异才能归因于结构本身的变化,而不是算法设置的不同。同时要记录每次分析时的环境温度、风速等辅助数据,方便后续汇总分析时排除环境因素干扰。
5.4 模态识别结果“对不上”有限元模型
这个问题经常出现在论文评审或项目验收阶段。SSI识别出的模态与有限元模型计算模态存在偏差的时候,别急着怀疑算法不准。要意识到,有限元模型的频率往往比实测偏高,因为模型理想化了边界条件和材料参数;而SSI识别出的频率受实际环境附加质量(冰雪、附属设施)影响,一般会偏低。两者误差10%以内是相当合理的范围。
如果偏差太大,先检查传感器测点与有限元模型节点位置的对应关系——很多模型更新的错误源于测点编号错位。再检查振型相关性,用MAC矩阵对比识别振型与计算振型,如果MAC值普遍低于0.7,那很可能是传感器布置方向或者测点坐标有误。我在一个储罐项目就遇到过测点坐标标注错误的问题,排查了整整两天才发现是三维坐标中两个轴写反了。
5.5 计算时间过长,有没有加速办法
对于上百通道长期监测数据,SSI的计算量确实可观。几条经验供参考:
- 矩阵尺寸的源头控制:块行数i决定Hankel矩阵的块行数,理论上i超过系统阶次即可,没有必要设置成很大的值。过大的i不仅增加计算量,还会引入更多噪声子空间,降低识别精度。
- QR分解利用稀疏性:MATLAB的
qr函数对稀疏矩阵有专门优化,Hankel矩阵虽然是稠密的,但其结构具有带状特征,可以用sparse格式存储。 - 多数据段平均:把长时间数据切成重叠的小段,每段单独做SSI-DATA识别,然后对频率取统计平均,比直接用全量数据做一次识别更快,还能获得结果的方差估计。
6. 最后再分享几个实操体会
我做了这么多年数据驱动识别,最大的感受是:算法数学越“高级”,越要重视工程细节。SSI只是从数据到模态参数的通道,它的输出质量完全由数据质量决定。预处理做到位了,一个朴素的算法也能给出漂亮的结果;预处理潦草,再精细的模型更新都是空中楼阁。
工具链上,MATLAB的System Identification Toolbox里有n4sid等函数可以处理类似问题,但SSI算法的具体实现和框细节不一定完全符合你的需求。自己写一遍代码虽然费时间,但对理解算法逻辑的收益是现成工具箱代替不了的。我这边平时会在开源社区参考ssi相关的GitHub项目,结合项目需求做二次改造,效率很高。
如果你是第一次把这套流程用到真实结构上,我建议先找一段干净的小型结构数据(比如实验室里的简支梁),把仿真验证做扎实,再逐步过渡到现场实测。测点越多、数据越长,算法的稳定性越好。做现场测试时,传感器同步精度一定要注意,SSI对通道间的相位一致性很敏感,如果采集仪各通道之间的同步偏差超过采样间隔的一半,识别出的振型就会扭曲。
希望这篇文章能帮你把随机子空间方法的原理和实操打通。如果你在实现中遇到什么奇怪的报错或者不合理的识别结果,欢迎在评论区留言,我会尽量根据实际项目经验给出排查方向。