PID详解(理论+应用)

~~~~    最近研究智能小车这个方面,发现这个课题貌似已经被研究透了,仅仅在CSDN中就能搜索到无数的相关博文。但我查看一些博文的时候,隐隐感觉出作者君似乎也仅仅处于似懂非懂的阶段,又或者他用的是春秋笔法所以模糊了一些关键点?为了记录下自己看过的博文并且自我总结一些相关方面,在此提笔记录一下自己的研究过程。

理论基础:

PID是什么?

工业过程中广泛采用的三作用控制器,也称PID控制器(PID controller).

P: (Proportional)比例;
I : (Integral)积分;
D:(Derivative)微分;

时域输出方程:

u(t)=KP∗e(t)+KI∗∫e(t)+KD∗de(t)dtu(t)=K_P*e(t) +K_I*\int e(t)+K_D*\frac{de(t)}{dt}u(t)=KP​∗e(t)+KI​∗∫e(t)+KD​∗dtde(t)​

编程中我们更多用到的是这个方程的数字式:

U[k]=KP∗err[k]+KI∗∑err[k]+KD∗(err[k]−err[k−1])U[k]=K_P*err[k]+K_I*\sum err[k]+K_D*(err[k]-err[k-1])U[k]=KP​∗err[k]+KI​∗∑err[k]+KD​∗(err[k]−err[k−1])

由基本的自控知识可得到传递函数:

Gc(s)=U(s)E(s)=KP+KIs+KD∗sGc(s)=\frac{U(s)}{E(s)}=K_P+\frac{K_I}{s}+K_D*sGc(s)=E(s)U(s)​=KP​+sKI​​+KD​∗s

其中可调的三个参数就是:

KPK_PKP​:比例增益 Proportional gain
KIK_IKI​ :积分增益 Integral gain
KDK_DKD​:微分增益 Derivative gain

  • 但很多情况下,我们不需要使用到全部的三种手段,经过排列组合就出现了P、PI、PD这种不完全版的控制器。

在工业中,更多采用传统的PID控制器:

u(t)=100P(e(t)+1T1∫e(t)dt+TDde(t)dt)~~~~~~~u(t)=\frac{100}{P}(e(t)+\frac{1}{T_1}\int e(t)dt+T_D\frac{de(t)}{dt})       u(t)=P100​(e(t)+T1​1​∫e(t)dt+TD​dtde(t)​)

其中:
P : 比例带(%)
T1T_1T1​ :积分时间(s)
TDT_DTD​:微分时间(s/min)

对比之前的公式,我们得到:

KP=100PK_P = \frac{100}{P}KP​=P100​
KI=100P∗1T1K_I = \frac{100}{P}*\frac{1}{T_1}KI​=P100​∗T1​1​
KD=100P∗TDK_D=\frac{100}{P}*T_DKD​=P100​∗TD​

~~~~    在工业的高精度要求与复杂处理环境下,我们对微积分时间的关注度更高。但在平时的小设计没有必要采用这一套体系。

~~~~    在实际应用中,反馈测量信号往往混杂高频噪声,微分处理则会放大这些噪声,所以这里我们需要滤波来去除高频噪声。

~~~~    所以这里我们的微分项在实际实现是采用:

Gd(s)=KDsτds+1~~~~~G_d(s)=\frac{K_Ds}{\tau_d s+1}     Gd​(s)=τd​s+1KD​s​

其中:
τd\tau_dτd​ 作为滤波时间常数,远远小于过程本身的时间,可以忽略。

位置式PID和增量式PID

位置式PID与增量式PID区别浅析:参考博文原址

位置式PID:

还是这个公式:

其中误差

P:e(k)=设定值−当前状态值P: e(k) = 设定值 - 当前状态值P:e(k)=设定值−当前状态值
I:∑e(i)=误差的累加I : \sum e(i) = 误差的累加I:∑e(i)=误差的累加
D:e(k)−e(k−1)=本次误差−上一次的误差D: e(k) - e(k-1) = 本次误差 - 上一次的误差D:e(k)−e(k−1)=本次误差−上一次的误差

位置式PID是对:当前系统的实际位置与你预期位置的偏差 进行PID控制。

通常PD控制器就可以满足位置式PID:

因为有误差积分 ∑e(i),一直累加,也就是当前的输出u(k)与过去的所有状态都有关系,用到了误差的累加值;(误差e会有误差累加),输出的u(k)对应的是执行机构的实际位置,,一旦控制输出出错(控制对象的当前的状态值出现问题 ),u(k)的大幅变化会引起系统的大幅变化
并且位置式PID在积分项达到饱和时,误差仍然会在积分作用下继续累积,一旦误差开始反向变化,系统需要一定时间从饱和区退出,所以在u(k)达到最大和最小时,要停止积分作用,并且要有积分限幅和输出限幅。
所以在使用位置式PID时,一般我们直接使用PD控制
而位置式 PID 适用于执行机构不带积分部件的对象,如舵机和平衡小车的直立和温控系统的控制

