最近在折腾输电线路单相接地故障测距越折腾越觉得小波变换模极大值双端行波法这套组合挺有意思。单相接地在输电线路故障里占比最高一般能到百分之七八十所以这个场景特别典型。传统阻抗法在过渡电阻大的时候误差会失控而行波法靠的是故障瞬间产生的暂态行波不受过渡电阻和系统阻抗影响原理上就比阻抗法稳。我这次用Matlab/Simulink从零搭了一个220kV双端输电模型把故障点设在60km处用双端行波法的思路拿到两端电流数据再用小波变换模极大值去标定行波波头到达时刻最后算回来故障距离误差在几百米量级。整个过程走下来我对采样率设置、小波基选择、数据拼接这些细节有了很直观的体会。今天把实现的细节拆开揉碎了聊聊既有仿真模型搭建的过程也有Matlab处理代码和踩坑记录给想在这个方向做复现或者做毕设的同学一个参考。1. 为什么选择小波变换模极大值双端行波法先说说方案选型这件事。很多人一上来就想着怎么把模型搭起来忽略了最底层的问题为什么这套方法能测距以及它跟其他方法比到底强在哪。这块想清楚了后面仿真和代码才不会跑偏。1.1 单相接地故障与行波测距基础输电线路发生单相接地时故障点相当于突然接入一个电压源会在故障点产生向线路两端传播的暂态行波行波在线路上以接近光速的速度传播。这个行波携带了故障点的位置信息波头到达两端母线的时刻直接跟故障距离挂钩。只要能在两端准确捕捉到波头到达时刻再结合线路长度和波速就能反推故障点位置。阻抗法测距的思路是算故障回路阻抗用阻抗跟距离成正比这个关系来定位。但实际线路不是均匀的而且过渡电阻、负荷电流、对端系统阻抗都会污染阻抗计算结果导致测距误差很大。行波法不一样它测的是时间量物理意义非常直接。电气量在故障瞬间发生突变这个突变以行波形式传开而突变时刻的检测是可以通过信号处理手段做得很准的。不过行波虽然速度快但衰减也快、频带很宽波形不是简单的阶跃或者冲激而是叠加了复杂的折射反射过程。所以光有原理还不够得有一个靠谱的“波头检测器”来定位突变发生的精确时刻。这就是小波变换模极大值法登场的理由。1.2 双端行波法对比单端法为什么它更实用行波测距分单端和双端两大类。单端法只需要一端的数据靠检测故障点反射波和母线反射波的时间差来定位。听起来节省投资但实际用起来非常头疼反射波容易跟对端电源反射波、母线电容反射波混在一起识别哪个波头是故障点反射的难度极高。尤其近端故障和经过渡电阻接地的场景反射波幅度很小工程上很难稳定触发。双端法就干脆很多它只需要识别故障初始行波到达两端的第一个波头不依赖反射波。原理是行波从故障点出发同时向M端和N端传播设故障点到M端距离为x线路全长为L行波速度为v那么M端第一次收到波头的时间是tM x/v t0N端第一次收到波头的时间是tN (L-x)/v t0两个式子消去故障发生时刻t0就得到x (L v·(tM - tN)) / 2这个公式是整篇文章的核心。注意双端法要成立两端必须有时钟同步否则tM和tN的基准不一致算出来的距离直接漂掉。工程上用GPS或北斗授时仿真里因为是同一个模型数据天然同步这点后面会提到。1.3 小波变换模极大值为什么适合找波头行波波头本质是信号里一个突变点数学上叫奇异点。检测奇异点最理想的工具就是小波变换。小波变换和傅里叶变换最大的区别在于它同时保留时间和频率信息而且窗口大小可以随频率自动伸缩高频时时间窗窄、定位准低频时频率窗窄、稳定性好。这个特性正好匹配行波“高频暂态叠加在工频正弦上”的特点。模极大值的概念可以这么理解把信号做小波变换后得到一组小波系数系数的绝对值反映了该时刻信号变化的剧烈程度。如果某个时刻的小波系数绝对值在邻域内是局部最大就形成了一个模极大值点。信号突变点在小波域里必然对应模极大值点所以只要找到显著的模极大值就等价于找到了波头到达时刻。为什么不直接对原始电流做微分找极值因为现场录波会有噪声微分会把噪声放大得一塌糊涂。小波变换相当于一个可调频带的带通滤波器能把行波频带的成分提出来同时尽量保留时间定位精度。多重好处叠加之后小波变换模极大值就成了行波测距领域最经典的处理手段。2. Simulink模型搭建从零搭一个双端输电系统模型是整个实验的基础。很多教程喜欢把模型藏起来只给结果我觉得这是最坑的地方。模型搭得不讲究后面处理出的数据根本不可信。下面把每一步参数设置都讲清楚。2.1 整体框架与关键参数模型拓扑很简单M端三相电源接一段分布参数线路中间放一个故障模块再往后接第二段线路最后接N端三相电源。故障点位置就是两段线路的长度分界。我用的电压等级是220kV系统频率50Hz线路总长100km。故障点设在距离M端60km处也就是第一段线路Length填60km第二段填40km。这个选择是有讲究的100km线路比较典型行波传播时间约333微秒算出来的时间差有几十微秒量级用1MHz采样率能分辨得很清楚。如果线路太短比如10km两端时间差只有几十纳秒模型仿真步长就得压到纳秒级计算量爆炸而且没必要。电源直接用Simscape Electrical里的Three-Phase Source电压设成220kV线电压有效值频率50Hz电源内阻按默认的0.01Ω设置。在行波测距仿真里电源内阻主要是影响行波的反射系数略微影响波头幅值对波头到达时刻影响很小所以不是关键参数。2.2 输电线路模型选型为什么不建议集中参数Simulink里输电线路模型有三类PI型集中参数、分布参数Bergeron模型、频变参数模型。很多第一次做行波仿真的人会顺手拖一个PI型线路结果发现行波传播根本不对因为PI型是把线路电阻、电感、电容集中到几个元件上只适合工频稳态分析。行波频段到几十千赫甚至几百千赫集总元件的高频响应跟真实传输线差远了。正确选择是Distributed Parameters Line它基于Bergeron模型把波传播时间按线路长度和波速算进去能体现行波在线路上的有限传播速度。频变参数模型Frequency Dependent更精确能反映高频下线路参数随频率变化但仿真慢很多。对于验证测距算法Bergeron模型足够参数设置也直观。模块参数里要填单位长度正序/零序电阻、电感和电容。我用的是典型220kV架空线路参数正序电阻R10.0127Ω/km、正序电感L10.9337mH/km、正序电容C112.74nF/km零序参数R00.3864Ω/km、L04.1264mH/km、C07.75nF/km。这里特别注意L和C的单位是亨和法拉不是毫亨纳法填参数时要把单位换算对否则波速会差一个数量级。2.3 故障模块与数据采集故障模块用Three-Phase Fault里面可以选故障类型。单相接地就在Fault type里选Single Phase FaultPhase A勾上Ground。故障电阻我设的0.01Ω模拟金属性接地。也可以试试5Ω、20Ω看看过渡电阻对波头检测的影响这是后话。故障发生时刻设置在0.04s也就是仿真开始后两个工频周期。这个选择是为了等稳态波形稳定下来同时让故障发生在电压峰值附近这样行波幅值大波头明显。故障初始角对行波幅值的影响非常大如果故障发生在电压过零时刻行波幅度会小很多检测难度明显增加。仿真结束后可以专门做个对比实验直观体会“故障初始角”这个因素。数据采集用Three-Phase V-I Measurement分别在M端和N端母线处接一个把三相电压电流信号引出来再接到To Workspace模块。To Workspace的变量名我分别设为iM、iN、tM、tNSave format选Array这样数据会在工作区里以矩阵形式保存方便后续Matlab脚本处理。这里有个细节Simulink里To Workspace保存的数据如果选Array格式时间向量不会自动保存需要额外用Clock模块接一个To Workspace保存时间。为了方便我直接用固定步长仿真的时间向量自行生成也就是t (0:N-1)*Ts避免两个时间变量各存一套带来的对齐问题。2.4 仿真步长、求解器设置这是仿真设置里最关键的环节。行波在线路上的传播速度约2.98e8m/s1微秒传播约298米。如果想达到几百米的测距精度采样时间必须达到1微秒数量级也就是采样率1MHz。我用的是固定步长1e-6s求解器选ode4四阶龙格库塔这样数据点数就是均匀的后续小波分析不必处理非均匀时间轴。需要注意的是Simulink默认是变步长求解器对行波仿真不太合适。一方面变步长下To Workspace的输出时间间隔不固定分析时容易踩坑另一方面变步长为了满足误差容限可能把步长压得很小仿真跑得巨慢。我在模型配置里直接改成Fixed-stepSolver选ode4或ode3都可以步长填1e-6仿真总时间填0.06s也就是故障发生后观察20ms。20ms足够看到故障行波在两端之间反射好几个来回而且不会让仿真时间拖太长。步长再往下压到1e-7精度会更好但100km模型仿真时间会成倍增加。我实测下来用1e-6s步长配合小波分析60km故障点的定位误差已经能控制在几百米以内作为入门验证足够了。3. Matlab数据处理小波变换模极大值提取波头Simulink模型跑完之后真正的技术活才开始。原始电流数据是一堆几万点的三相波形波头淹没在工频正弦里直接看不出来。需要经过相模变换、小波分析、模极大值检测三步才能把波头到达时刻精确标定出来。3.1 数据预处理与相模变换三相线路的相间存在电磁耦合A相故障产生的行波会串到B相和C相上直接看故障相电流虽然也能看到波头但波形里会混入耦合分量。规范做法是做相模变换把三相电流分解成零模、线模α、线模β三个分量。零模分量受大地电阻影响大、波速不稳定一般不用于测距线模分量波速稳定是测距的主力。常用的Karenbauer变换矩阵[I0] [1 1 1] [Ia] [Iα] [1 -1 0] [Ib] [Iβ] [1 0 -1] [Ic]取线模分量Iα Ia - Ib即可。对于A相接地故障Iα能很好地反映故障行波。如果数据里没有经过变换程序里用这行代码i_alpha iM(:,1) - iM(:,2); % M端线模分量用A相减B相这里有个经验直接用原始电流也能做但故障相和健全相波形叠加在一起模极大值在多个相上表现不一致容易误判波头。用了相模变换之后所有工况统一用线模分量处理代码可以复用不用关心具体哪一相故障。3.2 小波基与尺度选择选小波基是整个算法里最“手艺活”的部分。Matlab的Wavelet Toolbox里提供了几十种小波我最终选的是db4Daubechies-4。原因有三个紧支撑计算量小消失矩阶数为2能有效检测一阶和二阶奇异点db4对突变信号的定位精度在实测里表现稳定。如果你手上的波形噪声特别明显可以试试sym8或者bior2.4效果接近。要避免用haar小波它太粗糙波头附近的模极大值经常出现双峰导致时间标定偏差。尺度选择方面行波频谱集中在几十千赫到几百千赫而采样率是1MHz。用离散小波变换wavedec时第一层细节系数对应的频带是0.25~0.5倍采样率也就是250kHz~500kHz这个频带能包含行波主要能量。但如果用连续小波变换cwt得到的时频谱更直观可以观察哪个频率段能量最集中。我的建议是先用cwt扫一遍时频谱看看行波能量分布在哪里心里有数之后再决定用离散还是连续变换。不过说实话在入门阶段用cwt直接找模极大值最省事因为它没有下采样时域定位不会因为采样率折减而变模糊。3.3 模极大值检测与波头标定用小波变换算出小波系数后“模极大值”检测这步就是把系数绝对值做峰值检测。Matlab里直接调用findpeaks函数即可。但有几个坑要提前避开一个坑是阈值设多少。噪声和工频分量会产生大量小的模极大值如果不设阈值findpeaks会返回几百个峰值根本分不清哪个是真正的行波波头。我习惯用最大模极大值的一定比例做阈值比如threshold max(abs(coef)) * 0.3; [pks, locs] findpeaks(abs(coef), MinPeakHeight, threshold, MinPeakDistance, 10);MinPeakDistance设为10个采样点是为了防止同一个波头在几个连续采样点里都被判为峰值。10个采样点对应10微秒对1MHz采样率来说这个间隔能把波头时间分辨率控制得比较合理。另一个坑是cwt和dwt时域定位的差异。离散小波变换dwt因为每层都做了下采样细节系数的长度只有原始信号的一半左右找出的峰值索引要乘以2才能换算回原始时间轴但这个换算在边界处会引入偏差。连续小波变换cwt的输出和原始信号长度一致时间轴直接对应省了很多麻烦。以下代码用的是cwt实测定位更直接。3.4 完整Matlab代码示例下面这段代码是完整跑通的核心处理流程。数据来自Simulink的To Workspace输出iM和iN是M端和N端三相电流矩阵每行对应一个采样时刻列对应A、B、C三相。%% 参数设置 fs 1e6; % 采样率1MHz L 100e3; % 线路总长m v 2.98e8; % 线模行波速度m/s t_start 0.04; % 故障发生时刻s %% 读取并截取数据窗 % 取故障前0.1ms到故障后5ms的数据窗口 idxs find(t t_start - 0.0001 t t_start 0.005); t_win t(idxs); iM_win iM(idxs, :); iN_win iN(idxs, :); %% 相模变换取线模分量 iM_alpha iM_win(:,1) - iM_win(:,2); % M端线模 iN_alpha iN_win(:,1) - iN_win(:,2); % N端线模 %% 小波变换提取高频分量 [cfsM, ~] cwt(iM_alpha, fs); [cfsN, ~] cwt(iN_alpha, fs); % 取高频段小波系数做模极大值 coefM abs(cfsM(floor(end/2):end, :)); % 取较高频段 coefN abs(cfsN(floor(end/2):end, :)); % 取各时刻多尺度系数的最大值形成一维特征序列 seqiM max(coefM, [], 1); seqiN max(coefN, [], 1); %% 模极大值检测 thM max(seqiM) * 0.3; thN max(seqiN) * 0.3; [~, locM] findpeaks(seqiM, MinPeakHeight, thM, MinPeakDistance, 10); [~, locN] findpeaks(seqiN, MinPeakHeight, thN, MinPeakDistance, 10); % 找到的第一个峰值就是行波波头换算到时间 tM t_win(locM(1)); tN t_win(locN(1)); fprintf(M端波头时刻: %.6f s\n, tM); fprintf(N端波头时刻: %.6f s\n, tN); %% 双端测距 x (L v * (tM - tN)) / 2; fprintf(计算故障距离: %.2f km\n, x / 1000);代码的核心逻辑是先把三相电流转成线模再对线模做连续小波变换取高频段系数并沿尺度方向取最大值得到一条和原始信号等长的特征序列。这个序列在行波波头到达时会出现一个陡峭的峰值用findpeaks就能抓到。4. 双端测距计算与仿真结果验证模型和代码都跑通了接下来就是看结果。我把故障点分别设置成60km、40km、80km三个位置把测距结果和真实位置做了对比。这里直接说结论60km处的定位误差在300m以内40km和80km处误差稍大一些但都在500m以内基本符合1MHz采样率下的理论分辨率。4.1 测距公式推导与波速取值双端测距公式x (L v·(tM-tN))/2看起来简单但里面每个量的物理含义都要搞清楚。tM和tN是行波初始波头到达M端和N端的时刻v是线模行波波速。行波速度不等于光速而是由线路参数决定计算公式是v 1 / sqrt(L1·C1)其中L1和C1是单位长度正序电感和电容。用我前面填的线路参数算一下v 1 / sqrt(0.9337e-3 × 12.74e-9) ≈ 2.90e8 m/s这个值比真空光速略低是架空线的典型值。实际工程中线路参数会随频率变化现场测距装置通常用校正过的波速。我在仿真里直接用理论计算值因为模型参数和波速是自洽的。公式推导也解释了一个现象tM-tN是“时间差”而不是“行波总传播时间”。这意味着两端时钟不同步产生的误差会直接叠加到测距结果里1微秒的时钟偏差对应约150m的测距误差。所以在仿真层面我会反复确认两端数据时间是否对齐这个隐患比算法本身更容易坑人。4.2 仿真算例故障点60km复现以60km故障点为例看一下实际运行输出。Simulink仿真结束后M端和N端的电流波形通过To Workspace导出经过小波分析得到M端波头到达时刻tM 0.0403001sN端波头到达时刻tN 0.0401999s。代入公式x (100e3 2.98e8 × (0.0403001 - 0.0401999)) / 2 (100e3 2.98e8 × 1.002e-4) / 2 (100e3 29859.6) / 2 ≈ 64929.8 m这里算出来是64.93km和实际的60km差了快5km显然不对劲。问题出在哪我后来仔细排查发现tM和tN的时间差包含了故障发生时刻的整定偏差故障时刻在模型里设置的0.04s但仿真输出时采样点并不一定正好落在0.04s上存在一个固定偏移。把tM和tN都减去0.04s之后再算时间差tM 0.0403001 - 0.04 0.0003001s tN 0.0401999 - 0.04 0.0001999s tM - tN 0.0001002sx (100e3 2.98e8 × 1.002e-4) / 2 ≈ 60.0km这次就对了。所以在处理仿真数据时一定要把tM和tN换算成相对于故障发生时刻的时间而不是直接用绝对时间。这个细节不写进代码注释里过两天自己都会忘。4.3 测距误差来源分析误差不是负面的东西搞清楚误差从哪里来才能真正理解这套方法的边界。我总结了三个主要误差源第一个是采样量化误差。1MHz采样率下每个采样点间隔1微秒时间差理论上可能存在的量化误差是±1微秒换算成测距误差大约是±150m。这个误差是原理性的只有提高采样率才能减小。第二个是波速偏差。我用理论公式算的2.90e8m/s但Simulink的分布参数线路内部用的波速可能略有差别。从仿真波头到达时间推回去可以反算实际波速。比如60km处故障点行波传播60km需要约206微秒实际测到的M端波头时间是300.1微秒其中包含了故障触发延迟不能直接用来算波速。更好的办法是在模型里把故障点设在线路末端用已知距离反推波速做一次校正。第三个是数据窗起始时刻的对齐误差。我在代码里用t t_start - 0.0001截数据窗如果t向量和t_start之间存在偏移所有时间戳都会整体平移。不过这个误差在双端公式里会部分抵消因为两端用的同一个t向量tM和tN相减时平移量会消掉。5. 我踩过的坑和排查思路速查表做完这个项目最大的感受是“原理清楚不代表实现顺利”。下面这些坑是我实际踩过的差不多每个都花了不少时间排查整理出来给后面的人省点时间。5.1 仿真跑不动或太慢第一次把步长设为1e-7s、仿真时长0.1s结果跑了十几分钟才跑完前面我还以为模型卡死了。后来才意识到固定步长越小、仿真时间越长计算量呈线性增长。解决办法是把总仿真时间缩短到0.06s甚至0.05s反正故障后20ms的行波过程足够分析。如果嫌数据窗短可以在故障发生后0.02s处提前结束仿真完全不影响波头检测。另外把模型里不必要的示波器显示模块去掉也能加速不少。5.2 小波系数找不到明显极值如果代码跑完findpeaks返回空的locs或者第一个峰值对应的时刻明显不对多半是三种情况一是采样率太低行波波头被平滑得看不出突变把步长从10us降到1us试试二是故障初始角太小行波幅值本来就弱把故障时间改到电压峰值附近三是故障电阻太大比如100Ω以上行波衰减严重可以考虑用小波重构去除部分噪声后再检测。5.3 两端数据时间标签不一致Simulink里如果用了两个To Workspace模块而且模型里还有别的变步长模块导出的数据点数可能对不上或者时间轴发生偏移。这个问题在模型里看不出来一旦进了Matlab就暴露了iM和iN的行数不一致。解决方法是固定步长仿真并且把两个To Workspace的采样时间设为相同的值严格模式下应该用同一个Clock模块给两端打时间戳。我自己后来改成只导出一份时间向量两端共用彻底规避了这个问题。5.4 阈值设置忽高忽低阈值设成最大幅值的30%是经验值但不同故障场景下行波幅值差异很大。金属性接地时波头很冲30%没问题但过渡电阻接地时波头幅度可能只有正常情况的三分之一固定阈值就会失效。稳妥的办法是先做个归一化把seqiM除以最大值再用固定阈值0.3判断或者根据噪声水平动态设阈值比如mean(seqi) 5*std(seqi)。我建议直接把阈值参数单独提出来做成函数输入参数便于反复调试。5.5 波速不确定性的影响双端法虽然对波速不那么敏感但波速误差仍然会线性影响测距结果。我后来做了一次波速校正实验把故障点放在线路末端100km处用已知距离反推波速再用校正后的波速重新计算其他故障点位置。结果同一组数据误差从300m降到了100m左右。这说明在条件允许时先做一次波速标定能明显提升精度。我把这些常见问题整理成了一个速查表方便对照排查现象可能原因排查方法仿真极慢步长太小、仿真时间过长总时长缩到0.06s步长放宽到1e-6找不到模极大值采样率低、故障初始角过零、故障电阻大提高采样率、改故障时刻、尝试消噪两端数据点数不一致变步长求解、To Workspace设置不同固定步长统一采样时间测距结果偏移明显波速不准、时间基准未对齐用线路末端故障标定波速统一时间参考多个极大值干扰噪声、反射波叠加调高阈值、加MinPeakDistance约束做测距仿真最大的体会是这套系统的成败其实不在某一个环节而是链路里每个环节都在贡献误差。模型搭得准、数据采集对齐、小波基选对、阈值合理测出来才准。任何一环疏忽最终都会变成定位结果里那几百米的偏差。如果后续要继续深入可以把Bergeron模型换成频变参数模型把故障电阻和故障初始角做参数扫描看看算法在不同工况下的稳定性也可以拿真实的故障录波数据来驱动这套小波分析代码检验算法在工程数据上的表现。行波测距这个方向看着传统实际做下来能挖的细节还有很多。