PID算法作为工业或日常生活中常用的控制算法,想必大家都不陌生,依靠误差反馈来消除误差,关于PID的原理部分相比看这篇博客的同学应该都十分清楚,有不清楚的同学可以百度或知网搜索。PID算法的应用程度很广但都逃不开一个步骤,也是相对而言最最令人头痛的一个过程——调参,具体来说就是调Kp、Ki、Kd。

   以往的方法都是手动调试,根据调参经验,先调KP,再调KD··········,繁琐的步骤让人头晕,费

  那么PID参数的调试是否有一种相对来说简单的调试方式呢?

————————————————————分割线————————————————————

  前面废话这么多为了凑字数,看官老爷莫着急,嘿嘿!我们步入正题,跟着小李准备发车!!!

  Step1:首先你要“学”会一个入门级的智能优化算法——粒子群算法

  粒子群优化算法(PSO)是一种进化计算技术(evolutionary computation),1995 年由Eberhart 博士和kennedy 博士提出,源于对鸟群捕食的行为研究 。该算法最初是受到飞鸟集群活动的规律性启发,进而利用群体智能建立的一个简化模型。粒子群算法在对动物集群活动行为观察基础上,利用群体中的个体对信息的共享使整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得最优解。

等等等等详细介绍我就不多说了,看官老爷可以移步至如下链接,超详细的解说。

引用于——https://cloud.tencent.com/developer/article/1424756

  好接下来我们来讲,如何将PSO与PID参数整定联系在一起。

  PSO可以用来求一个函数的最大最小值,那么我们在调参时,示波器的波形上就会明显的看出自身系统的状态运行曲线和期望到达的状态,并且你的理想曲线往往是这样的:

粒子群算法改进随机森林Python代码 粒子群算法调参_算法

  没有超调量、运行平稳。

  但无论参数怎么好,都是根据反馈的误差来消除误差,那么对于任一你想调的系统,在系统达到期望状态前,都会有一个误差

粒子群算法改进随机森林Python代码 粒子群算法调参_算法_02

,显然对每个系统,在MATLAB的仿真中,最终都会得到某一时间段系统的一个误差函数

粒子群算法改进随机森林Python代码 粒子群算法调参_matlab_03

,我们想要得到的期望曲线往往是

粒子群算法改进随机森林Python代码 粒子群算法调参_matlab_03

往往也是较小的或者说最小的,那么这也就对应了用粒子群算法来求解函数最小值。

     即我们需要在仿真中建立一个目标函数,这个函数关系到你的控制效果。那怎么建立一个目标函数呢。一般我们采取ITAE准则,英文缩写ITAE。准则的表达式为:

                                                                  

粒子群算法改进随机森林Python代码 粒子群算法调参_算法_05

按此准则设计的控制系统,瞬态响应的振荡性小,且对参数具有良好的选择性。缺点是用分析法计算很困难。

采用误差积分指标作为系统整定的性能指标时,系统的整定就归结为计算控制系统中的待定参数,使上述各类积分数值最小

———————————————————分割线—————————————————————

如何在simulink中建立呢?看官老爷看下图:

粒子群算法改进随机森林Python代码 粒子群算法调参_性能优化_06

  想必熟悉simulink的看官老爷看的很明白吧,仿真时将时间分为一个很多段的小段,用来模拟连续,这样就得到了近似解,而且我们知道

粒子群算法改进随机森林Python代码 粒子群算法调参_matlab_07

越小,越近似。

   目标函数的仿真做好了,目标函数的.m文件怎么做?

function z = ayy(kp,ki,kd)
%赋值运行且返回适应度
%assigni函数的第一个参数填base就行
%第二、三个参数即仿真和.m文件对应即可
assignin('base','kp',kp);%赋值给kp
assignin('base','ki',ki);%赋值给kp
assignin('base','kd',kd);%赋值给kp
try  %% simulink仿真异常,返回一个极大值
    y_out=sim('plane_pid2.slx',[0,20]);    %使用命令行运行控制系统模型
    z=simout1.data(end,1);                  %得到目标函数值
catch
    z=1e6;
end

目标函数ok了,下面我对一个很简单的例子的参数进行整定

粒子群算法改进随机森林Python代码 粒子群算法调参_matlab_08

 另附PSO代码

