在自动控制中,PID及其衍生出来的算法是应用最广的算法之一。各个做自动控制的厂家基本都有会实现这一经典算法。我们在做项目的过程中,也时常会遇到类似的需求,所以就想实现这一算法以适用于更多的应用场景。

1PID算法基本原理

PID算法是控制行业最经典、最简单、而又最能体现反馈控制思想的算法。对于一般的研发人员来说,设计和实现PID算法是完成自动控制系统的基本要求。这一算法虽然简单,但真正要实现好,却也需要下一定功夫。首先我们从PID算法最基本的原理开始分析和设计这一经典命题。

PID算法的执行流程是非常简单的,即利用反馈来检测偏差信号,并通过偏差信号来控制被控量。而控制器本身就是比例、积分、微分三个环节的加和。其功能框图如下:

根据上图我们考虑在某个特定的时刻t,此时输入量为rin(t),输出量为rout(t),于是偏差就可计算为err(t)=rin(t)-rout(t)。于是PID的基本控制规律就可以表示为如下公式:

其中Kp为比例带,TI为积分时间,TD为微分时间。PID控制的基本原理就是如此。

2PID算法的离散化

上一节简单介绍了PID算法的基本原理,但要在计算机上实现就必须将其离散化,接下来我们就说一说PID算法的离散化问题。在实现离散化之前,我们需要对比例、积分、微分的特性做一个简单的说明。

比例就是用来对系统的偏差进行反应,所以只要存在偏差,比例就会起作用。积分主要是用来消除静差,所谓静差就是指系统稳定后输入输出之间依然存在的差值,而积分就是通过偏差的累计来抵消系统的静差。而微分则是对偏差的变化趋势做出反应,根据偏差的变化趋势实现超前调节,提高反应速度。

在实现离散前,我们假设系统采样周期为T。假设我们检查第K个采样周期,很显然系统进行第K次采样。此时的偏差可以表示为err(K)=rin(K)-rout(K),那么积分就可以表示为:err(K)+ err(K+1)+┈┈,而微分就可以表示为:(err(K)- err(K-1))/T。于是我们可以将第K次采样时,PID算法的离线形式表示为:

也可以记为:

这就是所谓的位置型PID算法的离散描述公式。我们知道还有一个增量型PID算法,那么接下来我们推到一下增量型PID算法的公式。上面的公式描述了第k个采样周期的结果,那么前一时刻也就是k-1个采样周期就不难表示为:

那么我们再来说第K个采样周期的增量,很显然就是U(k)-U(k-1)。于是我们用第k个采样周期公式减去第k-1个采样周期的公式,就得到了增量型PID算法的表示公式:

当然,增量型PID必须记得一点,就是在记住U(k)=U(k-1)+∆U(k)。

3PID控制器的基本实现

完成了离散化后,我们就可以来实现它了。已经用离散化的数据公式表示出来后,再进型计算机编程已经不是问题了。接下来我们就使用C语言分别针对位置型公式和增量型公式来具体实现。

1)位置型PID的简单实现

位置型PID的实现就是以前面的位置型公式为基础。这一节我们只是完成最简单的实现,也就是将前面的离散位置型PID公式的计算机语言化。

首先定义PID对象的结构体:

 /*定义结构体和公用体*/

 typedef struct

 {

   float setpoint;       //设定值

   float proportiongain;     //比例系数

   float integralgain;      //积分系数

   float derivativegain;    //微分系数

   float lasterror;     //前一拍偏差

   float result; //输出值

   float integral;//积分值

 }PID;

接下来实现PID控制器:

 void PIDRegulation(PID *vPID, float processValue)

 {

   float thisError;

   thisError=vPID->setpoint-processValue;

   vPID->integral+=thisError;

   vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);

   vPID->lasterror=thisError;

 }

这就实现了一个最简单的位置型PID控制器,当然没有考虑任何干扰条件,仅仅只是对数学公式的计算机语言化。

2)增量型PID的简单实现

增量型PID的实现就是以前面的增量型公式为基础。这一节我们只是完成最简单的实现,也就是将前面的离散增量型PID公式的计算机语言化。

首先定义PID对象的结构体:

 /*定义结构体和公用体*/

 typedef struct

 {

   float setpoint;       //设定值

   float proportiongain;     //比例系数

   float integralgain;      //积分系数

   float derivativegain;    //微分系数

   float lasterror;     //前一拍偏差

   float preerror;     //前两拍偏差

   float deadband;     //死区

   float result; //输出值

 }PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)

{

  float thisError;

  float increment;

  float pError,dError,iError;

  thisError=vPID->setpoint-processValue; //得到偏差值

  pError=thisError-vPID->lasterror;

  iError=thisError;

  dError=thisError-*(vPID->lasterror)+vPID->preerror;

  increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量计算

  vPID->preerror=vPID->lasterror;  //存放偏差用于下次运算

  vPID->lasterror=thisError;

  vPID->result+=increment;

}

这就实现了一个最简单的增量型PID控制器,也没有考虑任何的干扰条件,仅仅只是对数学公式的计算机语言化。

4、基本特点

前面讲述并且实现了PID控制器,包括位置型PID控制器和增量型PID控制器。界限来我们对这两种类型的控制器的特点作一个简单的描述。

位置型PID控制器的基本特点:

  • 位置型PID控制的输出与整个过去的状态有关,用到了偏差的累加值,容易产生累积偏差。
  • 位置型PID适用于执行机构不带积分部件的对象。
  • 位置型的输出直接对应对象的输出,对系统的影响比较大。

