简介:这份资源面向电力系统保护与控制领域的研究人员、工程师及配电网故障检测方向的技术人员,聚焦谐振接地系统中两点同相接地与高阻接地两类复杂单相接地故障的选线及定位难题。内容围绕零序等效网络与高阻故障建模展开,针对两点同相接地提出基于零序电流暂态量和过渡电阻特征的选线思路,针对高阻故障则采用变模态分解法结合对地电容参数特征完成选线与定位,并配有可运行的Python代码实现,涵盖系统建模仿真、VMD选线算法与故障定位流程,仿真结果验证了方法的抗干扰能力与适用性。资源包为1个docx文档,约54KB,结构紧凑,便于对照理论推导与代码实现同步学习。目前已有38人学习,适合希望快速掌握复杂接地故障选线定位方法、并借助代码复现验证的读者参考。
1. 谐振接地系统里,为什么两点同相接地和高阻接地总让选线算法集体翻车
10kV 配电网里跑谐振接地(经消弧线圈接地)的人,多半都经历过这种场面:变电站报单相接地,选线装置却一会儿报线路 A、一会儿报线路 B,甚至干脆不报;运维到现场拿钳形表一卡,零序电流小得可怜,波形还畸变。问题往往不在装置本身,而在于故障不是教科书里那种"理想单相金属性接地"。谐振接地系统为了抑制弧光过电压,人为把中性点经消弧线圈调谐到接近全补偿,故障点的容性电流被感性电流抵消,故障线路的零序电流特征被大幅削弱。这时候再叠加两点同相接地(两条线路不同位置同时接地)或高阻接地(过渡电阻几百欧到几千欧),传统基于零序电流幅值或群体比幅比相的选线方法基本失效。
这篇文章要讲的就是这两类复杂故障的选线及定位怎么做。核心思路是把零序电流做变模态分解(VMD),提取暂态特征频带,再结合稳态无功方向做综合判据,最后用行波或阻抗法做故障定位。适合正在做配网自动化、选线装置算法开发,或者被现场误选困扰的运维工程师。下面从原理到代码一步步拆,能复现的我都给可跑的 Python 片段。
2. 谐振接地系统单相接地故障的电气特征与选线难点
2.1 消弧线圈补偿后零序电流到底还剩什么
要理解选线为什么难,得先把谐振接地系统的零序回路算清楚。中性点经消弧线圈接地后,单相接地时故障点流过的电流是全网对地电容电流与消弧线圈电感电流的矢量和。设全网单相对地电容为 $C_\Sigma$,消弧线圈电感为 $L$,脱谐度 $v = 1 - \frac{1}{\omega^2 L C_\Sigma}$。当 $v \approx 0$(全补偿)时,故障点基波电流接近零,故障线路首端的工频零序电流也接近零。
但注意,零序电流并不是完全消失,它还剩三部分:
- 暂态分量:故障瞬间电容充电产生的高频振荡,频率通常在 300Hz~3kHz,衰减时间常数几毫秒到几十毫秒。这部分不受消弧线圈基波补偿影响,是选线的主要信息源。
- 有功分量:消弧线圈和线路本身有电阻,产生一个与零序电压同相的微小有功电流,幅值约为容性电流的 2%~5%。
- 五次谐波分量:消弧线圈对五次谐波呈感性且阻抗大,补偿效果弱,五次谐波零序电流仍保留较明显的方向特征。
所以选线算法的信息基础,本质上就是暂态、有功、五次谐波这三块。传统装置只用工频幅值比,自然在复杂故障下翻车。
2.2 两点同相接地为什么让方向判据失效
两点同相接地指的是同一相在两条不同线路的不同位置同时接地。此时系统形成两个故障点,零序电压由两个接地点共同决定,零序电流的分布不再是"故障线路流向母线、非故障线路流出母线"的简单模式。
具体表现是:两条故障线路的零序电流方向可能一个超前一个滞后,群体比相时相位关系混乱;非故障线路的零序电流反而可能因为两个故障点的电位差而出现异常幅值。更麻烦的是,两个接地点之间的线路段会有穿越性零序电流,让基于"故障线路零序电流最大"的判据直接失效。
工程上识别两点接地的一个实用特征是:零序电压波形出现明显的非正弦畸变,且各线路零序电流的 3 次谐波含量同时升高。因为两个接地点形成的回路对 3 次谐波呈现低阻抗,3 次谐波零序电流会显著增大。
2.3 高阻接地为什么把暂态特征也吃掉了
高阻接地(过渡电阻 $R_f$ 通常 500Ω~5kΩ)的问题是它同时削弱暂态和稳态特征。过渡电阻串在故障回路里,对高频暂态分量形成强阻尼,暂态零序电流的幅值随 $R_f$ 增大迅速衰减,衰减时间常数也变短。当 $R_f$ 超过 1kΩ 时,很多线路的暂态零序电流已经接近测量噪声水平。
稳态方面,高阻使零序电压降低,零序电流的有功分量和无功分量同步减小。这时候如果装置零序电流互感器(零序 CT)精度不够,或者存在不平衡电流,选线就完全靠运气。
应对高阻接地的常见做法是:降低选线判据的幅值门槛,改用波形相似度或能量占比作为判据,同时提高采样率以保留暂态细节。下面这张表对比了三类故障的特征差异,是后面算法参数设置的依据。
| 故障类型 | 零序电压 | 暂态零序电流 | 工频零序电流 | 五次谐波 | 主要可用特征 |
|---|---|---|---|---|---|
| 金属性单点 | 高 | 强 | 弱(全补偿) | 中等 | 暂态+五次谐波 |
| 两点同相 | 中高、畸变 | 中等 | 混乱 | 强 | 3次谐波+暂态 |
| 高阻单点 | 低 | 弱 | 极弱 | 弱 | 波形相似度+能量 |
3. 用 VMD 分解零序电流提取暂态特征频带
3.1 为什么选 VMD 而不是 EMD
变模态分解(VMD)在选线里的价值,是把零序电流这种非平稳信号分解成若干个有限带宽的模态分量(IMF),每个模态对应一个中心频率。相比经验模态分解(EMD),VMD 的模态数和中心频率可以预先设定,不会出现模态混叠,这对特征频带提取很关键。
选线场景下,我们关心的是暂态特征频带,通常在 300Hz~3kHz。用 VMD 把零序电流分解成 4~6 个模态,然后按中心频率筛选出落在特征频带的模态,计算其能量占比。故障线路的特征频带能量占比通常高于非故障线路,这是核心判据。
VMD 的关键参数有两个:模态数 $K$ 和惩罚因子 $\alpha$。$K$ 太小会欠分解,特征频带和其他频带混在一起;$K$ 太大会过分解,产生虚假模态。工程上 $K$ 取 4~6,$\alpha$ 取 2000 左右比较稳。下面给一个可跑的 VMD 实现。
import numpy as np from vmdpy import VMD def vmd_feature(zero_seq_current, fs=10000, K=5, alpha=2000): """ 对零序电流做VMD分解,返回各模态及特征频带能量占比 zero_seq_current: 一维零序电流数组 fs: 采样率(Hz) K: 模态数 alpha: 惩罚因子 """ # VMD要求输入为实数,tau=0表示无噪声约束,DC=0不允许直流 u, u_hat, omega = VMD(zero_seq_current, alpha, 0, K, 0, 1, 1e-7) # u shape: (K, N),omega shape: (K, 迭代次数),取最后一列为中心频率 center_freqs = omega[:, -1] * fs / (2 * np.pi) # 特征频带 300Hz ~ 3000Hz band_mask = (center_freqs >= 300) & (center_freqs <= 3000) total_energy = np.sum(u ** 2) band_energy = np.sum(u[band_mask] ** 2) ratio = band_energy / total_energy if total_energy > 0 else 0 return u, center_freqs, ratio # 示例:读取某条线路零序电流 # i0 = np.loadtxt('line1_i0.csv') # u, freqs, ratio = vmd_feature(i0) # print('中心频率:', freqs) # print('特征频带能量占比:', ratio)逻辑说明:VMD 函数返回的u是各模态时域波形,omega是每次迭代的中心频率。取最后一次迭代的中心频率换算成 Hz,筛选落在 300~3000Hz 的模态,计算这些模态能量占总能量的比例。参数说明:fs必须和实际采样率一致,否则中心频率换算错误;K=5是经验值,线路短、暂态频率高时可取 6;alpha=2000控制带宽,越大带宽越窄,高阻接地时信号弱可适当减小到 1500 以保留更多能量。
3.2 特征频带能量占比的选线判据怎么设阈值
算出每条线路的特征频带能量占比后,怎么判定哪条是故障线路?直接用最大值容易受噪声干扰。工程上常用两种判据结合:
- 相对判据:故障线路的能量占比应大于所有线路能量占比均值的 1.5 倍,且大于次大值的 1.2 倍。
- 绝对判据:故障线路能量占比应大于 0.3,否则认为信号太弱,判据不可信,转用其他方法。
这两个阈值不是拍脑袋来的。0.3 的绝对门槛来自大量现场录波统计:金属性接地时故障线路占比通常在 0.5~0.8,高阻接地时可能降到 0.3~0.4,低于 0.3 基本淹没在噪声里。1.5 倍和 1.2 倍的相对门槛是为了防止两条线路占比接近时误判,这在两点同相接地时特别重要。
实际部署时,建议把每条线路的占比和阈值都存进录波文件,方便事后复盘。下面这段代码给出完整的判据逻辑。
def select_fault_line(ratios, line_names): """ ratios: 各线路特征频带能量占比列表 line_names: 线路名称列表 返回: 故障线路候选及置信度 """ ratios = np.array(ratios) mean_r = np.mean(ratios) sorted_idx = np.argsort(ratios)[::-1] max_r = ratios[sorted_idx[0]] second_r = ratios[sorted_idx[1]] # 绝对判据 if max_r < 0.3: return None, 'energy_too_low', ratios # 相对判据 if max_r > 1.5 * mean_r and max_r > 1.2 * second_r: return line_names[sorted_idx[0]], 'confident', ratios else: return line_names[sorted_idx[0]], 'ambiguous', ratios # 示例 # names = ['L1','L2','L3','L4'] # result, conf, r = select_fault_line([0.12,0.55,0.10,0.23], names) # print(result, conf)逻辑说明:先排序拿到最大和次大占比,再依次判断绝对门槛和相对门槛。返回ambiguous时说明判据不可靠,需要引入五次谐波或稳态无功方向做二次确认。参数说明:1.5和1.2这两个系数在两点同相接地场景可以适当放宽到1.3和1.1,因为两点接地时能量分散,故障线路占比不会特别突出。
4. 两点同相接地与高阻接地的综合选线策略
4.1 用五次谐波和 3 次谐波区分故障类型
前面提到,两点同相接地会让 3 次谐波零序电流显著增大,而高阻接地会让五次谐波也变弱。所以选线前先做一个故障类型粗判,能大幅提高后续判据的针对性。
粗判逻辑:计算各线路零序电流的 3 次谐波含量比(3 次谐波幅值 / 基波幅值)和五次谐波含量比。如果所有线路的 3 次谐波含量比普遍高于 0.15,且零序电压波形畸变率大于 5%,判为疑似两点同相接地;如果五次谐波含量比低于 0.05 且零序电压低于额定相电压的 30%,判为疑似高阻接地。
这个粗判不需要很精确,它的作用是决定后面用哪套参数。两点同相接地时,VMD 的 $K$ 取 6,特征频带下限降到 200Hz 以捕捉 3 次谐波附近的能量;高阻接地时,$K$ 取 4,$\alpha$ 降到 1500,并且把波形相似度作为主判据。
def harmonic_ratio(signal, fs, f0=50, order=3): """计算指定次谐波含量比""" N = len(signal) freqs = np.fft.rfftfreq(N, 1/fs) spectrum = np.abs(np.fft.rfft(signal)) fund_idx = np.argmin(np.abs(freqs - f0)) harm_idx = np.argmin(np.abs(freqs - f0 * order)) fund = spectrum[fund_idx] harm = spectrum[harm_idx] return harm / fund if fund > 1e-6 else 0 def classify_fault(i0_list, u0, fs): """粗判故障类型""" r3 = np.mean([harmonic_ratio(i, fs, order=3) for i in i0_list]) r5 = np.mean([harmonic_ratio(i, fs, order=5) for i in i0_list]) u0_rms = np.sqrt(np.mean(u0 ** 2)) if r3 > 0.15 and u0_rms > 0.3 * 57.7: return 'two_point' elif r5 < 0.05 and u0_rms < 0.3 * 57.7: return 'high_resistance' else: return 'normal'逻辑说明:用 FFT 取基波和各次谐波幅值算比值。57.7是 10kV 系统相电压有效值(kV),实际用标幺值或实际值要统一。参数说明:3 次谐波门槛 0.15 和五次谐波门槛 0.05 来自现场统计,不同系统可能有差异,建议先用历史录波校准。
4.2 波形相似度判据在高阻接地下的用法
高阻接地时能量判据容易失效,这时候改用波形相似度。原理是:非故障线路的零序电流主要由本线路对地电容决定,波形相似;故障线路的零序电流包含故障点电流,波形与非故障线路差异大。用皮尔逊相关系数衡量各线路零序电流两两之间的相似度,相似度最低的那条就是故障线路。
具体做法:取故障后一个工频周期的零序电流,计算所有线路两两之间的相关系数矩阵,对每条线路求它与其他线路相关系数的均值,均值最小的判为故障线路。这个方法在高阻接地时比能量判据稳,因为相关系数对幅值不敏感,只看波形形状。
def waveform_similarity_select(i0_matrix): """ i0_matrix: shape (n_lines, n_samples) 返回相似度均值最低的线路索引 """ n = i0_matrix.shape[0] corr = np.corrcoef(i0_matrix) # 排除对角线 mean_corr = (np.sum(corr, axis=1) - 1) / (n - 1) return np.argmin(mean_corr), mean_corr # 示例 # idx, mc = waveform_similarity_select(i0_matrix) # print('故障线路索引:', idx, '相似度均值:', mc)逻辑说明:np.corrcoef直接算相关系数矩阵,对角线是 1,减掉后求均值。故障线路因为波形独特,与其他线路相关性最低。参数说明:样本长度建议取一个工频周期(20ms),采样率 10kHz 时是 200 点;如果采样率低,可以取两个周期。注意这个方法要求各线路零序 CT 极性一致,否则相关系数会反号,需要先做极性校验。
4.3 综合判据的投票机制与置信度输出
单一判据都有失效场景,工程上常用投票机制:能量判据、相似度判据、五次谐波方向判据各投一票,得票最多的线路判为故障线路,同时输出置信度(得票数 / 总判据数)。如果最高票数不过半,输出"选线不确定",提示人工介入。
这套机制在两点同相接地时特别有用:能量判据可能投给线路 A,相似度判据投给线路 B,五次谐波方向可能投给 A 或 B,最终结果虽然可能只覆盖一个故障点,但至少不会给出完全错误的单一结论。实际运行中,两点同相接地的两个故障点往往需要靠定位算法分别确定,选线阶段能缩小到两条线路就算成功。
5. 选线之后的故障定位:从行波到阻抗法的落地选择
5.1 行波法在谐振接地系统里的适用边界
选线确定故障线路后,定位是下一步。行波法测距精度高,但在谐振接地系统里有边界:消弧线圈对行波波头有衰减,且配网线路分支多,行波在分支点的折射反射会让波头识别困难。行波法更适合线路结构简单、分支少的架空线路,且要求采样率不低于 1MHz。
如果现场条件满足,行波法双端测距的公式是 $x = \frac{L + v(t_1 - t_2)}{2}$,其中 $L$ 是线路全长,$v$ 是行波波速(架空线约 2.9×10^8 m/s),$t_1$、$t_2$ 是两端检测到的初始波头时刻。难点在波头标定,建议用模极大值法配合小波变换。
5.2 阻抗法定位在高阻接地下的参数修正
高阻接地时行波法信号弱,改用阻抗法。阻抗法通过测量故障线路首端的零序电压和零序电流,计算故障回路阻抗,再换算故障距离。谐振接地系统里,零序阻抗受消弧线圈影响,公式要修正:
$$x = \frac{3 U_0}{I_0 \cdot z_0} \cdot \frac{1}{1 + j\omega L / (3 z_0 l)}$$
其中 $z_0$ 是线路单位长度零序阻抗,$l$ 是线路长度,$L$ 是消弧线圈电感。实际工程中,这个修正系数可以预先按线路参数算好,做成查表。高阻接地时,过渡电阻会叠加进测量阻抗,导致测距偏大,需要用迭代法扣除过渡电阻估计值。
def impedance_locate(u0, i0, z0_per_km, line_len, L_coil, f=50): """ 阻抗法定位,返回故障距离估计(km) u0, i0: 首端零序电压(V)、零序电流(A)相量 z0_per_km: 单位长度零序阻抗(ohm/km) line_len: 线路全长(km) L_coil: 消弧线圈电感(H) """ w = 2 * np.pi * f z_meas = u0 / i0 if abs(i0) > 1e-6 else 0 # 消弧线圈修正系数 k = 1 / (1 + 1j * w * L_coil / (3 * z0_per_km * line_len)) z_corrected = z_meas * k x = abs(z_corrected) / abs(z0_per_km) return min(x, line_len) # 示例 # dist = impedance_locate(3000+0j, 2+0j, 0.5+1.2j, 10, 2.0) # print('故障距离:', dist, 'km')逻辑说明:先算测量阻抗,再乘消弧线圈修正系数,最后按单位长度零序阻抗换算距离。参数说明:z0_per_km要用复数,实部是电阻、虚部是电抗;L_coil从消弧线圈铭牌取;高阻接地时u0/i0的相量估计要用全周傅里叶算法,避免用瞬时值。
6. 避坑与排查:现场调试最容易踩的五个坑
6.1 零序 CT 极性接反导致相似度判据全乱
现象:波形相似度判据选出的故障线路和能量判据完全相反,且每次故障结果不稳定。原因:部分线路零序 CT 的 S1、S2 接反,导致该线路零序电流相位反 180°,相关系数矩阵出现负值。解决:投运前用一次侧通流试验校验所有零序 CT 极性,或在算法里加自动极性识别——如果某条线路与其他线路相关系数普遍为负,先翻转其符号再计算。
6.2 VMD 模态数设太大产生虚假模态
现象:特征频带能量占比计算出来所有线路都接近,无法区分。原因:$K$ 设成 8 或 10,VMD 过分解,把噪声也分解成模态,特征频带能量被稀释。解决:$K$ 控制在 4~6,先用一段已知故障录波试,看中心频率分布,如果出现两个模态中心频率很接近,说明 $K$ 偏大。
6.3 采样率不够导致暂态特征丢失
现象:高阻接地时所有判据都失效,录波看暂态分量几乎看不到。原因:装置采样率只有 2kHz,而暂态特征频带在 300Hz~3kHz,2kHz 采样率下 1kHz 以上信号已经混叠。解决:选线装置采样率至少 10kHz,最好 20kHz;如果装置已定型,改用五次谐波和波形相似度作为主判据,放弃暂态能量判据。
6.4 消弧线圈补偿状态变化后判据阈值未更新
现象:同一线路,消弧线圈从过补偿切到全补偿后,选线准确率明显下降。原因:全补偿时工频零序电流更小,原来按过补偿整定的能量占比阈值不再适用。解决:把脱谐度作为参数传入算法,不同脱谐度区间用不同阈值表;或者干脆只用暂态和五次谐波判据,这两者对脱谐度不敏感。
6.5 两点同相接地时误判为单点故障导致定位错误
现象:选线选出线路 A,但定位结果在线路 A 上找不到故障点,实际故障点一个在 A 一个在 B。原因:选线阶段只输出了得票最高的线路,没有提示可能存在多点接地。解决:当选线置信度低于 0.6 且 3 次谐波含量比偏高时,输出"疑似多点接地"告警,提示运维对得票前两位的线路都进行巡视;定位算法也要支持多故障点假设,用聚类方法分离两个故障点。
7. 把判据阈值做成自适应:一个可复用的参数整定技巧
上面所有判据都依赖阈值,而阈值随系统运行方式变化。我一般不在代码里写死阈值,而是做一个自适应整定模块:每次系统正常运行时,采集一段零序电流作为背景噪声,计算各线路能量占比和相似度的统计分布,取均值的 3 倍标准差作为动态门槛。这样消弧线圈调谐、线路投切后,门槛自动跟着变。
具体实现是维护一个滑动窗口,存最近 N 次(比如 50 次)正常运行的判据值,每次故障时用当前窗口的统计量算门槛。注意窗口要按运行方式分段,消弧线圈档位变化后清空窗口重新积累。这个技巧看起来简单,但能省掉大量现场重新整定的工作量,血泪经验是:千万别用出厂默认阈值跑一年,系统方式早变了。
class AdaptiveThreshold: def __init__(self, window_size=50): self.window = [] self.window_size = window_size def update(self, value): self.window.append(value) if len(self.window) > self.window_size: self.window.pop(0) def get_threshold(self, k=3): if len(self.window) < 10: return None # 样本不足,用默认阈值 mu = np.mean(self.window) sigma = np.std(self.window) return mu + k * sigma # 用法:正常运行时不断 update,故障时 get_threshold # at = AdaptiveThreshold() # for v in normal_ratios: # at.update(v) # th = at.get_threshold()逻辑说明:滑动窗口存历史正常值,用均值加 k 倍标准差做门槛。参数说明:window_size=50对应约一周的正常运行数据(按每天几次录波估算),k=3对应 99.7% 置信度,要求更严可取 4。样本不足 10 个时返回 None,回退到默认阈值,避免冷启动误判。
最后说个习惯:每次现场选线动作后,不管对错,我都把录波和判据中间结果存下来,按月复盘一次。谐振接地系统的故障样本本来就少,两点同相和高阻接地更是稀缺,不攒数据,算法永远调不好。希望帮到你。
本文还有配套的精品资源,点击获取