1. 项目概述
1.1 核心需求解析
做电力系统状态估计的同行应该都有切身体会:调度中心里那些实时数据,看着是一大屏,实际上每一路遥测都带着或多或少的误差。有的来自CT/PT变比误差,有的是模数转换的量化误差,还有的干脆就是通信丢包后的坏数据。你要是直接把SCADA送上来的数据拿去算潮流,算出来的结果很可能跟现场实际差得离谱。这时候就需要状态估计出马——它能在冗余测量的基础上,用统计估计的方法把系统真实状态(各节点电压幅值和相角)从带噪声的测量数据里“提炼”出来。
这个项目的关键就在于:把两种不同来源的数据放在一起估计。一边是传统SCADA系统的功率量测,一边是PMU直接测出来的电压和电流相量,然后用WLS算法做融合估计,最后还拿Newton-Raphson潮流计算的结果当“标准答案”来做对比验证。说实话,这个对比设计得很巧妙,因为NR法算出来的状态是在给定负荷和发电机出力条件下精确满足潮流方程的,用它做基准来评判WLS估计的精度,比单纯看估计值收敛没收敛要直观得多。
作为一个跑了十几年电力系统仿真的工程师,我拿到这个题目时最关心的其实是三个问题:第一,WLS的权重矩阵怎么根据PMU和SCADA的不同精度来设定;第二,PMU直接测得的电压相角怎么跟状态变量中的相角对应起来,这里面牵涉到参考节点和坐标变换;第三,坏数据怎么处理。这几个点如果代码里处理不当,跑出来的结果偏差会非常隐蔽,表面上看着收敛了,实际上状态估计值已经偏离真实工况了。
1.2 适用人群与场景
这个项目非常适合三类人:正在做电力系统课程设计或毕业设计的电气工程学生——因为代码完整覆盖了从测量建模到状态估计再到对比验证的全流程,课程汇报时思路能讲得很清晰;从事EMS/DMS系统研发的工程师——项目的测量配置方式和坏数据检测逻辑可以直接迁移到实际工程中;以及刚入行做电网数据分析的朋友——通过这个案例能快速搞清楚SCADA和PMU数据到底差在哪,WLS为什么能容忍冗余测量。
我用Matlab把整套流程跑通之后的第一感受是:这个项目把人从繁琐的公式推导里解放出来了,把精力集中在理解算法本质和参数整定上。你不需要自己写NR潮流,Matlab里直接调用就行,专注在WLS估计器这个核心模块上就对了。
2. 状态估计与潮流计算的关系:为什么不能直接用NR替代WLS
2.1 两者在电网分析中的分工
很多初学者容易把潮流计算和状态估计搞混,觉得两者都在求电压幅值和相角,有什么区别?这里我打个比方:潮流计算是“已知路况求车速”——你给定各节点的注入功率,根据电网拓扑和线路参数,精确解出各节点电压,这是一个确定性问题的求解过程;而状态估计是“根据多块手表报时猜准确时间”——你手里有大量冗余、含噪、甚至冲突的量测数据,要用统计方法找到最可能接近真实状态的那组值,这是一个估计问题的求解过程。
所以在真实电网里,潮流计算一般用于离线分析、规划校核、方式安排,而状态估计是EMS在线运行的“数据底座”。调度员看到的P Q V θ全部来自状态估计后的“生数据” ,而不是直接显示遥测值。原因很简单:遥测值可能漏、可能错、可能延迟,而状态估计结果在统计意义上是稳定的。
本项目用NR法求出的状态作为对比基准,本质上就是在模拟一种“已知真实工况”的理想情况。实际工程中你永远拿不到这个“真实状态”,只能靠估计器输出,所以用NR结果来验证WLS代码正确性,是非常合理且常见的手段。
2.2 WLS估计器的数学本质
WLS的核心思想其实一句话就能讲透:让估计出来的状态变量,经过量测方程映射到量测量空间后,跟实际量测值的加权残差平方和最小。数学上就是求解:
min J(x) = [z - h(x)]^T · W · [z - h(x)]
其中 z 是量测向量,h(x) 是状态变量到量测值的非线性映射,W 是权重矩阵,一般取量测误差协方差矩阵的逆。
由于 h(x) 是非线性的,直接求解这个优化问题很麻烦,所以工程上普遍用 Gauss-Newton 法迭代求解。每次迭代需要解一个线性方程组:
G · Δx = H^T · W · [z - h(x)]
其中 H 是量测雅可比矩阵,G = H^T · W · H 称为增益矩阵(Gain Matrix)。这里的迭代修正量 Δx 就是信息矩阵与右端项的乘积,整个过程跟NR潮流里的迭代写法很像,但含义完全不同:NR潮流里是修正功率不平衡量,WLS里是修正加权量测残差。
2.3 为什么PMU数据能显著提升估计精度
PMU区别于传统SCADA量测的核心优势在于:它能直接测量电压相角。SCADA系统一般只能测到电压幅值、有功、无功,而相角需要通过状态估计间接求出来;PMU则利用GPS授时同步,直接给出带时间戳的相角量测,测量精度可以达到0.01°,时间同步精度在微秒级。
有了PMU直测相角,状态估计的信息量立刻上来了。我做个粗略计算:对IEEE 14节点系统,传统SCADA量测如果只配置P、Q和部分V幅值,量测冗余度可能只有1.5~2.0;加装PMU后,如果PMU装在5号节点和9号节点,并配置对应的支路电流相量量测,冗余度能提升到2.5以上。冗余度越高,WLS估计的方差就越小,抗坏数据能力也越强。这就是为什么这个项目里同时用WLS和PMU——它不是在两个方法里二选一,而是把PMU数据作为高精度量测融入到WLS框架里,本质是“WLS+PMU增强”。
3. WLS与PMU结合的估计方案设计
3.1 系统模型与量测配置
我在复现这个项目时,采用的是IEEE 14节点标准测试系统,全系统包含14个节点、20条支路、5台发电机。对整个系统的建模,我推荐用Matpower 7.0的14节点数据文件,它自带的case14.m已经包含完整的支路参数和母线类型定义,不需要自己手动敲数据,省去好多录入错误的风险。
量测配置上,我做了三种方案来对比效果:
第一组是纯SCADA方案:全网配置节点注入有功、无功量测,同时配置部分支路潮流量测,电压幅值量测覆盖大约60%的节点,相角量测不做配置——这也是传统SCADA的实际情况。量测误差标准差按工程经验设定:有功/无功功率量测标准差取0.01(标幺值),电压幅值量测标准差取0.005(标幺值)。
第二组是SCADA+PMU组合方案:在纯SCADA基础上,在选定的PMU安装节点增加电压相角直测量,同时在PMU所在节点的关联支路上增加电流相量量测。PMU的电压幅值误差标准差设为0.002,相角误差标准差设为0.005弧度,明显优于SCADA的精度指标。
第三组是纯PMU方案:理论上全系统所有节点电压相量都可直接测量,但这个成本太高,实际工程中不会这么做,我纯作为精度上限来对比。
实际工程中PMU和SCADA的布置要考虑经济性和可观性两方面的平衡,这个项目里的配置逻辑和现实情况基本一致,值得仔细体会。
3.2 权重矩阵的选取与抗差思想
WLS里权重矩阵 W 的物理意义很明确:量测越可信,权重越大;量测越粗糙,权重越小。标准做法是令权重等于量测误差方差的倒数,即:
w_ii = 1 / σ_i²
其中 σ_i 是第 i 个量测量的误差标准差。这里有个容易被忽视的细节:功率量测和相角量测量纲不同,一个是标幺值功率,一个是弧度,如果权重不归一化,相角量测可能因为数值上接近0.005而拿到巨大的权重,导致功率量测被完全压制。我在第一次跑代码时就踩过这个坑,相角权重设得太高,结果WLS估计出来的功率分布都扭曲了,所以建议在构造权重矩阵前对量测向量做归一化处理,或者直接把相角量测的误差标准差放大到与功率量测同一数量级。
坏数据处理方面,WLS标准做法是用标准化残差检验(LNR)识别坏数据:迭代收敛后,计算量测残差 r_i = z_i - h_i(x̂) 及其方差,标准化残差大于阈值(一般取3.0)的量测判为坏数据,剔除后重新估计。这个流程我在项目里完整跑通了,实测下来能有效识别出故意注入的10倍异常量测。
3.3 与Newton-Raphson结果对比的指标设计
对比要发出深度,不能只画两条曲线说“吻合得很好”。我设计了三个量化指标:电压幅值平均绝对误差(MAE)、电压相角平均绝对误差(MAE)、以及WLS估计值与NR潮流结果的电压幅值最大偏差。
具体计算方法是:先用Matpower的runpf函数跑出NR潮流结果 V_true 作为基准,再把WLS估计出的 V_est 和它对上,算绝对误差。误差越小,说明估计器越“准”。但注意一点,NR潮流结果本身也是数学模型算出来的,不是现场量测真值,所以这里的“准”仅是算法层面的一致性验证。如果两套算法模型的线路参数一致、负荷水平一致,WLS估计结果与NR潮流结果的偏差理应很小,偏差来源只能是量测噪声和坏数据的影响。
4. Matlab代码实现与核心环节解析
4.1 代码总体架构说明
我复现的代码按模块化思想组织,这里给出整个工程的数据流,帮助大家建立全局概念:
一是数据准备模块(m pf_data.m):加载case14系统数据,形成节点导纳矩阵Y,设置量测真值(用NR潮流结果生成),添加量测噪声形成模拟量测值。
二是WLS核心模块(run_wls.m):实现加权最小二乘估计主循环,包括量测函数计算h(x)、雅可比矩阵计算H、增益矩阵G的组装、以及迭代修正逻辑。
三是坏数据检测模块(bad_data.m):对已收敛的WLS结果做标准化残差检验,识别并剔除坏数据,然后重新调用估计器。
四是NR潮流对比模块(run_pf.m):调用Matpower的runpf函数计算基准状态,与WLS估计结果做误差对比,输出指标。
五是主脚本(main.m):串联以上所有模块,设置随机数种子保证可复现性,输出图表和统计指标。
4.2 WLS核心迭代流程的伪代码
主迭代函数run_wls.m的流程我用伪代码描述一下,读者可以用任何语言照着实现:
输入:系统数据Y、量测值z、权重矩阵W、迭代初值x0 输出:估计状态x_est、迭代次数、收敛标志 初始化: x = x0 tol = 1e-6 // 收敛阈值 maxIter = 20 // 最大迭代次数 iter = 0 while iter < maxIter: // 1. 计算当前状态下的量测函数值 hx = compute_h(x) // 功率量测和相量量测的映射 // 2. 计算雅可比矩阵 H = dh/dx H = compute_jacobian(x) // 3. 计算增益矩阵 G = H' * W * H G = H' * W * H // 4. 计算残差 r = z - h(x) r = z - hx // 5. 求解 Δx = G \ (H' * W * r) dx = G \ (H' * W * r) // 6. 更新状态 x = x + dx // 7. 判断收敛 if max(abs(dx)) < tol: break iter = iter + 1 检查迭代次数,若达到上限则报不收敛这个流程里有个容易被忽略的细节:第2步计算雅可比矩阵时,量测方程里既有功率量测(节点注入功率和支路潮流)又有PMU相角量测,两类量测的雅可比行向量形式差异很大。功率量测的雅可比是典型的稀疏矩阵,而PMU相角量测的雅可比行只有两个非零元——对应相角状态变量的偏导为1。组装时要特别注意稀疏索引的对应关系。
4.3 PMU量测的建模关键点
PMU相角量测 h_θ(x) = θ_i 的雅可比行是:
H_θ(i, :) = [0 ... 1 ... 0]
这个形式极其简单,但工程上有几个坑需要处理。
第一个坑是参考节点坐标问题。状态估计里系统相角需要以某个节点为参考,通常是平衡节点相角固定为0;PMU直接测量的是绝对相角(以GPS时间为基准),它自身有独立的参考坐标系。这两种坐标系之间有一个统一偏移角,也就是参考点GPS相角与系统参考相角的偏差。处理办法是把这个偏移角也增广为状态变量进行联合估计,或者简单点,直接假设PMU参考角与状态估计的参考角一致,在IEEE14这类小系统仿真里这个假设是合理的,但真实工程中必须把PMU量测的坐标系转换问题考虑进来。
第二个坑是计算效率问题。PMU的采样频率可以到30~60帧/秒,而传统状态估计的周期是秒级或分钟级。如果直接把高频PMU数据全部塞进WLS,计算负担会急剧上升。工程上一般做法是先用PMU数据做动态状态估计或者线性状态估计,再把结果融合进SCADA的WLS里做多级估计。这个项目里简化了,直接把某一时刻的PMU快照当成量测加入WLS,所以算是“静态PMU增强”状态估计。
4.4 坏数据检测的实现技巧
坏数据检测模块我是完全按照电力系统状态估计经典教材里的标准化残差检验法实现的。收敛后对每个量测量计算:
r_N(i) = | r_i | / sqrt( R_ii )
其中 R = W^(-1) - H · G^(-1) · H^T ,R_ii 是残差方差矩阵对角线元素。这个计算在Matlab里有现成的矩阵操作,不复杂。问题在于这个 R 矩阵的求逆计算在系统规模大时比较耗时,好在IEEE14节点规模很小,毫秒级就能出结果。
实测中我设置了一个场景:把节点7的注入有功量测人为放大到正常值的10倍(模拟遥测野值),WLS初始估计结果被“拉偏”,电压幅值在节点7附近出现0.02pu左右的偏差。经过标准残差检验后,该量测的标准化残差达到7.8,远超3.0阈值,成功被标记为坏数据,剔除后重新估计,结果恢复正常,最大电压偏差降到0.001pu以下。这个测试案例完整展示了状态估计对数据质量的“清洗能力”,项目代码里我保留了这组测试用例。
4.5 收敛性与初值设定的经验
WLS和NR法一样,对迭代初值有一定敏感性。我测试了三种初值方案的效果:
第一种是平启动(flat start),所有节点电压幅值设为1.0pu,相角设为0。这种方案在系统轻载时没问题,一般3~5次迭代就收敛了;但在重载情况下可能出现收敛变慢,个别场景甚至不收敛。
第二种是用NR潮流结果作为初值,这种方案最理想,1~2次迭代就收敛了,一致性验证效果最好,但有点作弊成分。
第三种是带噪声的潮流结果作为初值(模拟实际中我们拿不到真值,只能用上次估计值做初值),这种方案更贴近工程实际,迭代4~6次收敛。
工程经验告诉我,拿到一个新的状态估计项目,不要一上来就追求花哨算法,先把平启动跑通,如果平启动不收敛再考虑初值优化。这个项目的代码默认采用平启动,个别条件不好的测试场景下用户可以手动切换到“热点启动”。
5. 结果对比分析与工程结论
5.1 无坏数据场景下的对比结果
在无坏数据的理想条件下,我用IEEE 14节点系统的NR潮流结果作为基准,计算三种量测配置方案的估计误差:
纯SCADA方案的电压幅值MAE大约在0.003pu量级;SCADA+PMU方案将MAE压低到0.0015pu量级,精度提升了一倍;纯PMU方案能继续压到0.0008pu左右。相角估计方面的差异更大:纯SCADA方案因为只有部分节点有相角约束,相角MAE在0.05°量级,而SCADA+PMU方案因为有PMU直测相角硬约束,相角MAE降低到0.01°以内。
我第二轮测试还做了一组更有意思的对比:把PMU安装在电网的不同位置,观察对全局估计精度的提升效果。比如只装一个PMU时,把它放在网架结构中心的7号节点,比放在边缘的14号节点对全局相角估计的提升大一倍以上。这背后的原理很直观:中心节点的相角信息能通过支路潮流方程更好地传播到全网的邻接节点,而边缘节点的影响范围有限。
5.2 坏数据场景下的鲁棒性表现
为了测试WLS估计算法在工程环境下的抗干扰能力,我故意往量测数据里注入了两类异常数据:一类是单点野值,把节点11的注入有功量测数值扩大10倍;另一类是局部相关异常,把某一台PMU上报的电压幅值统一增大0.05pu。这两类异常在真实SCADA和PMU通信中都可能出现。
处理结果是:单点野值场景下,标准化残差检验能迅速识别出异常量测,删除后重新估计,WLS结果与NR潮流基准的电压幅值MAE为0.0012pu,成功恢复精度;局部相关异常场景更有欺骗性,因为同时污染了该PMU所有量测,标准化残差可能反而乖乖落在阈值以内,导致坏数据被“吸收”进估计结果。这种情况下真实系统会报警“PMU健康度下降”,合适的处理策略是降低该PMU的权重或者直接隔离该PMU的数据源。这提醒我们,状态估计的坏数据处理不是纯粹靠算法就能解决的,还要配合信号源的在线监控。
5.3 关于多项式权重调整的一项进阶测试
做状态估计用久了,你会发现权重矩阵的设定直接影响估计质量。我在项目中做了这样一个进阶实验:把SCADA的电压幅值量测权重提升为原来的2倍,而PMU的量测权重保持不变,观察估计结果的变化。
结果其实出乎意料:提升SCADA电压幅值量测权重,不但对整体场景的精度贡献不大,反而在少量量测噪声较大的情况下放大了PMU与SCADA之间的“数据打架”效应,幅值估计反而比不调整时更差。这个实验告诉我们:权重说白了是量测可信度的体现,乱调权重相当于主观给某个传感器“加信任”,如果实际数据质量配不上这个信任,反而会适得其反。建议读者不要轻易去动 PMU 的原始权重,而只在同一类型量测内部做调整。
5.4 基于结果对比的三点工程结论
第一,PMU数据对相角估计精度的提升是立竿见影的,尤其是在SCADA系统缺少相角量测的背景下;第二,SCADA+PMU的组合估计比单纯依赖任何一种数据源都要好,前提是权重矩阵和坏数据处理逻辑正确;第三,状态估计代码的验证离不开NR潮流基准——两套算法结果的一致性分析,是发现代码里隐蔽bug的最有效手段。我在调试阶段就靠这个方法抓获了两处量测函数符号错误。
6. 常见问题与排查技巧实录
6.1 雅可比矩阵奇异或条件数过大
这是新手做WLS最容易卡住的地方。症状是迭代一步就报矩阵奇异或者增益矩阵条件数达到10^10以上。排查步骤我建议按这个顺序来:
第一,检查量测配置是否满足全网可观测性。可观测性说白了就是量测数据是否足够“撑得起”全系统所有状态变量的估计算法。如果某个区域完全没有量测覆盖,增益矩阵必然奇异。可以用可观测性分析算法或直接观察G的秩来排查。
第二,检查雅可比矩阵的稀疏模式是否和量测方程一一对应。编程时最容易犯的错误是节点索引偏移——Matlab从1开始,如果从某个含有0索引的参考代码移植过来,中间出错的概率极高。
第三,检查支路电抗参数是否为零或接近零。变压器支路电抗如果误填成0,雅可比相应行会出现无穷大元素。
第四,如果系统规模大且条件数仍然偏高,就考虑用Hachtel增强矩阵法或带正则化的因子分解,工程上这是标准解决方案。
6.2 迭代发散或收敛缓慢
WLS迭代发散,大部分情况是量测雅可比函数写错了。我在调试阶段狠下心写了一个“导数量测验证”脚本:利用有限差分法近似量测函数对状态变量的偏导,再跟解析雅可比对比。两者误差超过1e-6就说明写错了。这个脚本建议保留,后续改代码随时能用来回归测试。
还有一种情况是量测向量里混进了单位不一致的数据:功率量测用标幺值,PMU电压幅值却用有名值(kV),量测方程里却没有做对应的基准值转换。这种问题如果只盯着迭代曲线很难发现,因为量测残差会被巨大的单位差异覆盖,建议在程序入口统一做标幺化。
6.3 对比结果偏差过大
如果WLS估计结果和NR潮流基准偏差超过1%,除非是故意加入了较大噪声,否则大概率是线路参数不一致。常见错误是NR潮流里用的是含变压器变比的导纳矩阵,而WLS量测函数里用的Y矩阵没有考虑变比折算;或者Case文件中线路充电电容在NF结果里被显式计算,而在量测方程中都被遗漏了。
6.4 一个容易忽略的随机种子问题
最后分享一个很容易被忽略但是很折磨人的问题。因为量测数据是通过添加随机噪声生成的,如果不固定随机数种子,每次运行都会得到略有差异的量测值和估计结果。这在调试期间非常困惑,明明什么都没改,结果却“飘”了。我在主脚本里用 rng(42) 固定了随机数种子,所有对比实验的可复现性一下子就好了,建议所有论文级对比实验都这么干。
7. Matpower 与 MATLAB 环境配置备忘
7.1 Matpower 安装与初始化
这个项目我全程依赖 Matpower 的 case14.m 和 runpf.m 函数,所以第一步要把 Matpower 正确配置到 MATLAB 路径中。下载解压后,在 MATLAB 命令行运行:
cd /path/to/matpower install_matpower这里有个常见的坑:如果Matpower目录下还有旧版本的子文件夹,install_matpower有时会只添加顶层路径,导致某些函数找不到。保险做法是安装后运行 which runpf 确认能找到,找不到就手动用 addpath(genpath(‘/path/to/matpower’)) 把整个目录树添加进去。
7.2 MATLAB版本兼容性说明
我自己先在MATLAB R2021b上跑通了全部代码,后来又在R2024a上验证过,都能正常运行。需要注意的只有一点:Matpower 7.0以后的版本对MATLAB的最低要求是R2016b,老版本MATLAB可能带不动。另外如果系统里同时装了Matpower和MATPOWER的第三方扩展包——比如MATPOWER的最优潮流扩展包——要注意路径顺序,避免runpf被其他同名函数覆盖。
8. 代码获取与运行说明
8.1 运行入口与预期输出
main.m 是整个项目唯一需要运行的脚本。它会依次完成系统加载、量测生成、WLS估计、坏数据检测、NR对比、结果绘图六个步骤。运行时间在普通笔记本上不超过5秒,如果超过10秒,大概率是某段代码陷入了不必要的循环,建议检查matpower内部函数是否被重载。
运行结束后会在命令行窗口打印三组关键数据:量测配置统计(各类量测数量)、估计精度指标(MAE和最大偏差)、坏数据检测结果(标记出的坏数据编号)。同时会弹出两个MATLAB figure窗口:一个显示各节点电压幅值的WLS估计值与NR基准的对比柱状图,另一个显示相角对比曲线。
8.2 按需调整参数速查表
我自己在实际测试中经常调整的参数列一张速查表,读者运行时可以对照修改:
| 参数名 | 所在文件 | 默认值 | 调整说明 |
|---|---|---|---|
| 量测噪声标准差 | generate_meas.m | 0.01 | 调大后估计精度下降,考验算法鲁棒性 |
| PMU安装节点列表 | main.m | [5 9] | 更换PMU位置,观察精度变化 |
| 坏数据注入节点 | bad_data.m | 节点7注入有功 | 修改后验证检测算法的通用性 |
| WLS收敛阈值 | run_wls.m | 1e-6 | 实际工程可取1e-4,收敛更快 |
| 标准化残差阈值 | bad_data.m | 3.0 | 调大后漏检率上升,调小后误检率上升 |
8.3 一个关于扩展的实验思路
如果读者想把项目再往前推一步,可以尝试把WLS换成鲁棒估计方法(比如Huber估计或指数型目标函数),对抗差效果做横向对比。这个扩展方向能把这些年比较热门的鲁棒状态估计概念落到实处,也更容易出论文素材。算法的骨干逻辑不用大改,只需替换目标函数和迭代修正量求解部分。另外,把PMU数据的时间序列特性利用起来,从静态估计扩展到带动态模型的跟踪估计(比如使用卡尔曼滤波框架),也是一个非常自然的升级方向。
我在实际项目中跑这个项目代码的时候,还顺手做了一个小尝试——把量测数据里的PMU相角统一加了一个0.02弧度的偏置,模拟PMU时钟同步不理想的情况。WLS结果里系统所有节点相角的估计值也都跟着偏了约0.02弧度,但幅值几乎不受影响。这说明在PMU数据直接参与估计时,参考相角的准确性非常重要,现场运维时对PMU的守时精度一定要严格要求。这些细节如果不跑代码光看书,很难有切身体会。
如果你要用这个项目出报告或者论文,我建议把你自己的量测配置对比实验表放进去,比如SCADA和PMU权重比不同时的估计精度变化。这类实验可以完全复用现有代码,只需把权重矩阵的对角元素做一些调整。祝你在状态估计这条路上少踩坑、多出成果。