增量型PID控制器的基本特点:

  • 增量型PID算法不需要做累加,控制量增量的确定仅与最近几次偏差值有关,计算偏差的影响较小。
  • 增量型PID算法得出的是控制量的增量,对系统的影响相对较小。
  • 采用增量型PID算法易于实现手动到自动的无扰动切换。

 欢迎关注:

PID控制器开发笔记之一:PID算法原理及基本实现的更多相关文章

  1. PID控制器开发笔记(转)

    源: PID控制器开发笔记

  2. PID控制器开发笔记之七:微分先行PID控制器的实现

    前面已经实现了各种的PID算法,然而在某些给定值频繁且大幅变化的场合,微分项常常会引起系统的振荡.为了适应这种给定值频繁变化的场合,人们设计了微分先行算法. 1.微分先行算法的思想 微分先行PID控制 ...

  3. PID控制器开发笔记之六:不完全微分PID控制器的实现

    从PID控制的基本原理我们知道,微分信号的引入可改善系统的动态特性,但也存在一个问题,那就是容易引进高频干扰,在偏差扰动突变时尤其显出微分项的不足.为了解决这个问题人们引入低通滤波方式来解决这一问题. ...

  4. PID控制器开发笔记之五:变积分PID控制器的实现

    在普通的PID控制算法中,由于积分系数Ki是常数,所以在整个控制过程中,积分增量是不变的.然而,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强.积分系数取大 ...

  5. PID控制器开发笔记之四:梯形积分PID控制器的实现

    从微积分的基本原理看,积分的实现是在无限细分的情况下进行的矩形加和计算.但是在离散状态下,时间间隔已经足够大,矩形积分在某些时候显得精度要低了一些,于是梯形积分被提出来以提升积分精度. 1.梯形积分基 ...

  6. PID控制器开发笔记之三:抗积分饱和PID控制器的实现

    积分作用的引入是为了消除系统的静差,提高控制精度.但是如果一个系统总是存在统一个方向的偏差,就可能无限累加而进而饱和,极大影响系统性能.抗积分饱和就是用以解决这一问题的方法之一.这一节我们就来实现抗积 ...

  7. PID控制器开发笔记之二:积分分离PID控制器的实现

    前面的文章中,我们已经讲述了PID控制器的实现,包括位置型PID控制器和增量型PID控制器.但这个实现只是最基本的实现,并没有考虑任何的干扰情况.在本节及后续的一些章节,我们就来讨论一下经典PID控制 ...

  8. PID控制器开发笔记之十二:模糊PID控制器的实现

    在现实控制中,被控系统并非是线性时不变的,往往需要动态调整PID的参数,而模糊控制正好能够满足这一需求,所以在接下来的这一节我们将讨论模糊PID控制器的相关问题.模糊PID控制器是将模糊算法与PID控 ...

  9. PID控制器开发笔记之九:基于前馈补偿的PID控制器的实现

    对于一般的时滞系统来说,设定值的变动会产生较大的滞后才能反映在被控变量上,从而产生合理的调节.而前馈控制系统是根据扰动或给定值的变化按补偿原理来工作的控制系统,其特点是当扰动产生后,被控变量还未变化以 ...

随机推荐

  1. 使用aspectJ实现Spring AOP的两种方式

    方式一:基于aspectJ的XML配置 方式二:基于aspectJ的注解方式 基于aspectJ的XML配置 1)       引入相关jar包 2)       创建Spring核心配置文件,必须导 ...

  2. 【全文转载】Gradle、Maven项目相互转换

    Doublemine 首页 标签 归档 关于 搜索   Gradle.Maven项目相互转换  发表于 2017-08-21 |  更新于: 2018-03-18 |  阅读次数: 920  字数统计 ...

  3. Linux centos 防火墙篇

    防火墙的关闭 service iptables stop 永久关闭 chkconfug iptables off 查看状态 service iptables status

  4. 【bzoj 3110】[Zjoi2013]K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  5. html页面设置<span>的高度和宽度

    <span>标签属于行内元素(inline),所以无法设置高度和宽度:如果需要改变其宽高,就需要将其转变为块体元素(block)或行内块体元素(inle-block): 1 span{di ...

  6. 嵌入式开发-迅为4418开发板Android4.4.4实现ble功能

    ①.如果是迅为4418开发板:在4418/android/device/nexell/drone2/device.mk中添加: frameworks/native/data/etc/android.h ...

  7. 源码解读-文件上传angularFileUpload1

    angular-file-upload 1.文件上传模块的引入就不赘述,简单准备 2.初始化组件并绑定change事件 3.监听用户选择文件FileItem(change事件),push进文件数组qu ...

  8. Python7 - 面向对象编程进阶

    本节内容: 面向对象高级语法部分 经典式 VS 新式类 静态方法,类方法,属性方法 类的特殊方法 反射 异常处理 Socket开发基础 面向对象高级语法部分 经典类 VS 新式类 先看一串代码: cl ...

  9. 批量清除react中的计时器小组件

    在Timers的父组件被卸载时,批量清除各个计时器.

  10. 安卓虚拟机与Hyper-V冲突

    经过各种经验,哪个安卓虚拟机跟Hyper-V都存在着冲突. 解决方案一 程序中卸载Hyper-V,之后还要再配置太麻烦. 解决方案二 1.关掉Hyper-V的启动项,命令如下. bcdedit /se ...