格斯文档网

您现在的位置是:格斯文档网 > 述职报告 >

智能控制实验报告

 智能控制实验报告

 姓名:

 学院:

 专业:自动化 班级:

  学号:

 指导教师:

 成绩:

 2019 年 12 月 25 日

 实验一

 模糊控制在角度随动系统中的应用 一、实验目的与意义 学习 Matlab 中建立模糊控制器的方法;了解模糊控制在角度随动系统中的

 应用。

 二、实验内容 在 Matlab 中建立模糊控制器,将生成的模糊规则表插入程序代码中,交叉

 编译代码,下载到目标版中进行测试。

 1 、Matlab 文本模式建立模糊控制器(必做)

 2 、利用 Matlab 模糊逻辑工具箱建立模糊控制器(选做)

 3 、模糊控制器 Simulink 仿真(必做)

 4 、嵌入式程序交叉编译(选做)

 三、实验结果 1 、matlab 文本模式建立模糊控制器 %Fuzzy Controller Design clear all;

 close all;

 %新建 FIS a=newfis("myfuzzy");

 %输入 e,范围[-48,48],7 个模糊语言,NB,NM,NS,Z,PS,PM,PB a=addvar(a,"input","e",[-48 48]);

 %Parameter e a=addmf(a,"input",1,"NB","trimf",[-48 -36 -24]); a=addmf(a,"input",1,"NM","trimf",[-36 -24 -12]); a=addmf(a,"input",1,"NS","trimf",[-24 -12 0]); a=addmf(a,"input",1,"Z","trimf",[-12 0 12]); a=addmf(a,"input",1,"PS","trimf",[0 12 24]); a=addmf(a,"input",1,"PM","trimf",[12 24 36]);

 a=addmf(a,"input",1,"PB","trimf",[24 36 48]);

 %输入 ec,范围[-64,64],7 个模糊语言,NB,NM,NS,Z,PS,PM,PB a=addvar(a,"input","ec",[-64 64]);

 %Parameter ec a=addmf(a,"input",2,"NB","trimf",[-64 -48 -32]); a=addmf(a,"input",2,"NM","trimf",[-48 -32 -16]); a=addmf(a,"input",2,"NS","trimf",[-32 -16 0]); a=addmf(a,"input",2,"Z","trimf",[-16 0 16]); a=addmf(a,"input",2,"PS","trimf",[0 16 32]); a=addmf(a,"input",2,"PM","trimf",[16 32 48]); a=addmf(a,"input",2,"PB","trimf",[32 48 64]);

 %输出 u,范围[-90,90],7 个模糊语言,NB,NM,NS,Z,PS,PM,PB a=addvar(a,"output","u",[-90 90]);

 %Parameter u a=addmf(a,"output",1,"NB","trimf",[-90 -67.5 -45]); a=addmf(a,"output",1,"NM","trimf",[-67.5 -45 -22.5]); a=addmf(a,"output",1,"NS","trimf",[-45 -22.5 0]); a=addmf(a,"output",1,"Z","trimf",[-22.5 0 22.5]); a=addmf(a,"output",1,"PS","trimf",[0 22.5 45]); a=addmf(a,"output",1,"PM","trimf",[22.5 45 67.5]); a=addmf(a,"output",1,"PB","trimf",[45 67.5 90]);

 %模糊规则表,7*7 = 49 行,5 列 rulelist=[1 1 1 1 1;

  1 2 1 1 1;

  1 3 1 1 1;

  1 4 2 1 1;

  1 5 2 1 1;

  1 6 3 1 1;

  1 7 4 1 1;

  2 1 1 1 1;

  2 2 1 1 1;

  2 3 1 1 1;

  2 4 2 1 1;

  2 5 2 1 1;

  2 6 3 1 1;

  2 7 4 1 1;

  3 1 1 1 1;

  3 2 2 1 1;

  3 3 2 1 1;

  3 4 3 1 1;

  3 5 4 1 1;

  3 6 5 1 1;

  3 7 6 1 1;

 4 1 1 1 1;

  4 2 3 1 1;

  4 3 3 1 1;

  4 4 4 1 1;

  4 5 5 1 1;

  4 6 6 1 1;

  4 7 7 1 1;

  5 1 2 1 1;

  5 2 3 1 1;

  5 3 4 1 1;

  5 4 5 1 1;

  5 5 6 1 1;

  5 6 7 1 1;

  5 7 7 1 1;

  6 1 3 1 1;

  6 2 4 1 1;

  6 3 5 1 1;

  6 4 6 1 1;

  6 5 7 1 1;

  6 6 7 1 1;

  6 7 7 1 1;

  7 1 4 1 1;

  7 2 5 1 1;

  7 3 6 1 1;

  7 4 6 1 1;

  7 5 7 1 1;

  7 6 7 1 1;

  7 7 7 1 1;

 ];

 a=addrule(a,rulelist); %showrule(a)

 % Show fuzzy rule base

 a1=setfis(a,"DefuzzMethod","centroid");

 % Defuzzy writefis(a1,"fuzzf");

  % save to fuzzy file "fuzz.fis" which can be

  % simulated with fuzzy tool a2=readfis("fuzzf"); disp("-------------------------------------------------------"); disp("

  fuzzy controller table:e=[-48,+48],ec=[-64,+64]

  "); disp("-------------------------------------------------------");

 Ulist=zeros(7,7);

  for i=1:7

 for j=1:7

  e(i)=-4+i;

  ec(j)=-4+j;

  Ulist(i,j)=evalfis([e(i),ec(j)],a2);

 end end

 Ulist=ceil(Ulist)

 figure(1); plotfis(a2); figure(2); plotmf(a,"input",1); figure(3); plotmf(a,"input",2); figure(4); plotmf(a,"output",1);

 运行结果:

 >> ksk -------------------------------------------------------

 fuzzy controller table:e=[-48,+48],ec=[-64,+64]

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

 Ulist =

  -13

  -11

 -8

 -6

 -4

 -2

 -1

 -11

 -9

 -7

 -4

 -2

 -1

  1

  -8

 -7

 -5

 -2

  0

  2

  3

  -5

 -3

 -1

  0

  2

  4

  6

  -2

 -1

  1

  3

  6

  8

  9

 0

  2

  3

  5

  8

 10

 12

 2

  3

  5

  7

  9

 12

 14

 2、 、 利用 Matlab 模糊逻辑工具箱建立模糊控制器步骤

 3、 、 模糊控制器 Simulink 仿真

  4、 、 嵌入式程序交叉编译 y Fuzzy 源代码:

 #define PMAX

 100 #define PMIN

 -100 #define DMAX

 100 #define DMIN

 -100 #define FMAX

 100 /*语言值的满幅值 */ /*输入量 P 语言值特征点*/ int PFF[4] = { 0, 12, 24, 48 };

 /*输入量 D 语言值特征点*/ int DFF[4] = { 0, 16, 32, 64 };

 /*输出量 U 语言值特征点*/ int UFF[7] = { 0, 15, 30, 45, 60, 75, 90 };

 /*采用了调整因子的规则表,大误差时偏重误差,小误差时偏重误差变化*/ /*a0=0.3,a1=0.55,a2=0.74,a3=0.89

  */ /* int rule[7][7] = {

 //误差变化率 -3,-2,-1, 0, 1, 2, 3

  // 误差

 {-13,-11,-8,-6,-4,-2,-1}, //

  -3 {-11,-9,-7,-4,-2,-1,1}, //

  -2 {-8,-7,-5,-2,0,2,3}, //

  -1 {-5,-3,-1,0,2,4,6}, //

 0 {-2,-1,1,3,6,8,9}, //

 1 {0,2,3,5,8,10,12}, //

 2

 {2,3,5,7,9,2,14} };*/

 int rule[7][7] = {

 //误差变化率 -3,-2,-1, 0, 1, 2, 3

  // 误差

  { -13,

 -11,

  -8,

  -6,

  -4,

  -2,

  -1},

 { -11,

  -9,

  -7,

  -4,

  -2,

  -1,

 1},

 { -8,

  -7,

  -5,

  -2,

 0,

 2,

 3 },

 { -5,

  -3,

  -1,

 0,

 2,

 4,

 6 },

 { -2,

  -1,

 1,

 3,

 6,

 8,

 9 },

 {

 0,

 2,

 3,

 5,

 8,

  10,

  12 },

 {

 2,

 3,

 5,

 7,

 9,

  12,

  14 }, }; /**********************************************************/ int Fuzzy(int P, int D) { /*模糊运算引擎 */ int U; /*偏差,偏差微分以及输出值的精确量 */ unsigned int PF[2], DF[2], UF[4]; /*偏差,偏差微分以及输出值的隶属度 */ int Pn, Dn, Un[4]; long temp1, temp2; /*隶属度的确定 */ /*根据 PD 的指定语言值获得有效隶属度 */ if (P > -PFF[3] && P < PFF[3]) { if (P <= -PFF[2]) { Pn = -2; PF[0] = FMAX * ((float) (-PFF[2] - P) / (PFF[3] - PFF[2])); } else if (P <= -PFF[1]) { Pn = -1; PF[0] = FMAX * ((float) (-PFF[1] - P) / (PFF[2] - PFF[1])); } else if (P <= PFF[0]) { Pn = 0; PF[0] = FMAX * ((float) (-PFF[0] - P) / (PFF[1] - PFF[0])); } else if (P <= PFF[1]) { Pn = 1; PF[0] = FMAX * ((float) (PFF[1] - P) / (PFF[1] - PFF[0])); } else if (P <= PFF[2]) { Pn = 2; PF[0] = FMAX * ((float) (PFF[2] - P) / (PFF[2] - PFF[1])); } else if (P <= PFF[3]) { Pn = 3; PF[0] = FMAX * ((float) (PFF[3] - P) / (PFF[3] - PFF[2])); } } else if (P <= -PFF[3]) {

 Pn = -2; PF[0] = FMAX; } else if (P >= PFF[3]) { Pn = 3; PF[0] = 0; } PF[1] = FMAX - PF[0]; if (D > -DFF[3] && D < DFF[3]) { if (D <= -DFF[2]) { Dn = -2; DF[0] = FMAX * ((float) (-DFF[2] - D) / (DFF[3] - DFF[2])); } else if (D <= -DFF[1]) { Dn = -1; DF[0] = FMAX * ((float) (-DFF[1] - D) / (DFF[2] - DFF[1])); } else if (D <= DFF[0]) { Dn = 0; DF[0] = FMAX * ((float) (-DFF[0] - D) / (DFF[1] - DFF[0])); } else if (D <= DFF[1]) { Dn = 1; DF[0] = FMAX * ((float) (DFF[1] - D) / (DFF[1] - DFF[0])); } else if (D <= DFF[2]) { Dn = 2; DF[0] = FMAX * ((float) (DFF[2] - D) / (DFF[2] - DFF[1])); } else if (D <= DFF[3]) { Dn = 3; DF[0] = FMAX * ((float) (DFF[3] - D) / (DFF[3] - DFF[2])); } } else if (D <= -DFF[3]) { Dn = -2; DF[0] = FMAX; } else if (D >= DFF[3]) { Dn = 3; DF[0] = 0; } DF[1] = FMAX - DF[0]; /*使用误差范围优化后的规则表 rule[7][7] */ /*输出值使用 13 个隶属函数,中心值由 UFF[7]指定 */ /*一般都是四个规则有效 */ Un[0] = rule[Pn - 1 + 3][Dn - 1 + 3]; Un[1] = rule[Pn + 3][Dn - 1 + 3]; Un[2] = rule[Pn - 1 + 3][Dn + 3]; Un[3] = rule[Pn + 3][Dn + 3]; if (PF[0] <= DF[0]) UF[0] = PF[0];

 else UF[0] = DF[0]; if (PF[1] <= DF[0]) UF[1] = PF[1]; else UF[1] = DF[0]; if (PF[0] <= DF[1]) UF[2] = PF[0]; else UF[2] = DF[1]; if (PF[1] <= DF[1]) UF[3] = PF[1]; else UF[3] = DF[1]; /*同隶属函数输出语言值求大 */

 if (Un[0] == Un[1]) { if (UF[0] > UF[1]) UF[1] = 0; else UF[0] = 0; } if (Un[0] == Un[2]) { if (UF[0] > UF[2]) UF[2] = 0; else UF[0] = 0; } if (Un[0] == Un[3]) { if (UF[0] > UF[3]) UF[3] = 0; else UF[0] = 0; } if (Un[1] == Un[2]) { if (UF[1] > UF[2]) UF[2] = 0; else UF[1] = 0; } if (Un[1] == Un[3]) { if (UF[1] > UF[3]) UF[3] = 0; else

 UF[1] = 0; } if (Un[2] == Un[3]) { if (UF[2] > UF[3]) UF[3] = 0; else UF[2] = 0; } /*重心法反模糊 */ /*Un[]原值为输出隶属函数标号,转换为隶属函数值 */ if (Un[0] >= 0) Un[0] = UFF[Un[0]]; else Un[0] = -UFF[-Un[0]]; if (Un[1] >= 0) Un[1] = UFF[Un[1]]; else Un[1] = -UFF[-Un[1]]; if (Un[2] >= 0) Un[2] = UFF[Un[2]]; else Un[2] = -UFF[-Un[2]]; if (Un[3] >= 0) Un[3] = UFF[Un[3]]; else Un[3] = -UFF[-Un[3]]; temp1 = UF[0] * Un[0] + UF[1] * Un[1] + UF[2] * Un[2] + UF[3] * Un[3]; temp2 = UF[0] + UF[1] + UF[2] + UF[3]; U = temp1 / temp2; return U; }

  实验二

 神经网络在角度随动系统中的应用 一、实验目的与意义 学习 Matlab 中建立 单神经元自适应神经网络控制器的方法;了解神经网络在角度随动系统中的应用。

 二、实验内容 1. 根据直流伺服电机的传递函数求出差分方程 2. 在 在 Matlab 中建立单神经元自适应控制器 3. K 得到较好的控制效果(方波、正弦波)

 *4. 编写单神经元自适应控制器的 C 程序, 编译并在角度随动系统中验证

 三、实验原理 1. 直流伺服电机传递函数

  2. 传递函数求差分方程步骤:

 以传递函数  为例:

 A. 使用 tf 函数建立传递函数

 sys=tf(1000,[1,50,2000])

 B. 设置采样时间

 ts = 0.001

 C. 使用 c2d 函数进行 Z 变换,其中

 dsys=c2d(sys,ts,"z")

 D. 交叉相乘得到

  E. 对 U(Z) 和 Y(Z) 进行

 z 逆变换得到差分方程

 3 、单神经元自适应控制算法 —— 方波 单神经元自适应控制的结构如下图所示。

  单神经元自适应控制器是通过对加权系数的调整来实现自适应、自组织功能,控制算法为

  如果权系数的调整按有监督的 Hebb 学习规则实现,在学习算法中加入监督项 z(k) ,则神经网络权值学习算法为

   为学习速率, K 为神经元的比例系数, K 0,  (0,1) 。

 K 值得选择非常重要。K 越大,则快速性越好,但超调量大,甚至可能使系统不稳定。当被控对象时延增大时,K 值必须减小,以保证系统稳定。K 值选择过小,会使系统快速性变差。

 被控对象为 y(k) (为 Matlab 中建立的直流伺服电机的差分方程),输入指令为一正弦信号:

 r(k) 2sin(4  k ts) ,采样时间 ts0.001s ,采用有监督的Hebb 学习规则实现权值的学习,初始权值取 W [w 1 w 2 w 3 ] [0.10.1 0.1] ,  0.1 ,K 0.01 。以此为条件在 Matlab 中建立单神经元自适应控制器。

 4. 单神经元自适应控制算法—— 正弦波 被控对象为 y(k) (为在 Matlab 中建立的直流伺服电机的差分方程),输入指令为一方波信号:

 r(k) 20sin(4  k ts) ,采样时间 ts0.001s ,采用有监督的 Hebb 学习规则实现权值的学习,初始权值取 W [w 1 w 2 w 3 ] [0.10.1 0.1] , 0.1 , K 0.01 。以此为条件在 Matlab 中建立单神经元自适应控制器。

 三、实验结果 1. 单神经元自适应控制算法 —— 方波

 源代码:

 %单神经元自适应控制器 clear all; close all;

 x=[0,0,0]"; %x1,x2,x3 的初始值 xite=0.1;

  %学习速率 K=0.01;

  %神经元比例系数 ts=0.001;

  %采样时间

 w1_1=0.10;%学习权值的初始值,w1_1 代表 w1(k-1)的值 w2_1=0.10; w3_1=0.10;

 e_1=0;%误差的初始值 e_2=0;

 y_1=0;y_2=0;%被控对象差分方程的输出值 u_1=0;u_2=0;% for k=1:1:1000 %循环迭代

  time(k)=k*ts;

 % r(k)=2*sin(4*pi*k*ts);%输入指令为一正弦信号

  r(k)=0.5*sign(sin(4*pi*k*ts));%输入指令为一方波信号

  y(k)=0.8464*y_1 + 32.01*u_1+0.1064*u_2;

 %y(k)=0.8464*y_1 +0.01*u_1+0.1064*u_2; %直流伺服电机的传递函数得到的差分方程

  e(k)=r(k)-y(k);%误差

 %有监督的 Hebb 学习规则实现权值的调整

 e(k)=r(k)-y(k);

 z(k)=e(k);

  x1(k)=e(k)-e_1;

  x2(k)=e(k);

  x3(k)=e(k)-2*e_1+e_2;

  w1(k)=w1_1+xite*0.07*z(k)*u_1*x1(k);

  w2(k)=w2_1+xite*0.005*z(k)*u_1*x2(k);

  w3(k)=w3_1+xite*0.02*z(k)*u_1*x3(k);

  w1p(k) = w1(k)/(abs(w1(k)) + abs(w2(k)) + abs(w3(k)));

  w2p(k) = w2(k)/(abs(w1(k)) + abs(w2(k)) + abs(w3(k)));

  w3p(k) = w3(k)/(abs(w1(k)) + abs(w2(k)) + abs(w3(k)));

 u(k)=u_1+K*(w1p(k)*x1(k)+w2p(k)*x2(k)+w3p(k)*x3(k));

  y_2=y_1;

  y_1=y(k);

  e_2=e_1;

  e_1=e(k);

  w1_1=w1(k);

  w2_1=w2(k);

  w3_1=w3(k);

  u_2=u_1;

  u_1=u(k);

  end figure(1); plot(time,r,"b",time,y,"r"); xlabel("time(s)");ylabel("Position tracking"); figure(2); plot(time,e,"r"); xlabel("time(s)");ylabel("error"); figure(3); plot(time,w1,"r"); xlabel("time(s)");ylabel("w1"); figure(4); plot(time,w2,"r"); xlabel("time(s)");ylabel("w2"); figure(5); plot(time,w3,"r"); xlabel("time(s)");ylabel("w3");

 运行结果:

  2. 单神经元自适应控制算法—— 正弦波 源代码:

 %单神经元自适应控制器 clear all; close all;

  x=[0,0,0]"; %x1,x2,x3 的初始值 xite=0.1;

  %学习速率 K=0.01;

  %神经元比例系数 ts=0.001;

  %采样时间

 w1_1=0.10;%学习权值的初始值,w1_1 代表 w1(k-1)的值 w2_1=0.10; w3_1=0.10;

 e_1=0;%误差的初始值 e_2=0;

 y_1=0;y_2=0;%被控对象差分方程的输出值 u_1=0;u_2=0;% for k=1:1:1000 %循环迭代

  time(k)=k*ts;

 % r(k)=2*sin(4*pi*k*ts);%输入指令为一正弦信号

  r(k) = 20*sin(4*pi*k*ts); ;%输入指令为一方波信号

  y(k)=0.8464*y_1 + 32.01*u_1+0.1064*u_2;

 %y(k)=0.8464*y_1 +0.01*u_1+0.1064*u_2; ;%直流伺服电机的传递函数得到的差分方程

  e(k)=r(k)-y(k);%误差

 %有监督的 Hebb 学习规则实现权值的调整

 e(k)=r(k)-y(k);

  z(k)=e(k);

  x1(k)=e(k)-e_1;

  x2(k)=e(k);

  x3(k)=e(k)-2*e_1+e_2;

  w1(k)=w1_1+xite*0.07*z(k)*u_1*x1(k);

  w2(k)=w2_1+xite*0.005*z(k)*u_1*x2(k);

  w3(k)=w3_1+xite*0.02*z(k)*u_1*x3(k);

 w1p(k) = w1(k)/(abs(w1(k)) + abs(w2(k)) + abs(w3(k)));

  w2p(k) = w2(k)/(abs(w1(k)) + abs(w2(k)) + abs(w3(k)));

  w3p(k) = w3(k)/(abs(w1(k)) + abs(w2(k)) + abs(w3(k)));

 u(k)=u_1+K*(w1p(k)*x1(k)+w2p(k)*x2(k)+w3p(k)*x3(k));

  y_2=y_1;

  y_1=y(k);

  e_2=e_1;

  e_1=e(k);

  w1_1=w1(k);

  w2_1=w2(k);

 w3_1=w3(k);

  u_2=u_1;

  u_1=u(k);

  end figure(1); plot(time,r,"b",time,y,"r"); xlabel("time(s)");ylabel("Position tracking"); figure(2); plot(time,e,"r"); xlabel("time(s)");ylabel("error"); figure(3); plot(time,w1,"r"); xlabel("time(s)");ylabel("w1"); figure(4); plot(time,w2,"r"); xlabel("time(s)");ylabel("w2"); figure(5); plot(time,w3,"r"); xlabel("time(s)");ylabel("w3");

 运行结果:

  4. 交叉编译步骤 Neural 源代码:

 #include <stdio.h> #include <math.h> #include <stdlib.h> #include "neural.h"

 /****************************************/ float neural_input_data[3] = {0, 0, 0}; //神经网络输入值初始值为零 float xite = 0.010;

  //学习率 float w1_1 = 0.10;

  //k-1 时刻的初始权值 float w2_1 = 0.10;

  //k-1 时刻的初始权值 float w3_1 = 0.10;

  //k-1 时刻的初始权值 float e_1 = 0;

  //e(k-1) float e_2 = 0;

  //e(k-2) float y_1 = 0, y_2 = 0; //y(k-1)和 y(k-2)初始值为零 float u_1 = 0, u_2 = 0; //u(k-1)和 u(k-2)初始值为零

 /*****************************************/ //单神经元自适应控制程序 //输入:

 control_sys_y -- 被控对象的角度 // control_sys_r -- 实际电机的角度 //输出:

 output --

 电机角度

 float neural_adaptive_control(float control_sys_y, float control_sys_r) {

 float control_sys_e = 0;

  //k 时刻的系统误差

 float control_sys_u = 0;

  //k 时刻的系统控制量 float w1=0;

 //k 时刻的神经元的第一个输入量的权值 float w2=0;

 //k 时刻的神经元的第二个输入量的权值 float w3=0;

 //k 时刻的神经元的第三个输入量的权值 float K =0.5;

 //单神经元自适应控制器的 K 增益 float z;

 control_sys_e = control_sys_r - control_sys_y;//k 时刻的误差

 printf("r is:%5.2f

  y is %5.2f\n", control_sys_r, control_sys_y);

 printf("e is: %7.2f\n", control_sys_e);

 z = control_sys_e; neural_input_data[1] = control_sys_e;

  //误差的位置量

 neural_input_data[0] = control_sys_e - e_1;

  //误差的速度量 neural_input_data[2] = control_sys_e - 2 * e_1 + e_2;

  //误差的加速度量

 printf("w1_1:

 %7.2f, xite: %7.2f, z: %7.2f, u_1: %7.2f, data0: %7.2f\n", w1_1, xite, z,u_1, neural_input_data[0]);

  w1 = w1_1 + xite*z*0.07*u_1*neural_input_data[0];

  w2 = w2_1 + xite*z*0.005*u_1*neural_input_data[1];

  w3 = w3_1 + xite*z*0.02*u_1*neural_input_data[2];

 if (w1 < WMIN || w1 > WMAX) { w1 = 0; } if (w2 < WMIN || w2 > WMAX) { w2 = 0; } if (w3 < WMIN || w3 > WMAX) { w3 = 0; }

 printf("w1: %7.2f, w2: %7.2f, w3: %7.2f\n", w1, w2, w3);

 float w1p = w1/(fabs(w1) + fabs(w2) + fabs(w3));

  float w2p = w2/(fabs(w1) + fabs(w2) + fabs(w3));

  float w3p = w3/(fabs(w1) + fabs(w2) + fabs(w3));

  control_sys_u = u_1 + K*(w1p*neural_input_data[0] + w2p*neural_input_data[1] + w3p*neural_input_data[2]);

 //Control law

 printf("u is %7.2f\n\n", control_sys_u);

 if (control_sys_u > 10000 || control_sys_u < -10000) { control_sys_u

 = 0; } float output;

 //output = 1.969*y_1 - 0.9731*y_2 + 0.01679*u_1 + 0.01663*u_2;

 //直流伺服电机的传递函数得到的差分方程 output = 1.014*y_1 - 0.01721*y_2+0.2322*u_1+0.8889*u_2;

 printf("y1:%7.2f

 y2:%7.2f

 u1:%7.2f

 u2:%7.2f\n", y_1, y_2, u_1, u_2); printf("output is %7.2f\n\n", output);

 //保存参数

 w1_1 = w1; w2_1 = w2; w3_1= w3;

  u_2 = u_1; u_1 = control_sys_u;

  e_2 = e_1; e_1 = control_sys_e;

  y_2 = y_1; y_1 = control_sys_y;

 return(output); }

 实验三

 遗传算法在角度随动系统中的应用 一、实验目的与意义 学习基于二进制编码遗传算法的 PID 整定方法;了解遗传算法在角度随动系统中的应用。

 二、实验内容 1. 了解数字 PID 控制原理; 2. 了解基于二进制编码遗传算法的 PID 整定的方法、步骤; 3. 在 在 Matlab 中建立基于二进制编码遗传算法的 PID 整定仿真程序; *4. 自己设计一种适应度函数,并进行仿真实验。

 *5. 在角度随动系统中验证得到的 PID 参数。

 三、实验原理 1. 数字 PID 控制 计算机控制是一种采样控制,它只能根据采样时刻的偏差值计算控制量。因

 此,连续 PID 控制算法不能直接使用,需要采用离散化方法。在计算机 PID 控制中,使用的是数字 PID 控制器。

 按模拟 PID 控制算法,以一系列的采样时刻点 kT 代表连续时间 t,以矩形法数值计算近似代替积分,以一阶后向差分近似代替微分,即

  可得离散 PID

 p

 位置式 PID 控制系统如下图所示。

 2. 基于遗传算法的 PID 整定原理 A.参数的确定及表示

 首先确定参数范围,该范围一般由用户给定,对其进行编码。选取二进制字

 串来表示每一个参数,并建立于参数间的关系。再把二进制串连接起来就组成一

 个长的二进制字串,该字串为遗传算法可以操作的对象。

 B.选取初始种群

 因为需要编程来实现各过程,所以采用计算机随机产生初始种群。针对二进

 制编码而言,先产生 0~1 之间均匀分布的随机数,然后规定产生的随机数 0~0.5

 之间带来表 0,0.5~1 之间代表 1。此外,考虑到计算的复杂程度来规定种群的大小。

 C.适配函数的确定

 一般的寻优方法在约束条件下可以求得满足条件的一组参数,在设计中是从

 该组参数中寻找一个最好的。衡量一个控制系统的指标有三个方面,即稳定性、

 准确性和快速性。而上升时间反映了系统的快速性,上升时间越短,控制进行得

 就越快,系统品质也就越好。

 如果单纯追求系统的动态特性,得到的参数很可能使控制信号过大,在实际

 应用中会因系统中固有的饱和特性而导致系统不稳定,为了防止控制能量过大,

 在实际应用中加入控制量。因此为了使控制效果更好,我们给出了控制量、误差

 和上升时间作为约束条件。因为适应函数同目标函数相关,所以目标函数确定后,

 直接将其作为适配函数进行参数寻优。最优的控制参数也就是在满足约束条件下

 使 f(x)最大时,x 所对应的控制器参数。

 D.遗传算法的操作

 首先利用适应度比例法进行复制。即通过适配函数求得适配值,进而求每个

 串对应的复制概率。复制概率与每代字串的个数的乘积为该串在下一代中应复制

 的个数。复制概率大的在下一代中将有较多的子孙,相反则会被淘汰。

 其次进行单点交叉,交叉概率为 P C 。从复制后的成员里以 P C 的概率选取字串组成

 匹配池,而后对匹配池的成员随机匹配,交叉的位置也是随机确定的。

 最后以概率 P m 进行变异。假如每代有 15 个字串,每个字串 12 位,则共有 15*12=180 个串位,期望的变异串位数为 180*0.01=2(位),即每代中有两个串位要由 1 变为 0 或由 0 变为 1。

 初始种群通过复制、交叉及变异得到了新一代种群,该代种群经解码后代入

 适配函数,观察是否满足结束条件,若不满足,则重复以上操作直到满足为止。

 结束条件由具体问题所定,只要各目标参数在规定范围内,则终止计算。

 以上操作过程可以通过下图来表示

 3. 遗传算法 MATLAB 仿真实验流程 A.在遗传算法的 MATLAB 仿真实验中应注意以下四个运行参数的设定与调节。

 (1) S:群体大小,即群体中所含个体的数量,一般取为 20-100.

 (2) G:遗传算法的终止进化代数,一般取为 100-500.

 (3) Pc:交叉概率,一般取为 0.4-0.99.

 (4) Pm:变异概率,一般取为 0.0001-0.1.

 B.遗传算法的 MATLAB 仿真程序设计

 在本次实验中,主要涉及 ga_pid.m 以及 ga_function.m 两个文件的内容填写。

 (1) 在 ga_pid.m 中对遗传算法的遗传代数、种群规模、编码长度以及 PID 初始值进行设置。

 (2) 对 PID 三个参数进行编解码操作。

 (3) 在理解最优指标设计以及选择与复制操作后,进行交叉步骤的编写。主

 要设计交叉概率与交叉操作两部分。

 (4) 进行变异步骤的编写。主要设计变异概率与变异操作两部分。

 (5) 在 ga_function.m 中填写采样时间以及电机传递函数。

 (6) 运行仿真程序,可以获得输出仿真图像与最优指标图像如下图所示。

  四、实验结果 ga_pid.m 源代码:

 %基于遗传算法的 PID 整定 clear all; close all; global yd y timef

 G=100;

 %遗传代数? Size=100;

  %种群大小? CodeL=8;

 %编码位数?

 MinX(1)=zeros(1);

  %kp 取值范围下限为 0 MaxX(1)=20*ones(1); %kp 取值范围上限为 20 MinX(2)=zeros(1);

  %ki 取值范围下限为 0 MaxX(2)=1.0*ones(1);%ki 取值范围上限为 1 MinX(3)=zeros(1);

  %kd 取值范围下限为 0 MaxX(3)=1.0*ones(1);%kd 取值范围下限为 1

 %************

 参数编解码 ***********

 E=round(rand(Size,3*CodeL));

 %Initial Code! 先由 rand 函数生成 30X30 的矩阵,然后对矩阵元素进行四舍五入,即初始种群

 BsJ=1;

 %所期望的最优指标为 0,即 J->0. BsJ 是 best J 的缩写

 for kg=1:1:G

 %100 代进化的主循环体

  time(kg)=kg;

 %time 变量为代数,从 1 到 100

 for s=1:1:Size

 %对每一代的种群中的 30 个样本(个体)进行循环

  m=E(s,:);

  %取 E30X30 矩阵的第 S 行,将其赋值给 m,m 的维度是 1X30,m 为当代种群中的某个个体

  y1=0;y2=0;y3=0;

  m1=m(1:1:CodeL);

 %P 值编解码%取 m(1X30)的前 10 位

  for i=1:1:CodeL

  y1=y1+m1(i)*2^(i-1);%将前 10 位二进制编码转化为 10 进制

  end

  Kpid(s,1)=(MaxX(1)-MinX(1))*y1/1023+MinX(1);%对kp的染色体编码进行解码

 m2=m(CodeL+1:1:2*CodeL);

 %I 值编解码%取 m(1X30)的中间 10 位

  for i=1:1:CodeL

  y2=y2+m2(i)*2^(i-1);

 %将中间 10 位二进制编码转化为 10 进制

  end

  Kpid(s,2)=(MaxX(2)-MinX(2))*y2/1023+MinX(2);

 %对ki的染色体编码进行解码

 m3=m(2*CodeL+1:1:end);

  %D 值编解码%取 m(1X30)的最后 10 位

  for i=1:1:CodeL

  y3=y3+m3(i)*2^(i-1);

 %将最后 10 位二进制编码转化为 10 进制

  end

  Kpid(s,3)=(MaxX(3)-MinX(3))*y3/1023+MinX(3);

 %即对kd的染色体编码进行解码

 %****** Step 1 : Evaluate BestJ ******

 Kpidi=Kpid(s,:);%取 Kpid 的第 s 行赋值给 Kpidi

 [Kpidi,BsJ]=ga_function(Kpidi,BsJ);%计算适应度

 BsJi(s)=BsJ;

 end

 [OderJi,IndexJi]=sort(BsJi);%对 BsJi 数组升序排序

  BestJ(kg)=OderJi(1);

  BJ=BestJ(kg);

  Ji=BsJi+1e-10;%避免分母为 0,即避免奇异

  fi=1./Ji;

 %Oderfi 为数值,Indexfi 为原序号,用 sort 函数对 fi 数组升序排序

 [Oderfi,Indexfi]=sort(fi);

  %Arranging fi small to bigger

 Bestfi=Oderfi(Size);

  % Let Bestfi=max(fi),即 Bestfi 为最大的值

  BestS=E(Indexfi(Size),:);

  % Let BestS=E(m), m is the Indexfi belong to max(fi)

 kg

  BJ

  BestS;

 %****** Step 2 : 选择与复制操作 Select and Reproduct Operation******

 fi_sum=sum(fi);%对 fi 数组求和

 fi_Size=(Oderfi/fi_sum)*Size;

  fi_S=floor(fi_Size);

  %Selecting Bigger fi value,向下取整,即 f_s为不大于且最接近 fi_size 的整数

  r=Size-sum(fi_S);

 Rest=fi_Size-fi_S;

  %残差

 [RestValue,Index]=sort(Rest);%对 Rest 升序排序

 for i=Size:-1:Size-r+1

  fi_S(Index(i))=fi_S(Index(i))+1;

  % Adding rest to equal Size

 end

 kk=1;

 for i=1:1:Size

  for j=1:1:fi_S(i)

 %Select and Reproduce

  TempE(kk,:)=E(Indexfi(i),:);

 kk=kk+1;

 %kk is used to reproduce

 end

 end

 E=TempE;

 %************ Step 3 : 交叉操作 Crossover Operation ************

  pc=0.63;%交叉概率建议 0.4~0.99

  n=ceil(20*rand);%n 为随机交叉点,使用 ceil 函数向离它最近的大整数取整

  for i=1:2:(Size-1)

  temp=rand;

  %设定交叉点

  if pc>temp

  %Crossover Condition,以 pc 的概率进行交叉操作

  for j=n:1:20

  %以下为交叉操作,在 n 到 20 之间的染色体基因位进行交叉

  TempE(i,j)=E(i+1,j);

  %?

  TempE(i+1,j)=E(i,j);

  %?

  end

  end

  end

  TempE(Size,:)=BestS;

  E=TempE;

 %************ Step 4:变异操作 Mutation Operation **************

 pm=0.002; %变异概率, 建议 0.0001~0.1

 for i=1:1:Size

  for j=1:1:3*CodeL

 temp=rand;

 if pm>temp

  %Mutation Condition,变异操作

  if TempE(i,j)==0

 TempE(i,j)=1;

  else

 TempE(i,j)=0;

  end

  end

  end

  end

  %Guarantee TempE(Size,:) belong to the best individual

  TempE(Size,:)=BestS;

  E=TempE; %******************************************************* end

 Bestfi BestS

 Kpidi Best_J=BestJ(G) figure(1); plot(time,BestJ,"r","linewidth",2); xlabel("Times");ylabel("Best J"); figure(2); plot(timef,yd,"r",timef,y,"b:","linewidth",2); xlabel("Time(s)");ylabel("yd,y"); legend("Ideal position signal","Position signal tracking");

 运行结果:

 Kpidi =

  0

  0

 0.2483

 Best_J =

  20.3517

 ga_function 源代码:

 function [Kpidi,BsJ]=ga_function(Kpidi,BsJ) global yd y timef

 ts=0.001;

  %采样时间 %sys=tf(400,[1,50,1]);

 %传递函数举例 sys=tf(209.06,[2.16*10^-8,0.006,1]);

 %电机传递函数

 dsys=c2d(sys,ts,"z"); [num,den]=tfdata(dsys,"v");

 u_1=0.0;u_2=0.0; y_1=0.0;y_2=0.0; x=[0,0,0]"; B=0; error_1=0; tu=1; s=0; P=150;

 for k=1:1:P

  timef(k)=k*ts;

  yd(k)=1.0;

 u(k)=Kpidi(1)*x(1)+Kpidi(2)*x(2)+Kpidi(3)*x(3);

 if u(k)>=10

  u(k)=10;

  end

  if u(k)<=-10

  u(k)=-10;

  end

  y(k)=-den(2)*y_1-den(3)*y_2+num(2)*u_1+num(3)*u_2;

  error(k)=yd(k)-y(k);

  %------------ Return of PID parameters -------------

  u_2=u_1;u_1=u(k);

  y_2=y_1;y_1=y(k);

 x(1)=error(k);

 % Calculating P

  x(2)=(error(k)-error_1)/ts;

  % Calculating D

  x(3)=x(3)+error(k)*ts;

 % Calculating I

 error_2=error_1;

  error_1=error(k);

  if s==0

  if y(k)>0.95&y(k)<1.05

  tu=timef(k);

  s=1;

  end

  end end

 for i=1:1:P

  Ji(i)=0.999*abs(error(i))+0.01*u(i)^2*0.1;

  B=B+Ji(i);

 if i>1

  erry(i)=y(i)-y(i-1);

  if erry(i)<0

  B=B+100*abs(erry(i));

  %误差惩罚

  end

  end end BsJ=B+0.2*tu*10;

 运行结果:

 >> ga_function(Kpidi,Best_J)

 ans =

  0

  0

 0.2317

 角度随动系统实验:

 #include <string.h> #include <stdio.h> #include "ga_pid.h" /*=========================================================

  PID Function

 The PID (比例、积分、微分) function is used in mainly

  control applications. PIDCalc performs one iteration of the PID

  algorithm.

 While the PID function works, main is just a dummy program showing

  a typical usage. ======================================================*/

  /*===================================================================

 Initialize PID Structure ======================================================*/

 void PIDInit (PID *pp) {

  memset ( pp, 0, sizeof(PID)); }

  //right_angle 期望值, left_angle 反馈值

 //left_angle --- 左边电机 被控电机角度 //right_angle --- 右边电机 理想电机角度 float ga_pid(PID * sPID, float left_angle, float right_angle) {

 //PIDInit ( &sPID );

  //

 Initialize Structure

  sPID->Proportion = 0.000015779;

 //

 PID 参数

  sPID->Derivative = -0.0013;

  sPID->Integral

  = 0.0192;

 float

 dError, Error; float u;

 Error = right_angle - left_angle;

 // 偏差

 printf("left_angle = %7.2f, right_angle = %7.2f, e = %7.2f\n", left_angle, right_angle, Error);

 sPID->SumError += Error;

 // 积分

  dError = sPID->LastError - sPID->PrevError;

 // 当前微分

  sPID->PrevError = sPID->LastError;

  sPID->LastError = Error;

 printf("err = %7.2f, sum = %7.2f, derr = %7.2f\n", Error, sPID->SumError, dError);

 u = sPID->Proportion * Error

  // 比例项

  +

  sPID->Integral * sPID->SumError

 // 积分项

  +

  sPID->Derivative * dError;

  // 微分项

  if (u > 10) u = 10;

  if (u < -10) u = -10;

  printf("u = %7.2f\n", u);

  return u; }

推荐访问:智能控制 实验 报告

上一条: Linux实验报告,, 下一条: 黑盒测试实验报告

版权所有:格斯文档网 2010-2024 未经授权禁止复制或建立镜像[格斯文档网]所有资源完全免费共享

Powered by 格斯文档网 © All Rights Reserved.。浙ICP备19042928号