ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

同步相量计算算法对比:FFT、窗函数、小波与HHT的Matlab实现

同步相量计算算法对比:FFT、窗函数、小波与HHT的Matlab实现 在电力系统里做同步相量计算最难受的事情不是公式记不住而是你明明用Matlab跑出了结果却说不清这个结果到底准不准。尤其是面对非稳态信号、频率偏移、谐波污染这些场景时FFT一上来就给你一堆旁瓣窗函数加了又担心主瓣太宽小波变换换个基函数结果差出一大截HHT倒是自适应端点效应又让人头疼。这个项目把FFT、窗函数法、小波变换和希尔伯特-黄变换四种算法放在同一个测试框架里做同步相量计算目的就是把这些坑全部摆到台面上逐一对齐精度、速度、抗扰性给电力系统相量测量单元PMU的算法选型提供一个能落地的参考。不论你是刚接触同步相量的研究生还是正在做PMU算法比选的工程师这套Matlab代码和比选思路都可以直接拿去用。1. 项目背景与核心思路1.1 同步相量计算是什么难点在哪里同步相量并不仅仅是“测一个正弦波的幅值和相位”它要求把测量结果打上统一的时间标签并且在全网时间同步的基准下能反映电力系统当前的状态。简单地说电力系统里几十个测点同时测一个50Hz的电压或电流波形大家不仅要知道自家这路信号是多大、什么角度还要保证所有测量点在同一个UTC时刻给出的结果可以被放在一起计算这样才能用于广域监测、故障定位、暂态稳定判断。难点在于实际电网信号根本不是什么干净的50Hz正弦波。负荷波动会产生幅值调制发电机转子摆动会产生相位调制故障瞬间会有衰减直流分量和谐波频率本身也可能从49.8Hz慢慢漂到50.2Hz。在这种情况下一个单纯的离散傅里叶变换DFT或快速傅里叶变换FFT会由于频谱泄露而产生巨大的测量误差。所以同步相量算法的核心问题不是不会算而是怎么在各种扰动下依然能算出接近真值的幅值和相角。1.2 为什么同时研究FFT、窗函数、小波和HHT做算法比选不能拿一个算法去解决所有问题。FFT是同步相量计算的基础IEC/IEEE标准里很多参考算法都建立在DFT框架上但它对非同步采样敏感这是它的死穴。窗函数法本质上是在FFT之前加一个加权序列压低旁瓣解决频谱泄露但会牺牲主瓣宽度和频率分辨率。小波变换的时频局部化能力很强能在频率波动和暂态突变时同时给出时间和频率信息可是小波基函数的选择会直接决定结果的倾向性。希尔伯特-黄变换则是完全数据驱动的不需要事先假定信号是平稳的适合分析非线性和非平稳信号但它的端点效应、模态混叠又让结果变得不太稳定。把这四个算法放到同一个信号模型里做对比就可以很清楚地看到各自的适用边界稳态下谁最准动态下谁反应最快噪声下谁最稳谐波下谁还能保持精度。这种横向对比比单独介绍任何一个算法都有价值。1.3 整体仿真方案设计这个项目的整体方案可以分成五层信号生成层构造包含基波、谐波、幅值调制、相位调制、频率偏移、高斯噪声的测试信号。算法层分别用FFT、窗函数FFT、连续小波变换CWT和HHT计算相量。评价层以幅值误差、相角误差、响应时间、计算耗时为指标。可视化层画频谱图、时频图、相量轨迹图和误差曲线。结论层整理成算法选型建议表。这套结构的好处是每一层都可以独立修改。你想测一个更恶劣的信号只要改信号生成层你想加入一个新的算法只要在算法层加一个封装函数不需要动评价逻辑。我就是按这个结构维护整个工程文件的后面加算法非常省事。2. 四种算法的原理与适用场景2.1 FFT快速傅里叶变换基波参数提取的基准线FFT是把时域信号变换到频域的最常规手段。对一组采样点做N点FFT后频谱上某一根谱线的幅值和相位就是对应频率分量的估计值。在同步相量计算里我们通常找到基波频率附近的峰值谱线读它的幅值并换算有效值再读它的相角作为同步相量的相角。但FFT有一个前提假设信号必须是严格周期截断的。也就是说采样窗口长度必须是信号周期的整数倍否则频谱上会出现能量泄漏。电网频率一般标称50Hz可实际运行中并不严格等于50Hz这时候如果采样窗口仍然固定为0.02s的整数倍那么FFT基波谱线附近的能量就会泄漏到相邻谱线上幅值和相位都出现偏差。这个问题的本质可以用一个生活化的例子说明你拿一个固定长度的尺子去量一根没法正好对齐刻度的绳子测出来的长度总带一点尾巴。FFT就相当于这把尺子采样窗口就是刻度频率偏了刻度就对不齐。2.2 窗函数法频谱泄露的对抗手段窗函数法的基本思路是在做FFT之前先把采样序列逐点乘以一个窗函数序列让信号在窗口两端平滑地衰减到零。这样即使截断产生不连续因不连续引起的频域旁瓣也会被大幅压低。常用的窗函数有Hanning窗、Hamming窗、Blackman窗和Kaiser窗。Hanning窗主瓣较宽但旁瓣衰减快适合一般电力谐波分析Blackman窗旁瓣衰减更快但主瓣更宽会降低频率分辨率Kaiser窗可以通过调节beta参数在主瓣宽度和旁瓣衰减之间折中。在同步相量计算里窗函数法最大的价值是抑制谐波和间谐波造成的频谱泄露。比如信号里有一个5次谐波它虽然远离基波但如果采样不同步5次谐波的旁瓣也可能会泄漏到基波附近。加窗后这个泄漏会明显减少。代价是基波自身因为主瓣变宽对频率偏移的容忍度反而下降需要配合插值或频率跟踪来修正。2.3 小波变换时频局部化的利器小波变换不同于FFT它把信号分解成一系列经过平移和伸缩的小波基函数与信号的相似度度量。伸缩意味着可以改变频率尺度平移意味着可以定位时间所以小波变换能得到一个二维的时频表示非常适应非平稳信号。在同步相量计算中连续小波变换CWT常用于提取瞬时幅值和瞬时相位。对基波分量可以选择一个与基波波形相似的小波基比如Morlet小波或复Morlet小波然后用小波系数模值估计信号幅值用系数幅角估计相位。小波变化的好处是抗噪性比较好因为小波分解本身会隔离噪声所在的尺度。坏处则很明显小波基函数一旦确定相当于你预设了信号形状。如果信号里有衰减直流分量或快速变化的暂态某个固定小波基可能无法同时匹配所有成分导致边缘时刻的计算误差增大。实际使用中我习惯在暂态分析时配合模极大值法检测突变时刻而不是只依赖单一尺度系数。2.4 希尔伯特-黄变换HHT自适应非平稳信号分析HHT由经验模态分解EMD加Hilbert变换组成。EMD会把信号自适应地分解为若干个固有模态函数IMF每个IMF代表一个窄带分量然后对每个IMF做Hilbert变换得到瞬时幅值和瞬时频率。HHT最大的特点是“自适应”。它不需要选择窗函数、不需要选择小波基完全根据信号本身的包络特征来分解。这在对未知扰动信号做分析时很有吸引力。在同步相量计算中我们通常把第一个或第二个IMF当作基波分量用它算瞬时幅值和相位绘制幅值随时间变化的曲线。不过HHT的两个先天毛病在同步相量场景下会被放大。一是端点效应Hilbert变换在信号两端会出现振荡导致起止时刻的瞬时频率和幅值严重失真。二是模态混叠当基波频率附近存在间谐波或噪声时EMD可能把一个物理分量拆到多个IMF里基波IMF被污染后续求出的相量自然不准。工程上常用集合经验模态分解EEMD来缓解模态混叠代价是计算量成倍增加。3. 仿真模型与实验条件搭建3.1 电力系统同步相量测试信号构造这个项目里我构造了一组具备代表性的测试信号包含稳态、动态和暂态三类场景。稳态场景的数学模型x(t) Xm * cos(2*pi*f0*t phi0) sum(Ah * cos(2*pi*h*f0*t phih))其中f0是基波频率h是谐波次数。动态场景则在幅值和相位上叠加调制Xm(t) Xm * (1 ka * cos(2*pi*fa*t)) phi(t) phi0 kp * cos(2*pi*fp*t) x(t) Xm(t) * cos(2*pi*f0*t phi(t))ka和kp是调制深度fa和fp是调制频率。这模拟了负荷波动引起的幅值摆动和系统低频振荡引发的相位摆动。此外还专门设计了从49.8Hz渐变到50.2Hz的频率偏移信号用来考验算法对非同步采样的适应能力。采样率我统一用10kHz50Hz下每周期200个采样点FFT窗口取10个周波也就是0.2s总共2000个点。10个周波窗口的好处是能显著压低旁瓣坏处是动态响应速度慢这个在后面的结果里会体现出来。3.2 采样参数与评价指标评价一个相量算法是否合格不能只看幅值误差。IEEE C37.118标准里除了幅值误差、相角误差还看总向量误差TVE把它当作同步相量的综合精度指标。TVE的计算公式TVE sqrt( (Xr - Xr_true)^2 (Xi - Xi_true)^2 ) / X_true换算成幅值和相角的形式TVE sqrt( (|X|/|X_true| - 1)^2 (angle(X) - angle(X_true))^2 )这个指标把幅值误差和相角误差统一到一个框架里工程上非常常用。我在项目里以TVE小于1%作为合格线这个标准比IEC要求的0.5%左右宽松一些适合观察算法差异而不是做标准符合性测试。响应速度方面我记录的是信号发生阶跃突变后算法输出从初始值过渡到新稳态值所需的时间取90%变化量为门槛。计算耗时则直接用tic/toc记录每次完整算法处理2000个点所需的时间重复20次取平均。3.3 算法对比的公平性控制做算法对比最怕不公平。这个项目里我做了三个关键控制输入完全一致所有算法吃的是同一个信号文件不针对任何算法单独调整采样率或信号内容。FFT和窗函数法使用相同的数据窗口长度都取10个周波。小波变换和HHT输出的是瞬时值序列我在评价时截取与FFT窗口中心对齐时刻的值避免时间偏移造成误差。另外FFT系列算法天然给出的是窗口内的平均相量小波和HHT给出的是逐点瞬时相量两者在做“真值”对比时口径本就不同。所以我另外设了一条规则真值也用信号的解析表达式在对应时刻计算而不是拿某个算法的结果当基准。这样至少保证所有算法都是和理论真值比而不是相互比。4. Matlab实现与核心代码解析4.1 FFT同步相量计算代码FFT提取基波相量最核心的一段代码如下function [Xm, phi] fft_phasor(x, fs, f0) N length(x); X fft(x) / N; [~, k0] min(abs((0:N-1) * fs / N - f0)); k0 k0 - 1; % 频谱下标从0开始 X_base X(k01); Xm 2 * abs(X_base); phi angle(X_base); end这里需要注意两点。第一幅值要乘以2因为单边频谱里基波的能量分布在正负两个频率点FFT结果直接取的幅值是双边幅值实际正弦信号幅值等于两倍谱线幅值。第二k0的搜索范围要限制在基波频率附近不能全频段乱找否则噪声的尖峰可能被误判为基波。这段代码在信号严格同步采样、没有谐波和噪声时精度极高幅值误差可以做到10的负14次方级别。但只要频率偏到50.05Hz误差立刻上升到0.3%左右相位误差还能更大。这就是直接FFT的局限性。4.2 窗函数法代码实现Hanning窗与Blackman窗加窗的代码非常简单核心就是把原始信号逐点乘以窗函数序列再做FFT。不过有一个补偿工作容易被忽略加窗会改变信号的总能量如果直接读取谱线幅值幅值会偏低。常用的做法是使用相干增益coherent gain修正也就是把FFT结果除以窗函数的直流增益即窗序列的均值。function [Xm, phi] windowed_fft_phasor(x, fs, f0, win_type) N length(x); switch win_type case hanning w hanning(N, periodic); case blackman w blackman(N, periodic); case kaiser w kaiser(N, 8); otherwise w ones(N, 1); end win_gain sum(w) / N; X fft(x(:) .* w(:)) / N / win_gain; [~, k0] min(abs((0:N-1) * fs / N - f0)); X_base X(k01); Xm 2 * abs(X_base); phi angle(X_base); end用周期性窗函数periodic而不是对称窗函数是因为FFT隐式地把信号看成周期延拓周期性窗的末端和首端衔接更自然能进一步减少周期延拓造成的跳变。这个细节我第一次跑的时候忽略了结果相位误差在窗口边界上比对称窗小但整体幅值波动反而大了后来改回周期性窗才正常。Hanning窗在频率偏移0.2Hz时的幅值误差能控制在0.1%以内比不加窗好很多Blackman窗的旁瓣衰减更猛但主瓣更宽在邻近谐波存在时可能把谐波能量也吞进主瓣导致基波幅值被抬高。所以并不是旁瓣压得越低越好必须结合实际信号频谱布局来选。4.3 小波变换实现CWT与模极大值Matlab里做连续小波变换最方便的是使用Wavelet Toolbox的cwt函数。计算基波相量时我会选择Morlet小波因为它是复值小波可以同时得到幅值和相位信息。function [Xm, phi] cwt_phasor(x, fs, f0) fb cwtfilterbank(SignalLength, length(x), ... SamplingFrequency, fs, VoicesPerOctave, 16, ... Wavelet, morl); [coef, freq] cwt(x, fs, wavelet, morl, ... VoicesPerOctave, 16); [~, idx] min(abs(freq - f0)); c coef(idx, :); Xm 2 * abs(c); phi angle(c); end这个代码的关键在于小波系数并不是直接对应信号的物理幅值需要根据小波基的傅里叶变换形状做幅值校正。我在实际调试中发现直接用abs(coef)读出来的幅值比真值小几倍原因是CWT的归一化方式是把小波基的2范数归一不是把物理幅值归一。简单处理可以在标定阶段对已知幅值的标准正弦信号跑一遍计算一个修正系数这样比推导解析表达式更快也够准。小波变换在频率偏移场景下的幅值波动明显小于直接FFT这是时频局部化的好处。但在信号端点附近误差很大我一般丢弃左右各百分之五的边界数据只在中间区段做相量输出。4.4 HHT实现EMD分解加Hilbert谱Matlab里做HHT有两个选择一个是官方Wavelet Toolbox里的emd函数一个是第三方工具包。官方自带emd函数配合hht函数可以很快得到瞬时频率和瞬时幅值。function [Xm, phi] hht_phasor(x, fs, f0) imf emd(x, MaxNumIMF, 6); imf1 imf(:, 1); analytic hilbert(imf1); inst_amp abs(analytic); inst_phase unwrap(angle(analytic)); inst_freq diff(inst_phase) / (2 * pi) * fs; % 以基波频率对应的瞬时值作为相量 idx inst_freq 45 inst_freq 55; Xm median(inst_amp(idx)); phi median(inst_phase(idx)); end这里有个比较实用的判断EMD的第一个IMF通常包含最高频成分。如果信号里没有谐波第一个IMF基本就是基波但只要有谐波或噪声第一个IMF往往是谐波加噪声的混合基波反而跑到第二个IMF里。我们需要提前判断哪个IMF才是基波。常用的判断方法是计算每个IMF的平均瞬时频率哪个IMF的瞬时频率均值离50Hz最近就拿哪个做相量计算。这段代码里median而不是mean取中位数是为了抵抗端点效应带来的尖峰。端点效应导致的振荡会让瞬时幅值在两端出现非常大的毛刺直接取均值会把结果带偏取中位数虽然会牺牲一些动态响应特性但在稳态和慢动态场景下更稳。4.5 主程序与结果可视化整个工程的主程序我用一个脚本将四类算法串起来统一输出一个结构体数组result包含幅值、相角、TVE和耗时。可视化部分我常用三幅图原始波形图加基波估计幅值曲线可以直观看到幅值跟踪效果。四类算法的TVE对比曲线用半对数坐标画因为不同算法的误差数量级差别很大线性坐标会把小误差压到看不见。HHT和小波的时频谱图用pcolor或imagesc画观察频率随时间的变化。还有一个小技巧所有算法的输出相角都要做unwrap处理否则相角在正负pi附近跳变画出来的相位误差曲线全是锯齿。这个坑我在第一次做对比时踩过后来在整个流程最前面统一对相角调用unwrap问题就消失了。5. 结果分析精度、速度与抗扰动能力对比5.1 稳态精度对比在纯50Hz、无谐波、无噪声的稳态场景下直接FFT理论上是最准的。实测幅值误差在10的负12次方量级加窗后稍微差一点因为窗函数本身改变了频谱形状但误差也在1e-4以内。小波变换和HHT的稳态误差都在1e-2到1e-3量级明显比FFT差。原因很好理解FFT是用整个窗口的数据拟合一个周期分量等价于一个最优的去噪平均器小波和HHT是逐点估计每个时刻只用局部数据随机波动没有被充分平均掉。因此如果只需要稳态测量完全没有必要上小波或HHT直接FFT就是天花板。5.2 动态响应与频率偏移场景一旦加入频率偏移或相角调制情况会完全反转。频率从50Hz渐变到50.2Hz时直接FFT的TVE会快速增大最大达到2.8%左右超过1%合格线。加Hanning窗之后TVE降到1.2%附近仍然偏高。Blackman窗更惨因为主瓣太宽频率偏移稍微大一点基波谱线的位置就落在主瓣边缘幅值衰减明显。小波变换在这个场景下表现最稳TVE始终在0.3%以下。因为它对频率尺度做了连续扫描基波能量不会因为频率偏移而“跑出”预设频率点。HHT的表现则依赖EMD的质量。没有噪声时第二个IMF能很好地跟随频率变化TVE在0.5%左右。加上端点处理后两端时刻的误差依然存在但中间区域的估计是可用的。5.3 谐波和噪声影响谐波场景测试的是5次谐波幅值为基波的10%的情况。直接FFT如果不加窗谐波泄漏到基波附近造成的TVE约为1.8%加Blackman窗后能压到0.1%以下。这里窗函数法的优势完全发挥出来。但窗也不是白加的。谐波测试里我还发现Hanning窗对5次谐波的抑制足够对间隔很近的间谐波就不行了。这个时候用Kaiser窗beta取8左右效果更好不过主瓣变宽的副作用也跟着来。噪声场景下所有算法的TVE都会升高。小波由于自带尺度分解对白噪声的耐受性最好HHT在信噪比低于30dB时EMD的模态混叠变得严重第一个IMF里的噪声成分明显增多基波幅值估计出现随机抖动。这种情况我更推荐对小波系数做平滑或者对HHT用EEMD。5.4 计算复杂度对比计算耗时我用相同数据长度2000点测过结果很有代表性算法相对耗时适合实时性FFT1x极强窗函数FFT1.1x极强CWT8~15x中等EMDHilbert30~50x较弱FFT加窗几乎是零成本这也是为什么工业PMU里主流算法还是基于DFT和加窗DFT。小波和HHT虽然精度在某些场景下有优势但计算量和参数复杂度决定了它们更适合离线分析而不是嵌入实时测量装置。真要做实时在线分析比较实际的做法是用FFT做稳态测量再用小波或HHT做暂态触发后的补充分析两者配合而不是互相替代。6. 常见问题与排查技巧实录6.1 FFT频谱泄露与栅栏效应很多人刚用FFT算同步相量一上来就遇到底噪很高或者幅值偏小。先检查采样窗口长度是不是信号周期的整数倍如果不是频谱上基波附近全是“裙边”这就是频谱泄露。其次是栅栏效应因为FFT只输出离散频率点上的结果基波实际频率落在两个谱线之间时谱线幅值会变低。解决办法是加入窗函数或做频谱插值如果还不行检查是否忘了除以窗函数的相干增益。6.2 HHT端点效应与模态混叠HHT最常见的报错不是代码问题而是结果里幅值两端剧烈振荡。我处理端点效应的经验是先对原始信号两端做镜像延拓延拓长度取信号总长的10%左右做完EMD之后再截掉延拓部分这样端点振荡就不会污染中间数据。模态混叠则常出现在基波附近有间谐波的情况这时候可以用EEMD噪声幅值一般取信号标准差的0.1倍集合次数在100到200之间这样才能稳定地分离出基波IMF。6.3 小波基选择困难小波基选不好你会得出“小波变换根本不适用于同步相量计算”的结论。实际上问题在于小波基和信号形态不匹配。基波是近似正弦的窄带信号最好选择复值小波或高斯小波族因为它们中心频率清晰相位响应线性。做相量计算建议用Morlet小波不要用db系列因为db小波的相位特性不是线性的提取出的瞬时相位会出现畸变。如果你需要同时做故障定位和相量提取可以在一个滤波器组里同时使用多个小波基然后按频率尺度分别输出。6.4 Matlab工具箱缺失很多人拿到代码后运行报错“未定义函数emd”或“未定义函数cwt”多半是缺少Wavelet Toolbox。emd函数需要较新版本的Matlab老版本里没有。如果不想安装完整工具箱两个替代方案一是下载第三方EMD工具包部署后调用二是手写简单的EMD循环但性能较差只适合教学演示。CWT则一定要有Wavelet Toolbox否则可以退而求其次用带通滤波器组实现近似的时频分析但代码复杂度会成倍上升。6.5 基于实践的算法选型建议做完这一整套对比我的个人体会是没有全能的算法只有合适的场景。工业PMU装置里首选还是加窗的DFT。它快、稳定、标准化程度高配合频率跟踪和插值算法能在绝大多数稳态和慢动态场景下满足0.5%的TVE要求。小波变换更适合做暂态事件记录和扰动起始时刻检测因为它的时间定位能力极强能告诉你故障发生在哪一个毫秒。HHT在分析非线性和非平稳调制的场景下有独特优势但更适合离线研究比如分析次同步振荡、间谐波演变而不是实时在线计算。最后再分享一个小技巧在Matlab里做算法比选时先写好一个统一的测试信号生成函数和评价函数再把自己新写的算法函数按固定格式封装进去。我第一次做对比时四个算法分别用了四个脚本信号参数改一处四个脚本都要跟进改不仅容易出不符合预期还浪费了大量时间。后来我把信号生成、算法调用、误差计算和画图全部收进一个m文件里只保留算法子函数整个比选流程才变得清爽。以后不管是加Prony算法、加ESPRIT算法还是加卡尔曼滤波法我只需要写一个子函数然后往主程序里加一行调用就够了。
返回列表