typedef struct PID
{ float P,I,D,limit;
}PID;typedef struct Error
{float Current_Error;//当前误差float Last_Error;//上一次误差float Previous_Error;//上上次误差
}Error;/*! *  @brief      位置式PID*  @since      v1.0*  *sptr :误差参数*  *pid:  PID参数*  NowPlace:当前位置*  Point:   预期位置  */// 位置式PID控制
float PID_Realize(Error *sptr,PID *pid, int32 NowPlace, float Point)
{int32 iError,  // 当前误差Realize;   //实际输出    iError = Point - NowPlace; // 计算当前误差sptr->Current_Error += pid->I * iError;    // 误差积分sptr->Current_Error = sptr->Current_Error > pid->limit?pid->limit:sptr->Current_Error;//积分限幅sptr->Current_Error = sptr->Current_Error <-pid->limit?-pid->limit:sptr->Current_Error;Realize = pid->P * iError       //比例P+ sptr->Current_Error   //积分I+ pid->D * (iError - sptr->Last_Error);  //微分Dsptr->Last_Error = iError;           // 更新上次误差return Realize;    // 返回实际值
}
增量式PID

Δu[k]=u[k]−u[k−1]\Delta u[k] = u[k]-u[k-1]Δu[k]=u[k]−u[k−1]
=KP[e[k]−e[k−1]]+KIe(k)+KD[e[k]−2e[k−1]+e[k−2]]=K_P[e[k]-e[k-1]]+K_Ie(k)+K_D[e[k]-2e[k-1]+e[k-2]]=KP​[e[k]−e[k−1]]+KI​e(k)+KD​[e[k]−2e[k−1]+e[k−2]]

P:e(k)−e(k−1)=P: e(k)-e(k-1)=P:e(k)−e(k−1)= 本次误差 - 上一次的误差

I:e(i)=I : e(i) =I:e(i)= 误差

D:e[k]−2e[k−1]+e[k−2]¥D: e[k]-2e[k-1]+e[k-2]¥D:e[k]−2e[k−1]+e[k−2]¥ = 本次误差 - 2*上一次的误差+上上次误差

增量式PID的控制量Δu(k)\Delta u(k)Δu(k)是最近几次误差的增量,而不是实际的误差,没有误差累加
所以增量式PID不需要累加,只需要最近的相邻三次误差就可以通过加权获得比较好的控制效果,而系统出问题时这种PID不会严重影响系统工作。

总结:增量型 PID,是对位置型 PID 取增量,这时控制器输出的是相邻两次采样时刻所计算的位置值之差,得到的结果是增量,即在上一次的控制量的基础上需要增加(负值意味减少)控制量。

typedef struct PID
{ float P,I,D,limit;
}PID;
typedef struct Error
{float Current_Error;//当前误差float Last_Error;//上一次误差float Previous_Error;//上上次误差
}Error;/*! *  @brief      增量式PID*  @since      v1.0*  *sptr :误差参数*  *pid:  PID参数*  NowPlace:实际值*  Point:   期望值*/
// 增量式PID电机控制
int32 PID_Increase(Error *sptr, PID *pid, int32 NowPlace, int32 Point)
{int32 iError,  //当前误差Increase; //最后得出的实际增量iError = Point - NowPlace;  // 计算当前误差Increase =  pid->P * (iError - sptr->Last_Error)   //比例P+ pid->I * iError      //积分I+ pid->D * (iError - 2 * sptr->Last_Error + sptr->Previous_Error);  //微分Dsptr->Previous_Error = sptr->Last_Error; // 更新前次误差sptr->Last_Error = iError;         // 更新上次误差return Increase;   // 返回增量
}

辨析:

增量式与位置式区别:
1。增量式算法不需要做累加,控制量增量的确定仅与最近几次偏差采样值有关,计算误差对控制 量计算的影响较小。而位置式算法要用到过去偏差的累加值,容易产生较大的累加误差。
2。增量式算法得出的是控制量的增量,例如在阀门控制中,只输出阀门开度的变化部分,误动作 影响小,必要时还可通过逻辑判断限制或禁止本次输出,不会严重影响系统的工作。 而位置式的输出直接对应对象的输出,因此对系统影响较大。
3。增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。
4。在进行PID控制时,位置式PID需要有积分限幅和输出限幅,而增量式PID只需输出限幅
位置式PID优缺点:
优点:
①位置式PID是一种非递推式算法,可直接控制执行机构(如平衡小车),u(k)的值和执行机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以很好应用
缺点:
①每次输出均与过去的状态有关,计算时要对e(k)进行累加,运算工作量大。
增量式PID优缺点:
优点:
①误动作时影响小,必要时可用逻辑判断的方法去掉出错数据。
②手动/自动切换时冲击小,便于实现无扰动切换。当计算机故障时,仍能保持原值。
③算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关。
缺点:
①积分截断效应大,有稳态误差;
②溢出的影响大。有的被控对象用增量式则不太好;

