An improved virtual synchronous generator power control strategy
Deep reinforcement learning based parameter self-tuning control
基于改进型RBF神经网络的VSG转动惯量自适应控制_杨旭红
基于RBF的VSG转动惯量和阻尼系数自适应控制策略_高子轩
基于虚拟同步发电机的逆变器并网稳定性研究_姚凤军
基于S函数的BP神经网络P...制器及Simulink仿真_杨艺
基于BP神经网络PID控制+Simulink仿真
想做一个把虚拟同步发动机中转动惯量J自适应调节的仿真,于是参考了姚凤君硕士的论文,在做仿真的时候遇到很多问题,主要是S函数怎么使用,网上资料很少,后来参考了csdn上一些博文,还看了杨艺的论文,摸索了一些方法,不能说完全掌握了s函数模块的使用,至少在一定程度上能复现出姚凤君论文中的效果了。
一般来说,神经网络算法是基于数据集来做预测和识别的,运用到控制系统里做参数自适应调节的例子不多,但是它是有潜力做这个工作的,毕竟其对非线性关系的拟合效果很好,能描述非线性关系。但是也有缺陷,那就是神经网络算法计算需要时间,怎么将这个时间尺度匹配好,还需要做更多优化,不能让基于t-1时刻状态得到的参数,拿来应用的时候已经是t+1时刻了,这样很有可能会导致系统的失调和震荡。
关于VSG相关的一些原理可以看我其他博文或者高子轩和姚凤军的论文,简单地说就是VSG的参数J(转动惯量)对VSG性能影响很大,主要体现在当有功功率指令变化(接入负载或负载撤去)时,产生的电网频率波动和有功功率、无功功率震荡,我们的目的是采用RBF神经网络,让它根据电网频率的偏差和变化率,取调节实时输出的转动惯量J,已达到减小电网频率波动的目的。那么输入就是两个,Δω和dω/dt,输出就是J。
下面着重来讲程序和仿真设计。
使用的版本是matlab2022a,我相信在其他版本下也可以完成这个建模。以下展示几个关键位置:
以下是转子机械方程:
设定中,有功功率在0.5秒时从5kw突增到20kw,再在0.8秒回到5kw。
detaw和dw_dt是用来观测的,删去也无所谓。
内部设置,mux模块,从上到下,是u(1),u(2),u(3)和u(4),里面前两个输入后面将作为神经网络的输入,乘以0.1是因为我想做数据归一化,尝试很多参数后发现0.1可行,大家可以自己改进这里的预处理形式,也可以把预处理封装携程代码坐进是模块中。里面的1/Z模块是延时模块Unit delay,这里表示ω(t-1),这些部分是和后面的RBF_VSG_a_4算法中联系起来的,里面使用的u(1)对应就是我外面输入进去的max第一个值。
s函数的设置就是你在外面写一个.m函数就行,保存,但是它有固定格式的。
我们怎么封装进去呢?
选择我圈出来的这个,双击,点编辑,浏览,找到你写的函数,双击
会弹出以下界面:
在编辑器中点运行-添加到路径。一定要有这一步,不然matlab找不到这个m文件的位置,你以后运行这个模型的时候,如果找不到文件位置,再进去点一下运行,报错不要紧,肯定会报错告诉你参数不足,但是一定要运行,添加到路径!
把这个名字复制到这里,点应用,这里要注意,文件名,文件中的代码(上图),仿真s函数中的名字要是一样的,缺一不可。 再把它连接到仿真里面去,就可以了,连接完就是这小节图二的样子。
重点再算法,原理就不说太多了,这里目的是教学使用s函数写代码,具体原理可以看论文:基于虚拟同步发电机的逆变器并网稳定性研究_姚凤军
这里使用的是2-5-1的结构,径向基函数的ci为0,bi为1,所以在代码里面我根本不定义这两个值,直接使用,需要用的可以定义,注意是向量的形式。
s函数可以识别C语言,我就用c语言编写了。代码注释很详细,不懂得可以看看,懂得劳烦多按删除键。
function [sys,x0,str,ts,simStateCompliance] = RBF_VSG_a_4(t,~,u,flag)
% 网络结构2-5-1的径向基函数,这里是定式,等号前面就这么写,等号后面是输入,输入t表示时间,~原来是x,表示中间变量,我这里没有中间变量,所以用~代替,u是输入,我们这里有4个,用u(i)表示,flag是标志位,后面细说
%u为输入矢量
%sys是系统输出
%x0是系统状态变量的初值
%str为保留参数且一直是空值
%ts是采样时间
%flag是标志位
%================================================
%flag | 调用函数 | 功能
% 0 |mdlInitializeSize |系统模型初始化函数
% 1 |mdlDerivatives |连续系统状态变量导数
% 2 |mdlUpdate |离散系统状态变量更新
% 3 |mdlOutputs |系统模型输出
% 4 |mdlGetTimeOfNextVarHit|计算下一个采样点时间
% 9 |mdlTerminate |仿真结束调用函数
%================================================
Ts = 0.005;%采样时间,每0.005秒进行一次计算,这个可以改的,大家根据需要来改
switch flag%flag可以为012349,分别的功能请参考杨艺的论文,这里用的功能3,输出值,因为我们要得到输出的J,功能0,初始化,别的功能不需要
case 0
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(Ts);%标准格式,这里可以定义外部封装参数,比如从外部输入隐藏层层数,我们不需要这个功能
case 3
sys=mdlOutputs(t,u);%在使用case 3的时候,需要用到t(仿真时间)和u(输入值),等号前面的sys是输出,我们后面会把J的计算结果给它,让它带到代码之外
case {1,2,4,9}
sys=[];%不需要的功能给空
otherwise
DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));%标准格式
end
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(Ts)%初始化,case 0
sizes = simsizes;
sizes.NumContStates = 0;%连续变量个数,不存在,毕竟我们的中间变量x=0
sizes.NumDiscStates = 0;%离散变量个数,不存在,理由同上
sizes.NumOutputs = 1;%输出变量是1个,就是J,在代码里面是J
sizes.NumInputs = 4;%4个输入,u1-4
sizes.DirFeedthrough = 1;%馈通,这里是1,尝试写为0,发现抱错
sizes.NumSampleTimes = 1;%默认为1
sys = simsizes(sizes);
x0 = [];%状态变量的初始值
str = [];
ts = [Ts 0];%采样时间
simStateCompliance = 'UnknownSimState';
function sys=mdlOutputs(t,u)%这里开始计算,case 3
persistent w w_1 h J_1 dw dw_1 J E_1%全局变量,我们用这种方式来代替x,保证在下一个计算时也可以使用上一次计算的结果
% RBF网络学习效率
xite = 0.5;
% RBF网络惯性系数
alfa = 0.05;
% 高斯基函数宽度
% b = 1;
if t == 0%初始化
J_1=0.05;%J_1的意思就是J(t-1)
%J的初始化
% c = 0;
h = zeros(5,1);%初始径向基函数设定值,你给个任意值就行了,反正要覆写的,我给的全0
w = rand(5,1)*(-1);%初始权值,也是随便给,我给的全为负
w_1 = w;
dw_1=0;
E_1=0;
end
RBF_input = [u(1) u(2)]';%输入层输入=隐层输入
%这里的u1和u2分别是△ω和d_ω/d_t
for j = 1:5%5个神经元
h(j) = exp(-norm(RBF_input)^2/2);%计算隐层输出,高斯基函数输出
end
ho_input=sum(h*w_1');%输出层输入,把隐层的5个结果加一起
yoout=0.5*exp(ho_input)/(exp(ho_input)+exp(-1*ho_input));%输出层激活函数,类似sigmoi
if yoout >=0.45
J = 0.450;
else if yoout <=0.035
J = 0.035;
else
J = yoout;%确保J在范围[0.035,0.45]内
end
%下面做权值更行,方法是改进的梯度下降法,具体见论文基于虚拟同步发电机的逆变器并网稳定性研究_姚凤军
end
o1=xite*u(1);%数
o2=sign((u(3)-u(4))/(yoout-J_1));%符号
o3=yoout*h;%向量,dim(5*1)
o4=alfa*dw_1;%向量,dim(5*1)
dw=o1*o2*o3+o4;
dw_1=dw;
%定义评价函数,如果上一次输入的电网频率偏差值或者这次输入的电网频率偏差值为0,就表明不需要调整权值
E=0.5*(u(1))^2;
if E_1*E == 0
w = w_1;
else
w = w_1-dw;
end
E_1=E;
w_1 = w;
J_1 = J;%下一次计算时,J(K-1)=本次输出的yoout也就是J
sys = J;
这个代码很简单,里面肯定有些漏洞,请大家看的时候多思考,但是基本功能是能实现的。
和固定参数(J=0.3)的对比
电网频率波动
可见RBF调节下的电网频率调节时间更快,但是超调量会增加,大概增加了2.25rad/s,超调量为0.7%,远小于电网准入标准的2.5%,说明性能达标。
无功功率对比,超调量增加,调节时间变短
有功功率对比,超调量和调节时间均好于固定参数!
诚然,这次实验从实验结果来看,是令人满意的,但是能看见电网频率在RBF调节下,在有功功率指令突变的时候,会发生一个陡峭的上升,这样的冲击,对用电设备是非常不利的,说明这个方法,至少在我复现的模型中,还有改进空间,那就是J能不能不要在0.45和0.035之间跳变,而是有个上升的过程。这说明算法还是有改进空间的,我觉得也许要把阻尼系数放进来一起调节,或许有助于改善这个问题。
不过对于熟悉s函数操作编程,模型搭建的入门来说,这个实例已经足够用了,感谢大家阅读本文,希望我的分享对大家有帮助。欢迎点赞和关注!