PID控制器开发笔记之一:PID算法原理及基本实现
在自动控制中,PID及其衍生出来的算法是应用最广的算法之一。各个做自动控制的厂家基本都有会实现这一经典算法。我们在做项目的过程中,也时常会遇到类似的需求,所以就想实现这一算法以适用于更多的应用场景。
1、PID算法基本原理
PID算法是控制行业最经典、最简单、而又最能体现反馈控制思想的算法。对于一般的研发人员来说,设计和实现PID算法是完成自动控制系统的基本要求。这一算法虽然简单,但真正要实现好,却也需要下一定功夫。首先我们从PID算法最基本的原理开始分析和设计这一经典命题。
PID算法的执行流程是非常简单的,即利用反馈来检测偏差信号,并通过偏差信号来控制被控量。而控制器本身就是比例、积分、微分三个环节的加和。其功能框图如下:

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

其中Kp为比例带,TI为积分时间,TD为微分时间。PID控制的基本原理就是如此。
2、PID算法的离散化
上一节简单介绍了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)。
3、PID控制器的基本实现
完成了离散化后,我们就可以来实现它了。已经用离散化的数据公式表示出来后,再进型计算机编程已经不是问题了。接下来我们就使用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算法原理及基本实现的更多相关文章
- PID控制器开发笔记(转)
源: PID控制器开发笔记
- PID控制器开发笔记之七:微分先行PID控制器的实现
前面已经实现了各种的PID算法,然而在某些给定值频繁且大幅变化的场合,微分项常常会引起系统的振荡.为了适应这种给定值频繁变化的场合,人们设计了微分先行算法. 1.微分先行算法的思想 微分先行PID控制 ...
- PID控制器开发笔记之六:不完全微分PID控制器的实现
从PID控制的基本原理我们知道,微分信号的引入可改善系统的动态特性,但也存在一个问题,那就是容易引进高频干扰,在偏差扰动突变时尤其显出微分项的不足.为了解决这个问题人们引入低通滤波方式来解决这一问题. ...
- PID控制器开发笔记之五:变积分PID控制器的实现
在普通的PID控制算法中,由于积分系数Ki是常数,所以在整个控制过程中,积分增量是不变的.然而,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强.积分系数取大 ...
- PID控制器开发笔记之四:梯形积分PID控制器的实现
从微积分的基本原理看,积分的实现是在无限细分的情况下进行的矩形加和计算.但是在离散状态下,时间间隔已经足够大,矩形积分在某些时候显得精度要低了一些,于是梯形积分被提出来以提升积分精度. 1.梯形积分基 ...
- PID控制器开发笔记之三:抗积分饱和PID控制器的实现
积分作用的引入是为了消除系统的静差,提高控制精度.但是如果一个系统总是存在统一个方向的偏差,就可能无限累加而进而饱和,极大影响系统性能.抗积分饱和就是用以解决这一问题的方法之一.这一节我们就来实现抗积 ...
- PID控制器开发笔记之二:积分分离PID控制器的实现
前面的文章中,我们已经讲述了PID控制器的实现,包括位置型PID控制器和增量型PID控制器.但这个实现只是最基本的实现,并没有考虑任何的干扰情况.在本节及后续的一些章节,我们就来讨论一下经典PID控制 ...
- PID控制器开发笔记之十二:模糊PID控制器的实现
在现实控制中,被控系统并非是线性时不变的,往往需要动态调整PID的参数,而模糊控制正好能够满足这一需求,所以在接下来的这一节我们将讨论模糊PID控制器的相关问题.模糊PID控制器是将模糊算法与PID控 ...
- PID控制器开发笔记之九:基于前馈补偿的PID控制器的实现
对于一般的时滞系统来说,设定值的变动会产生较大的滞后才能反映在被控变量上,从而产生合理的调节.而前馈控制系统是根据扰动或给定值的变化按补偿原理来工作的控制系统,其特点是当扰动产生后,被控变量还未变化以 ...
随机推荐
- GCC编译器原理(一)------交叉编译器制作和GCC组件及命令
1.1 交叉编译器制作 默认安装的 GCC 编译系统所产生的代码适用于本机,即运行 GCC 的机器,但也可将 GCC 安装成能够生成其他的机器代码.安装一些必须的模块,就可产生多种目标机器代码,而且可 ...
- 对XML文件进行的修改
XmlDocument xml = new XmlDocument(); xml.Load(Way);//获取相对路径 var Exports = xml.GetElementsByTagName(& ...
- (13)UniquePathIII
一.问题描述 给定一个二维数组. 数组只有一个元素是1,是起点 数组只有一个元素是2,是终点 数组中的0是必须经过的地方 数组中的-1是障碍不可通过 从起始点到终点一共有多少路径? 二.思路 DFS ...
- mssql 创建函数简单实例
CREATE FUNCTION [dbo].[f_DailyIncome] ( @userId int, @date date ) ,) AS BEGIN ,); ) from Channel_Use ...
- java并发基础
一.创建线程 1.使用Executor:java.util.concurrent包中的执行器(Execute)为你管理Thread对象,从而简化并发编程. package thread; import ...
- 如何解压RPM包
有时我们需要RPM包中的某个文件,如何解压RPM包呢? RPM包括是使用cpio格式打包的,因此可以先转成cpio然后解压,如下所示: rpm2cpio xxx.rpm | cpio -div 解压了 ...
- TCC
严格遵守ACID的分布式事务我们称为刚性事务,而遵循BASE理论(基本可用:在故障出现时保证核心功能可用,软状态:允许中间状态出现,最终一致性:不要求分布式事务打成中时间点数据都是一致性的,但是保证达 ...
- ASP.NET MVC - XML节点查找
Jquery操作Xml Jquery1.2开始不再支持XPath表达式. <?xml version="1.0" encoding="utf-8" ?&g ...
- jQuery实现回车绑定Tab事件
有时候我们希望回车事件绑定的是键盘的Tab事件.我的第一思路就是切换事件的keyCode,比如键盘事件按下的keyCode如果是13,我们将keyCode改为9.但是在实际编程中却未能实现此效果.于是 ...
- android listView多层嵌套listView显示不全问题
最近在做项目,需要用到listVIew多层嵌套listVIew的需求,先发现已下两个处理办法比较好用 第一种: public class ListViewNesting extends ListVie ...