下面理论分析PID的作用

Gc(s)=KP+KIs+KDs=KDs2+KPs+KIs=KD(S2+as+b)s=KD(s+z1)(s+z2)sG_c(s)=K_P+ \frac{K_I}{s}+K_Ds =\frac{K_Ds^2+K_Ps+K_I}{s}\\ =\frac{K_D(S^2+as+b)}{s}=\frac{K_D(s+z_1)(s+z_2)}{s}Gc​(s)=KP​+sKI​​+KD​s=sKD​s2+KP​s+KI​​=sKD​(S2+as+b)​=sKD​(s+z1​)(s+z2​)​

根据数学知识可得:
a=KPKD,b=KIKDa=\frac{K_P}{K_D},b=\frac{K_I}{K_D}a=KD​KP​​,b=KD​KI​​

所以我们可以得知,引用PID会为系统带来一个纯积分环节和两个零点。
原点处的极点可以提高系统的型数,改善稳态性能
两个零点理论上可以在任何位于左半S平面的任意位置

PID整定方法

对于有数学模型的系统,自然可以仿真完成整定,但对于一个实际系统,我们可以通过实验来标定。

1.手动标定

1.系统闭环,采取P控制器,设置Ki = 0, Kd = 0, Kp取一个较小的数,满足系统稳定即可
2.逐渐增加Kp,每次改变控制器参数,都要观察一段时间系统输出量、控制量,直到闭环系统达到临界稳定,输出量产生等幅度、等周期的持续震荡记录此时的Kp
3.将Kp减少一半,继续采用P控制器,逐步减少Kp,直到获得4:1衰减震荡
4.固定Kp,设置Kd = 0,采用PI控制器,将Ki从0开始逐渐增大,每次改变控制器参数,都要观察一段时间系统输出、控制量,直到闭环系统对扰动的抑制 和/或 对设定值的阶跃响应 达到最佳。
5.固定Kp和Ki,采用PID控制器,将Kd从0开始逐渐增大,每次改变控制器参数观察系统输出、控制量,直到闭环系统对扰动的抑制 和/或 对设定值的阶跃相应达到最佳
6.采用PID控制器,在已获得的Kp,Ki,Kd附近,进一步精调控制器参数,直到得到最满意的系统响应

对于PID的三个参数,对系统阶跃相应的影响:

PID增益 百分比超调量 调整时间 稳态误差
增大Kp 增大 影响很小 减小
增大Ki 增大 增大 为0
增大Kd 减小 减小 没有影响

上表仅为参考,现实中情况错综复杂,一定要积极变通。

2.临界比例带法:Z-N法(Zigler-Nichols)

闭环:

这是一套实验得出的方法,目标是使得闭环系统得到4:1衰减振荡的阶跃相应,闭环相应速度较快、振荡适中、扰动抑制能力强。

1.设置Ki = 0, Kd = 0, 采用纯P控制器
2.增大Kp,观测输入、输出,直到系统达到临界稳定,产生幅值和周期不变的持续振荡
3.记录Kp,成为临界增益Ku;振荡周期称为临界振荡周期Tu
4.选定控制器类型,按闭环Z-N整定规则计算PID各个增益

整定规则:

控制器类型 Kp Ki Kd
P Gc(s)=Kp 0.5Ku - -
PI Gc(s)=Kp+Ki/s 0.45Ku 0.54Ku/tu -
PID Gc(s)=Kp+Ki/s+Kds 0.6Ku 1.2Ku/Tu 0.6KuTu/8

其实还有一种开环Z-N手段,这里不再赘述

3.经验法:

1.P控制器:Ki = 0, Kd = 0,选择初始Kp, 观测扰动曲线或设定值响应曲线,增大或减小Kp,观测曲线是否有所改善,若改善,则继续按此方向整定Kp,反之,反向整定Kp,直到得到较好的曲线
2.Kp减小0.8倍,从0开始增大Ki,观测曲线,得到较好的响应曲线
3.固定Ki,精调Kp,增大或减小Kp,直到得到较好的响应曲线
4.同里,精调Ki
5.由此得到较好的Kp、Ki
6.若增加微分,则采用类似方法,从0开始整定Kp,并进一步精调Kp、Ki、Kd

