ARTICLE DETAIL

资讯详情

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

电力系统动态状态估计的EKF与UKF实现:Matlab完整对比实战

电力系统动态状态估计的EKF与UKF实现:Matlab完整对比实战 这阵子我在做电力系统动态状态估计的对比实验正好需要把扩展卡尔曼滤波EKF和无迹卡尔曼滤波UKF两种算法放在同一套电力系统动态模型上用Matlab完整实现一遍。整个过程从模型搭建、噪声设置、滤波循环到调参踩坑跨度不小但做完之后对两种非线性滤波的认识彻底清晰了。这篇文章就把整套实现思路、核心代码逻辑和实际调试经验完整写下来给正在做电力系统动态状态估计的同行或者刚入门非线性滤波想找个真实工程场景练手的读者一份可以直接参考的样本。这个方向其实挺典型的电力系统的静态状态估计SSE大家都很熟了基于潮流方程做加权最小二乘解一个稳态断面。但到了动态状态估计DSE问题就变成了处理发电机转子运动方程这类非线性动态模型需要在量测噪声和模型不确定性同时存在的情况下实时跟踪功角、转速这类状态量。EKF和UKF恰好是最经典的两类非线性滤波器计算量适中、Matlab实现友好作为起点再合适不过。不想看原理推导的同学可以直接跳到第3章的代码框架照着改但我建议还是把第2章的建模思路过一遍否则后面调参会比较痛苦。1. 电力系统动态状态估计从静态到动态的必然演进1.1 静态状态估计为什么不够用传统的电力系统静态状态估计核心任务是基于SCADA系统提供的量测数据估计出当前时刻系统的母线电压幅值和相角。SCADA的数据刷新周期通常在秒级甚至几十秒级采集到的往往是稳态断面因此SSE天然是“快照式”的——每个时间断面独立求解断面之间没有时序约束也没有把系统的动态物理过程纳入考虑。问题在于电力系统本质上是个连续动态系统。发电机是旋转机械转子运动方程决定了功角和转速在扰动发生后的毫秒到秒级时间尺度内会持续变化。当系统遭遇短路故障、负荷突变或机组跳闸时功角会快速摆动电压相角也会剧烈波动。这时候静态状态估计的“逐个断面孤立求解”模式就跟不上系统的动态行为了。你拿到的量测数据可能已经是一个动态过程的中途快照用稳态潮流模型去硬解结果自然失真。PMU同步相量测量装置大规模部署之后这个矛盾更加突出。PMU能以30帧/秒甚至60帧/秒的速率上传带时标的电压、电流相量数据数据量是SCADA的几十倍。数据变丰富了信息密度变高了但如果没有一个能把量测序列和物理模型融合起来的估计器海量数据反而会淹没掉真正关键的状态信息。这正是动态状态估计的核心价值把模型预测和实时量测在贝叶斯框架下融合逐拍输出系统状态的实时最优估计。1.2 动态状态估计的问题本质动态状态估计本质上是求解一个非线性状态估计问题。系统的动态过程用状态空间模型描述状态方程过程模型描述状态量如何随时间演化来源于发电机转子运动方程、励磁系统动态方程等量测方程观测模型描述量测量和状态量之间的映射关系来源于电网的电气量计算关系。由于电力系统是强非线性的状态方程和量测方程都不是线性的。发电机的电磁功率与功角之间是正弦函数关系状态方程里的角速度更新又含有非线性乘积项。因此动态状态估计不能直接套用经典的线性卡尔曼滤波KF必须使用非线性滤波方法。处理非线性状态估计工程上有两条主流路线。一条是解析近似路线把非线性函数在当前估计点附近做泰勒展开只保留一阶项这就是扩展卡尔曼滤波EKF的基本思想。另一条是统计近似路线找一组确定性采样点Sigma点把这些点通过非线性函数传播再用传播后的点的样本均值和协方差去近似状态的后验分布这就是无迹卡尔曼滤波UKF的基本思想。1.3 为什么先选EKF和UKF这里有个很现实的选型逻辑。粒子滤波PF理论上能处理任意非线性非高斯场景但计算量太大在电力系统在线估计这种对实时性有要求的场景下往往跑不起来。而EKF和UKF的计算量都只在O(n^3)量级n为状态维数在发电机动态估计这类低维状态空间中通常是2到6维完全能满足在线计算需求。EKF的优势在于实现简单、代码量少、对线性化点附近的系统有较好的估计精度计算效率也最占优。UKF的优势则是不需要计算雅可比矩阵对强非线性模型的近似精度更高尤其是当系统非线性程度较高、线性化误差不可忽略时UKF通常能获得比EKF更稳定的估计结果。把两种方法在同一个模型、同一组噪声参数下做对比既能验证算法的适用性边界也能在实际项目里根据精度和速度要求做取舍。这也是这篇文章选择同时实现EKF和UKF的原因。2. 动态模型与状态空间方程搭建2.1 单机无穷大系统的发电机动态模型动态状态估计的第一步是建立系统的状态空间模型。为了把核心逻辑讲清楚同时让代码保持简洁我选用单机无穷大Single Machine Infinite Bus, SMIB系统作为仿真对象。这套模型虽然简单但包含了发电机动态估计的核心要素完整理解之后向多机系统扩展只是增加状态维数和量测配置的问题。SMIB系统下发电机采用经典二阶模型状态变量取为转子功角δ和转子角速度偏差Δω后文直接用ω表示指代相对于同步转速的偏差。连续时间状态方程为dδ/dt ω - ω0dω/dt (ω0 / (2H)) × (Pm - Pe - D(ω - ω0))其中ω0是同步角速度50Hz系统对应314.1593 rad/sH是发电机的惯性时间常数D是阻尼系数Pm是机械功率输入Pe是电磁功率。电磁功率Pe与功角δ的关系通过简化的电网络方程确定Pe (E′ × V / x′d) × sin(δ)这里E′是发电机暂态电动势V是无穷大母线电压通常取1.0 pux′d是发电机暂态电抗。所有电气量均采用标幺值制。这套二阶模型的物理含义很直观功角的变化率由转速差决定转速的变化率由加速功率Pm - Pe和阻尼决定。扰动发生后机械功率和电磁功率的失衡会让发电机转子加速或减速功角随之摆动再反过来影响电磁功率。整个动态过程形成了一个闭环的机电振荡回路而动态状态估计要做的事情就是从带噪声的量测中实时还原这条振荡轨迹。2.2 量测方程与可观测性分析动态状态估计的量测配置决定了状态量能不能被“看到”。在我的仿真里量测向量选为发电机的电磁功率Pe和转子功角δ即z [Pe; δ]。对应的量测方程为h1(x) (E′ × V / x′d) × sin(δ)h2(x) δ这里要特别强调可观测性的问题。如果仅量测电磁功率Pe那么功角δ和角速度ω的联合可观性会变得很微妙Pe只与δ有关角速度ω只能通过状态方程中的耦合关系间接获得一旦系统接近稳定状态ω ω0这种间接可观测性会变得非常弱。实际调试中我发现只测Pe时EKF的功角估计往往会出现缓慢漂移直到扰动再次激发动态响应才能校正回来。因此在SMIB仿真中我直接加入功角量测保证状态量可以被直接观测对于更复杂的多机系统或受限于PMU配置的场景一般还需要加入母线电压相角、线路有功潮流等量测来保证全系统可观。2.3 离散化处理与噪声注入状态方程是连续时间的但卡尔曼滤波的预测更新必须在离散时间步上执行。这里用最简单的显式欧拉法做离散化取采样周期Ts 0.02s对应50Hz采样率和PMU的典型上传速率接近比较贴近实际应用场景。离散后的状态方程写成x_{k1} x_k f(x_k) × Ts w_k量测方程离散为z_k h(x_k) v_k其中过程噪声w_k满足均值为0、协方差为Q的高斯分布量测噪声v_k满足均值为0、协方差为R的高斯分布。Q和R的取值与实际系统的噪声水平相关在仿真中Q一般设置为对角阵量级根据状态量的动态范围去匹配R则根据量测装置的仪表精度设定。这两个矩阵的参数整定经验我在第4章详细展开。这里有一个新手很容易踩的坑显式欧拉法的截断误差和采样周期Ts直接相关Ts越大离散化误差越大。如果状态变化太快而Ts选得过大离散方程本身就和真实连续动态偏差很大再好的滤波器也救不回来。我在实测中建议Ts取0.01~0.05s之间。对于二阶SMIB模型0.02s是一个精度和计算负担都合适的值。3. EKF与UKF原理和Matlab实现3.1 EKF滤波循环与雅可比矩阵推导EKF的核心思路是在每个时间步把非线性系统在当前估计点处做一阶泰勒展开然后用线性卡尔曼滤波的标准流程完成预测和校正。EKF的一个完整滤波周期包含五个步骤。第一步是状态预测用离散状态方程把上一时刻的状态后验估计x_{k-1}推演到当前时刻得到先验估计x_{k|k-1}。第二步是协方差预测用状态转移矩阵F的雅可比即f对x的偏导数矩阵完成协方差的线性传播再叠加上过程噪声Q。第三步是计算卡尔曼增益先用量测函数h在当前先验估计点的雅可比矩阵H计算新息协方差S再算出增益K。第四步是测量更新用实际量测z和预测量测h(x_pred)的差值乘以增益对先验状态做修正。第五步是协方差更新用标准的Joseph型或简化型公式更新后验协方差。对于前面建立的二阶SMIB模型状态转移雅可比F和量测雅可比H都有解析表达式不需要用数值差分去逼近实现起来非常干净。状态方程f(x)对x [δ; ω]求偏导再乘以采样周期加上单位阵就得到离散化的F矩阵量测方程h(x)对δ求偏导得到H矩阵。解析式的好处是计算精度高、速度快而且代码调试时可以直接核对数值结果我强烈推荐优先用解析式。3.2 EKF的Matlab核心代码实现这里给出EKF核心滤波循环的Matlab实现。假设仿真系统状态维数为2δ和ω量测维数为2Pe和δ状态转移函数和量测函数分别封装在函数文件里。主循环的核心代码如下% EKF主滤波循环 for k 2 : N % 状态预测 x_pred x_est(:, k-1) Ts * f_smib(x_est(:, k-1), Pm, E_prime, V, xd_prime, H_const, D_const, w0); % 状态转移雅可比矩阵 F解析式 ddelta x_est(1, k-1); dFedelta E_prime * V / xd_prime * cos(ddelta); F [1, Ts; -w0 / (2 * H_const) * dFedelta * Ts, 1 - D_const / (2 * H_const) * Ts]; % 协方差预测 P_pred F * P_est(:, :, k-1) * F Q; % 量测预测 z_pred h_smib(x_pred, E_prime, V, xd_prime); % 量测雅可比矩阵 H解析式 ddelta_pred x_pred(1); dFedelta_pred E_prime * V / xd_prime * cos(ddelta_pred); H [dFedelta_pred, 0; 1, 0]; % 卡尔曼增益 S H * P_pred * H R; K P_pred * H / S; % 状态校正 x_est(:, k) x_pred K * (z_meas(:, k) - z_pred); % 协方差校正 P_est(:, :, k) (eye(2) - K * H) * P_pred; end这里f_smib和h_smib分别是状态方程和量测方程的Matlab函数实现。整个EKF实现的核心逻辑非常紧凑一共就这十个步骤。我实际运行中体会EKF的代码量约为UKF的一半而且因为需要解析雅可比调试时更容易定位是模型的问题还是滤波逻辑的问题。但要注意当系统强非线性或采样周期较大时一阶线性化误差会直接反映在估计偏差里这是EKF的天生短板。3.3 UKF的Sigma点机制与参数选择UKF的思路完全不同。它不计算雅可比矩阵而是通过“无迹变换”把状态的均值和协方差编码到一组确定性采样点Sigma点中让每个点独立经过非线性函数传播再根据传播后的点重新计算均值和协方差。由于Sigma点保留了状态分布的二阶矩信息UKF对非线性函数的近似精度理论上可以达到二阶高于EKF的一阶精度。Sigma点的生成方式为给定n维状态均值x和协方差P取尺度参数λ α²(n κ) - n生成2n 1个Sigma点。其中第0个点就是状态均值本身剩下的2n个点沿协方差矩阵的特征方向对称分布距离由sqrt((n λ)P)控制。α控制Sigma点离均值的距离通常取1e-3到1之间的小值κ是一个次级缩放参数通常取0β用于融合先验分布信息在高斯分布下取2最优。生成Sigma点后它们通过状态方程和量测方程分别传播。时间更新阶段用传播后的Sigma点加权计算出先验均值和协方差测量更新阶段用量测方程传播后的Sigma点计算新息协方差、状态与量测的互协方差再按标准卡尔曼增益公式完成校正。整个过程不需要任何求导操作对黑箱模型或难以解析求导的复杂模型特别友好。3.4 UKF的Matlab核心代码实现UKF的核心循环实现如下。这里给出的代码完整的包含了Sigma点生成、时间更新和测量更新三个环节% UKF主滤波循环 n 2; lambda alpha^2 * (n kappa) - n; w_m [lambda/(nlambda); repmat(1/(2*(nlambda)), 2*n, 1)]; w_c [lambda/(nlambda) (1 - alpha^2 beta); repmat(1/(2*(nlambda)), 2*n, 1)]; for k 2 : N % 生成Sigma点 sqrtP sqrtm((n lambda) * P_est(:, :, k-1)); X_sigma zeros(n, 2*n1); X_sigma(:, 1) x_est(:, k-1); for i 1 : n X_sigma(:, i1) x_est(:, k-1) sqrtP(:, i); X_sigma(:, ni1) x_est(:, k-1) - sqrtP(:, i); end % 时间更新状态方程传播Sigma点 X_pred zeros(n, 2*n1); for i 1 : 2*n1 X_pred(:, i) X_sigma(:, i) Ts * f_smib(X_sigma(:, i), Pm, E_prime, V, xd_prime, H_const, D_const, w0); end % 加权计算先验均值与协方差 x_pred sum(w_m .* X_pred, 2); P_pred Q; for i 1 : 2*n1 diff X_pred(:, i) - x_pred; P_pred P_pred w_c(i) * (diff * diff); end % 测量更新量测方程传播Sigma点 Z_pred zeros(2, 2*n1); for i 1 : 2*n1 Z_pred(:, i) h_smib(X_pred(:, i), E_prime, V, xd_prime); end z_pred sum(w_m .* Z_pred, 2); % 计算新息协方差与互协方差 S_ukf R; P_xz zeros(n, 2); for i 1 : 2*n1 diff_z Z_pred(:, i) - z_pred; diff_x X_pred(:, i) - x_pred; S_ukf S_ukf w_c(i) * (diff_z * diff_z); P_xz P_xz w_c(i) * (diff_x * diff_z); end % 卡尔曼增益与状态更新 K P_xz / S_ukf; x_est(:, k) x_pred K * (z_meas(:, k) - z_pred); P_est(:, :, k) P_pred - K * S_ukf * K; end这段代码里我特意用了最直白的循环写法没有用向量化优化目的是让每一步的数学含义都清清楚楚。实际项目里如果追求性能可以把Sigma点的传播改成矩阵批量运算速度会有明显提升。但第一次实现时我建议先用这种逐点传播的写法方便和EKF对照验证。值得注意的是UKF的协方差更新我用了增益-新息协方差的减式形式这在数值上等价于标准更新公式但在某些病态情况下更稳定。另外sqrtm是用来对矩阵求平方根的实际工程中更推荐用Cholesky分解chol函数替代因为sqrtm对非正定矩阵的敏感性更低一些。4. 仿真参数配置与结果分析方法4.1 仿真场景设计与关键参数整定搭建完代码框架后下一步就是设计仿真场景并配置参数。我采用的仿真参数如下发电机惯性时间常数H取4.0s阻尼系数D取2.0暂态电动势E′取1.05 pu暂态电抗x′d取0.3 pu无穷大母线电压V取1.0 pu机械功率Pm在初始稳态时取0.8 pu。为了制造动态过程让系统“动起来”我在t 2s时让机械功率Pm阶跃上升到0.9 pu模拟一次负荷扰动引发的机电暂态过程。状态初值设置为δ(0) 0.6155 rad由潮流计算获得的稳态功角ω(0) ω0即转速偏差为0。量测噪声协方差R取diag([1e-4, 1e-6])对应电磁功率量测噪声标准差约0.01 pu、功角量测噪声标准差约0.001 rad这个数值大致反映了PMU量测精度水平。过程噪声协方差Q取diag([1e-6, 1e-6])初始协方差P0取diag([0.1, 0.1])反映初始状态存在一定程度的不确定性。这几个参数的整定是有讲究的。Q矩阵决定了滤波器对模型的信任程度Q越小滤波器越相信状态方程量测的修正作用越弱Q越大滤波器越依赖量测数据跟踪速度变快但噪声也变大。我在调试中发现Q取diag([1e-6, 1e-6])时功角估计曲线比较平滑但如果把Q调大到1e-3量级功角曲线会出现明显的锯齿波动这是因为滤波器对量测噪声过度响应。这里分享一个经验性的调参顺序先固定R通常由仪表精度的先验知识决定不需要过度调然后从较小的Q出发逐渐增大观察估计曲线的平滑程度和跟踪响应。对于SMIB模型Q的对角元素量级通常在1e-6到1e-3之间而不是随意取到0.1或1。我最初就是直接取了比较大的Q导致滤波曲线几乎完全跟踪量测、噪声污染严重花了一些时间才摸清规律。4.2 EKF与UKF的估计结果对比为了对比两种滤波器的性能我在完全相同的仿真场景、完全相同的Q/R参数和完全相同的初始条件下分别运行EKF和UKF并计算各个状态量的均方根误差RMSE。仿真时长设为10s采样周期0.02s共500个时间步。UKF的无迹变换参数取α 0.01β 2κ 0。从实际运行结果看两种滤波器都能在扰动发生后快速跟踪功角和转速的真实轨迹但细节上有明显差异。在电磁功率阶跃的瞬间功角开始加速摆动非线性程度短期内显著增强EKF的估计误差在这个阶段会出现小幅尖峰而UKF的误差曲线相对平滑几乎看不到线性化误差的影响。在动态过程趋于平稳后两者的估计精度非常接近RMSE差距缩小到几乎可忽略的程度。从数值上统计整个仿真时间段内UKF对功角估计的RMSE通常比EKF低20%到40%转速估计的RMSE差距则相对小一些大约10%到20%。计算耗时方面UKF因为需要生成和传播5个Sigma点耗时大约是EKF的3到5倍。对SMIB这种2维状态模型来说两种算法的单步耗时都在毫秒级以下实际在线使用都不成问题。结论很清晰在状态维数低、实时性要求高的场景EKF的性价比其实很高如果系统非线性强或者对精度要求高UKF是更稳妥的选择。4.3 结果可视化与RMSE评估仿真结果的可视化是判断滤波效果的重要手段。我习惯用三张图做完整评估第一张图画出真实状态、量测值、EKF估计值和UKF估计值四条曲线直观观察跟踪效果第二张图画出两种算法的估计误差随时间的演化曲线重点观察扰动发生后的误差尖峰和收敛速度第三张图画出状态估计协方差P的对角线元素即估计方差的演化检查滤波器是否“过度自信”——如果估计方差快速收缩到极小值而实际误差却很大说明滤波器出现了不一致性问题。RMSE的计算方式很简单对整个仿真时间段取每个时刻估计误差的平方均值再开方即可。我建议把功角误差和转速误差分开统计因为两者的量纲和物理意义完全不同合并成一个综合指标反而掩盖了问题所在。另外我还会额外统计稳态阶段比如t 4s以后的RMSE用来衡量滤波器的稳态精度与包含瞬态阶段的整体RMSE形成对照。5. 调试中的常见问题与避坑经验5.1 滤波发散症状、成因与定位顺序滤波发散是动态状态估计调试中最常见的故障现象是估计值和真实值之间的偏差越来越大直至完全脱离真实轨迹。造成发散的原因通常集中在三个方面状态不可观测、模型与实际系统不匹配、噪声协方差设置失当。我的排查顺序是先检查可观测性。如果量测配置有问题比如只量测了Pe而没有量测功角滤波器在系统趋于稳态后就会逐渐失去对δ的约束能力估计值慢慢漂移。这一步通过检查量测雅可比H矩阵是否满列秩就能判断。第二步检查模型参数是否和真实系统一致尤其是惯性时间常数H和阻尼系数D这两个参数直接影响状态预测的质量如果错误滤波器会不断用错误的模型做预测量测校正也挽救不回来。第三步再检查Q/R的比例关系Q过小导致滤波器对模型过度自信遇到模型偏差就发散Q过大则估计方差无法收敛曲线乱跳。我实际调试中踩得最深的坑是一开始为了“让滤波器多相信量测”把Q设得很大、R设得很小结果功角曲线跟着量测噪声剧烈抖动而且P矩阵迟迟不收敛。后来把Q降到1e-6量级后曲线立刻变得平滑滤波器也能充分平滑量测噪声。记住一条原则Q和R不是越大越好或越小越好关键是两者比例要能反映你对模型和量测的真实信任程度。5.2 协方差矩阵病态与数值稳定性卡尔曼滤波类算法的数值稳定性问题不可忽视。在长时间的循环迭代中协方差矩阵P可能因为舍入误差积累而失去对称性或正定性进而导致后续计算出现问题。EKF的协方差更新采用(I - KH)P的形式时如果H矩阵有条件数较大的情况更容易出现P矩阵轻微不对称的问题。我常用的处理手段有两个。第一在每次迭代后对P矩阵做强制对称化P (P P) / 2这一步代码量几乎为零但很有效。第二用Joseph形式的协方差更新公式替代简化形式P (I - KH)P(I - KH) KRK这一形式在数值上能更好保持正定性代价是多两次矩阵乘法。UKF的sqrtm函数如果遇到P矩阵不正定会直接报错这时候改用Cholesky分解并加一个极小的单位阵修正P P 1e-6 * eye(n)通常能解决大部分数值问题。5.3 初值设定与可观测性问题初值的设定会影响滤波器的收敛速度和稳定性。如果初始状态和真实值偏差过大滤波器在初始阶段可能会出现明显的收敛过程甚至因为线性化点偏离真实轨迹太远而发生发散。对于电力系统动态状态估计我建议用静态状态估计的结果作为动态估计的初值即先做一次基于潮流方程的稳态求解把得到的功角作为动态滤波的初始状态转速初值直接设为同步转速。这个方法在实际工程里非常常见能极大改善滤波器的初始收敛性。需要注意的是即便采用了合理的初值初始协方差P0也不能设得太小。P0的物理意义是对初值不确定性的描述设得太小会让滤波器一开始就过度自信后续量测的修正作用被削弱收敛变慢。一般取P0的每个对角元素为0.01到0.1量级是比较稳妥的区间。5.4 UKF参数速查与工程建议UKF的α、β、κ三个参数虽然看似不起眼但对滤波性能有直接影响。这里把常见的取值规则和工程建议整理成一张速查表。参数典型取值范围作用与建议α1e-3 ~ 1控制Sigma点分布的扩展范围值越小Sigma点越集中在均值附近对强非线性系统建议取小值0.01以下β2高斯分布最优融合先验分布信息的高阶项高斯场景下固定取2即可无需调整κ0最常用次级缩放参数状态维数为2时取0高维状态下可以取3 - n保证四阶矩匹配我在实际使用中发现α取太大接近1会导致Sigma点分布过宽在强非线性区域引入较大的采样误差α取太小1e-4以下又会让Sigma点过于集中协方差传播时信息不足。0.01是平衡性比较好的取值大家可以以此为起点根据自己的模型微调。写在最后的实操体会整套代码从模型搭建到两种滤波器实现我在Matlab里反复跑了几十轮一个比较深的体会是EKF和UKF的差异并不只在纸面上的“精度高一阶”这么简单它对调试体验的影响更实际。用EKF时雅可比矩阵的解析推导虽然麻烦但推导出来之后每一步都能对照模型检查哪一步出错很容易定位用UKF时虽然省去了求导但Sigma点传播的过程更像是一个“黑箱”出了问题往往需要从权重、参数、协方差的数值逐项排查调试成本反而更高。如果你刚开始做电力系统动态状态估计我建议先用EKF跑通全流程确认模型、量测配置和噪声参数都没有问题之后再切换到UKF做精度对比。另外一个小技巧是调试阶段可以把真实状态和量测值都保存下来用一张图同时画出真实值、量测值和估计值对比着看能帮你一眼判断是滤波逻辑问题还是模型问题。这套代码框架本身也能扩展状态变量可以加入励磁系统动态、调速器动态甚至负荷模型量测配置也可以扩展到多节点、多台机的PMU量测组合。顺着这个框架改比从头搭建要省很多事。
返回列表