close all;
clear;
clc;
%惯性因子
wmax=0.9;
wmin=0.4;
%自我、种群学习因子
c1=0.8;
c2=0.5;
%迭代次数、种群大小、维度
gens=50;
np=80;
nd=3;
%范围
kpmax=100;
kpmin=0;
kimax=100;
kimin=0;
kdmax=100;
kdmin=0;
%速度
vmin=-2;
vmax=2;
v=ones(np,nd);
%初始化种群
x=ones(np,nd);
xp_best=1e2*ones(np,nd);
xg_best=[1e2 1e2 1e2];
%种群、全局最优
zp_best=1e6*ones(np,1);
zg_best=1e6;
zz=ones(1,gens);
K_p=ones(1,gens);
K_i=ones(1,gens);
K_d=ones(1,gens);
for i=1:np
    %初始化粒子位置
    x(i,1)=kpmin+(kpmax-kpmin)*rand;
    x(i,2)=kimin+(kimax-kimin)*rand;
    x(i,3)=kdmin+(kdmax-kdmin)*rand;
    %初始化粒子速度
    v(i,:)=vmin+(0.5*rands(1,nd)+0.5)*(vmax-vmin);
    z=pso_pid(x(i,1),x(i,2),x(i,3));
    %更新个体最优
    if z<zp_best(i)
       zp_best(i)=z;
       xp_best(i,:)=x(i,:);
    end
    %更新全局最优
    if z<zg_best
       zg_best=z;
       xg_best=x(i,:);
    end    
end
%开始迭代
iter=0;
for k=1:gens
    for i=1:np
      v(i,:)=wmax*v(i,:)+c1*rand*(xp_best(i,:)-x(i,:))+c2*rand*(xg_best-x(i,:));
      %速度限幅
      for j=1:nd
          if v(i,j)>vmax
              v(i,j)=vmax;
          end
          if v(i,j)<vmin
              v(i,j)=vmin;
          end
      end
      x(i,:)=x(i,:)+v(i,:);
      %位置限幅
      for j=1:nd
          if x(i,1)>kpmax
              x(i,1)=kpmax;
          end
          if x(i,1)<kpmin
              x(i,1)=kpmin;
          end
          
          if x(i,2)>kimax
              x(i,2)=kimax;
          end
          if x(i,2)<kimin
              x(i,2)=kimin;
          end
          
          if x(i,3)>kdmax
              x(i,3)=kdmax;
          end
          if x(i,3)<kdmin
              x(i,3)=kdmin;
          end  
      end
      z=pso_pid(x(i,1),x(i,2),x(i,3));
      %更新个体最优
      if z<zp_best(i)
          zp_best(i)=z;
          xp_best(i,:)=x(i,:);
      end
      %更新全局最优
      if z<zg_best
          zg_best=z;
          xg_best=x(i,:);
      end
    end 
    iter = iter+1;                % 迭代次数更新
    zz(1,iter) = zg_best;         % 为绘图做准备
    K_p(1,iter) = xg_best(1,1);
    K_i(1,iter) = xg_best(1,2);
    K_d(1,iter) = xg_best(1,3);
end
figure     % 绘制性能指标ITAE的变化曲线
plot(zz,'LineWidth',2)
title('最优个体适应值','fontsize',18);
xlabel('迭代次数','fontsize',18);ylabel('适应值','fontsize',18);
set(gca,'Fontsize',18);

figure      % 绘制PID控制器参数变化曲线
plot(K_p)
hold on
plot(K_i,'k','LineWidth',3)
plot(K_d,'--r')
title('Kp、Ki、Kd 优化曲线','fontsize',18);
xlabel('迭代次数','fontsize',18);ylabel('参数值','fontsize',18);
set(gca,'Fontsize',18);
legend('Kp','Ki','Kd');
zg_best
xg_best

得到如下结果

粒子群算法改进随机森林Python代码 粒子群算法调参_matlab_09

粒子群算法改进随机森林Python代码 粒子群算法调参_粒子群算法改进随机森林Python代码_10

最终的效果,波形图:

粒子群算法改进随机森林Python代码 粒子群算法调参_算法_11

但他跑得很快,曲线还算,,一般吧,但速度真的很快,而且可能会得到全局最优解哦,全局最优解!!!

王维诗里的全局最优解!一般人工调试难以达到这种程度,所以用智能算法整定参数,不香么!!

最后声明:

            代码可直接复制使用,小白也可以!!!

            只要找到想要整定的参数,修改下你相应地仿真!!

            让电脑自己跑吧!!!