也可按照以下初始试凑范围设定PID控制器初始值,然后精调

系统类型 P(%) Ti(s) Td(s)
温度 20-60 180-600 30-180
流量 40-100 6-60 -
压力 30-70 124-180
液压 20-80

PID详解1(理论+整定方法)相关推荐

  1. PID详解3(摄像头循迹分析)

    PID详解3(摄像头循迹分析) 看了那么多成功的案例和大佬们的分享.讲解,终于轮到我们自己来设计PID了. 首先需要分析的是,想要用PID,我们得先知道,我们需要通过传感器拿到哪些参数,我们处理后要得 ...

  2. 详解linux杀死进程方法:kill、pkill、killall之间的区别及用法!

    详解linux杀死进程方法:kill.pkill.killall之间的区别及用法! kill 命令 killall 命令 pkill 命令 kill.pkill.killall之间的区别 kill 命 ...

  3. indesign图片规定在左下角_详解InDesign基本使用方法

    详解InDesign基本使用方法 为了使朋友们尽快掌握InDesign的使用方法,下面,我们通过一个例子来说明它的操作过程.做之前,先要说两句.乍一接触Indesign,许多朋友会觉得很不熟悉,很不适 ...

  4. python获取屏幕文字_详解:四种方法教你对Python获取屏幕截图(PyQt , pyautogui)...

    前言: 今天为大家带来的内容是详解:四种方法教你对Python获取屏幕截图(PyQt , pyautogui)本文具有不错的参考意义,希望能够帮助到大家! Python获取电脑截图有多种方式,具体如下 ...

  5. 处理对象(toString()方法详解和==与equals方法的区别)

    处理对象(toString()方法详解和==与equals方法的区别) toString()是一个非常特殊的方法,它是一个自我描述的方法.当程序员直接打印该对象的时候,系统会输出该对象的"自 ...

  6. python导入模块介绍_详解Python模块导入方法

    python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...

  7. ubuntu 文件权限命令详解使用格式和方法

    为什么80%的码农都做不了架构师?>>>    在 Ubuntu Linux 中用源码文件安装软件时经常都会用到chmod命令来更改文件的权限使其在安装时有执行的权限.由于 Ubun ...

  8. 5 获取窗口位置_详解:四种方法教你对Python获取屏幕截图(PyQt , pyautogui)

    前言: 今天为大家带来的内容是详解:四种方法教你对Python获取屏幕截图(PyQt , pyautogui)本文具有不错的参考意义,希望能够帮助到大家! Python获取电脑截图有多种方式,具体如下 ...

  9. python expandtabs_详解Python中expandtabs()方法的使用

    详解Python中expandtabs()方法的使用 expandtabs()方法返回制表符,即该字符串的一个副本. '\t'已经使用的空间,可选择使用给定的tabsize(默认8)扩展. 语法 以下 ...

最新文章

  1. 清华硕士眼中的2021届算法岗秋招
  2. 七、Linux脚本进阶和进程管理
  3. 淮海工学院计算机宿舍住b几,淮海工学院本部2009-操作系统试卷B
  4. 借助财务客户评估解决方案在云中构建AppDev
  5. 移动通信—无线波传播
  6. php+mysql投票代码_PHP+jQuery+MySql实现红蓝投票功能
  7. su、sudo、限制root远程登录
  8. php if throw,Laravel throw_if 和 throw_unless 辅助函数
  9. Python案例篇:爬取分析大型招聘网站Python岗
  10. Netty 网络框架概述 与 快速入门
  11. python-随机生成数据faker
  12. 子龙山人 opengl系列 - 网址
  13. android微信视频自动播放,Android微信内网页音频自动播放能力调整
  14. echarts树图设置高亮
  15. 为什么对方的QQ邮箱收不到我QQ邮箱发的邮件?
  16. MacBook Pro 设置Finder显示隐藏文件
  17. ssb门限_SSB调制
  18. Web 前端学习之表单制作、网页超链接
  19. “The Gentle Lentil Restaurant“ Case Solution Report 模型与决策-温柔小扁豆餐厅例题
  20. 对立志成为DBA的人的几点建议

热门文章

  1. Redis清空所有数据命令
  2. 超级课程表课表的界面的实现
  3. 大数据处理技术导论(7) | Datawhale组队学习46期
  4. 视频直播技术——编码和封装
  5. java毕业生设计中小学教师培训管理系统计算机源码+系统+mysql+调试部署+lw
  6. Fail2ban防止网站CC
  7. C语言return的用法详解,C语言函数返回值详解
  8. String你真的会吗?不会还不进来!!!是等我胖虎锤各位呢?!!!
  9. Appium详解(超详细)
  10. 股票查询接口: 腾讯