PID详解1(理论+整定方法)

PID详解(理论+应用)

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

理论基础:

PID是什么?

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

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

时域输出方程:

u ( t ) = K P ∗ e ( t ) + K I ∗ ∫ e ( t ) + K D ∗ d e ( t ) d t u(t)=K_P*e(t) +K_I*\int e(t)+K_D*\frac{de(t)}{dt} u(t)=KPe(t)+KIe(t)+KDdtde(t)

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

U [ k ] = K P ∗ e r r [ k ] + K I ∗ ∑ e r r [ k ] + K D ∗ ( e r r [ k ] − e r r [ k − 1 ] ) U[k]=K_P*err[k]+K_I*\sum err[k]+K_D*(err[k]-err[k-1]) U[k]=KPerr[k]+KIerr[k]+KD(err[k]err[k1])

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

G c ( s ) = U ( s ) E ( s ) = K P + K I s + K D ∗ s Gc(s)=\frac{U(s)}{E(s)}=K_P+\frac{K_I}{s}+K_D*s Gc(s)=E(s)U(s)=KP+sKI+KDs

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

K P K_P KP:比例增益 Proportional gain
K I K_I KI :积分增益 Integral gain
K D K_D KD:微分增益 Derivative gain

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

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

        u ( t ) = 100 P ( e ( t ) + 1 T 1 ∫ e ( t ) d t + T D d e ( t ) d t ) ~~~~~~~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)+T11e(t)dt+TDdtde(t))

其中:
P : 比例带(%)
T 1 T_1 T1 :积分时间(s)
T D T_D TD:微分时间(s/min)

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

K P = 100 P K_P = \frac{100}{P} KP=P100
K I = 100 P ∗ 1 T 1 K_I = \frac{100}{P}*\frac{1}{T_1} KI=P100T11
K D = 100 P ∗ T D K_D=\frac{100}{P}*T_D KD=P100TD

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

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

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

      G d ( s ) = K D s τ d s + 1 ~~~~~G_d(s)=\frac{K_Ds}{\tau_d s+1}      Gd(s)=τds+1KDs

其中:
τ 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(k1)=

位置式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);  //微分D
	sptr->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[k1]
= K P [ e [ k ] − e [ k − 1 ] ] + K I e ( k ) + K D [ e [ k ] − 2 e [ 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[k1]]+KIe(k)+KD[e[k]2e[k1]+e[k2]]

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

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

D : e [ k ] − 2 e [ k − 1 ] + e [ k − 2 ] ¥ D: e[k]-2e[k-1]+e[k-2]¥ D:e[k]2e[k1]+e[k2] = 本次误差 - 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);  //微分D
	
	sptr->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的作用

G c ( s ) = K P + K I s + K D s = K D s 2 + K P s + K I s = K D ( S 2 + a s + b ) s = K D ( s + z 1 ) ( s + z 2 ) s G_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+KDs=sKDs2+KPs+KI=sKD(S2+as+b)=sKD(s+z1)(s+z2)

根据数学知识可得:
a = K P K D , b = K I K D a=\frac{K_P}{K_D},b=\frac{K_I}{K_D} a=KDKP,b=KDKI

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

PID整定方法

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

1.手动标定

1.系统闭环,采取P控制器,设置Ki = 0, Kd = 0, Kp取一个较小的数,
  满足系统稳定即可
2.逐渐增加Kp,每次改变控制器参数,都要观察一段时间系统输出量、控
  制量,直到闭环系统达到临界稳定,输出量产生等幅度、等周期的持续震荡
  记录此时的Kp
3.将Kp减少一半,继续采用P控制器,逐步减少Kp,直到获得41衰减震荡
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)