资源简介

参照薛定宇教授《控制系统计算机辅助设计:MATLAB语言与应用》第二版中8.3.3章节中的内容编写代码和搭建模型,对书中代码进行了部分修改,解决了权值初始化问题,采用二次选择后的权值做初值,控制效果比较理想,并在代码中编写了比较详细的注释。

资源截图

代码片段和文件信息

function [sysx0strts]=nnbp_pid(txuflagTnhxitealfakF1kF2)
%T是采样时间,nh是隐含层数量,xite是学习率,alfa是动量因子,kF1和kF2的值分别来选择隐含层和输出层的激活函数
%以上参数在双击main中BP_PID模块后可以设置
switch flag 
    
case 0 [sysx0strts] = mdlInitializeSizes(Tnh); 
case 3 sys = mdlOutputs(txuTnhxitealfakF1kF2); 
case {1 2 4 9}sys = []; 
otherwise error([‘Unhandled flag =‘num2str(flag)]);
    
end;
% 初始化函数
function [sysx0strts] = mdlInitializeSizes(Tnh)

sizes = simsizes; 

% 读入模板,得出默认的控制量
sizes.NumContStates = 0;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 4+7*nh;
%输出包括ukpkikdwi(4*nh)个及wo(3*nh)个
sizes.NumInputs = 7+14*nh;
%输入包括error(k)error(k-1)error(k-2)yout(k)yout(k-1)...
%rinu(k-1)wi_2(4*nh)个wo_2(3*nh)wi_1(4*nh)个及wo_1(3*nh)个
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;

sys = simsizes(sizes);
x0 = [];
str = [];
ts = [T 0];
% 系统输出计算函数
function sys = mdlOutputs(txuTnhxitealfakF1kF2)

wi_2=reshape(u(8:7+4*nh)nh4);
wo_2=reshape(u(8+4*nh:7+7*nh)3nh);
wi_1=reshape(u(8+7*nh:7+11*nh)nh4);
wo_1=reshape(u(8+11*nh:7+14*nh)3nh);
%权值更新,但有初始化问题(若不初始化,权值初值均为0,pid三个参数经过计算会一直保持为0.5)

% if sum(wi_2)==0  %初始化
%     wi_2=0.5*rands(nh4);
%     wo_2=0.5*rands(3nh);
%     wi_1=0.5*rands(nh4);
%     wo_1=0.5*rands(3nh);
% end

%以上注释的if---end部分为随机初始权值,效果不理想,采用以下代码对权值进行二次选择后作为初始权值,效果比较理想
%w_data.mat文件为权值随机初始化,输出稳定后确定的权值数据,可以load后作为网络初始权值,控制效果比较理想

if sum(wi_2)==0  %权值二次选择后初始化
    load w_data; 
    u=WW‘;       %WW里面前7个数据没有用,只是为了保持代码一致,随机给赋了7个值
    wi_2=reshape(u(8:7+4*nh)nh4);
    wo_2=reshape(u(8+4*nh:7+7*nh)3nh);
    wi_1=reshape(u(8+7*nh:7+11*nh)nh4);
    wo_1=reshape(u(8+11*nh:7+14*nh)3nh);
end
  
xi=[u([641])‘ 1]; %xi=[rinyouterror1]
xx=[u(1)-u(2);u(1);u(1)+u(3)-2*u(2)]; %增量式PID三个本量
I=xi*wi_1‘;
Oh=non_transfun(IkF1); 
K=non_transfun(wo_1*Oh‘kF2);
uu=u(7)+K‘*xx;
dyu=sign((u(4)-u(5))/(uu-u(7)+0.0000001));
dK=non_transfun(K3);  %输出层激活函数的导数
delta3=u(1)*dyu*xx.*dK;
wo=wo_1+xite*delta3*Oh+alfa*(wo_1-wo_2);
dO=2*non_transfun(I3);  %隐含层激活函数的导数
wi=wi_1+xite*(dO.*(delta3‘*wo))‘*xi+alfa*(wi_1-wi_2);
sys=[uu; K;wi(:);wo(:)];  %输出数量为4+7*nh
% 激活函数及导数
function W1=non_transfun(Wkey)
switch key 
case 1 W1=(exp(W)-exp(-W))./(exp(W)+exp(-W)); %隐层激活函数
case 2 W1=exp(W)./(exp(W)+exp(-W));           %输出层激活函数
case 3 W1=2./(exp(W)+exp(-W)).^2;             %输出层激活函数的导数
end



 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----

     文件       2654  2018-11-07 19:46  sfunction_Cnnbp_pid.m

     文件        772  2018-11-01 21:08  w_data.mat

     文件      16239  2018-11-07 19:53  main.slx

----------- ---------  ---------- -----  ----

                19665                    3


评论

共有 条评论