对于pid控制的个人理解 附c语言代码

一、对于PID控制算法的引入

位式控制算法(二位式)所比较的只有输出值与设定值,输出方式只有两种,用开关量控制控制对象,但是用“开关量”来控制一个物理量,就显得比较简单粗暴了。有时候,是无法保持稳定的。因为单片机、传感器不是无限快的,采集、控制需要时间。而且,控制对象具有惯性。比如你将一个加热器拔掉,它的“余热”(即热惯性)可能还会使水温继续升高一小会。导致输出不稳定且输出不平滑,相对设定值有很大的误差。由此我们需要一个更新的算法来满足:
它可以将需要控制的物理量带到目标附近
它可以“预见”这个量的变化趋势
它也可以消除因为散热、阻力等因素造成的静态误差

二、对于PID算法的理解

P:比例(Kp)
I:积分(Ki)
D:微分(Kd)
过程:输入通过比例调节,积分调节,微分调节,判断输出到执行机构;执行机构输出的同时有测量元件,对于输出与设定再比较,再输入。循环往复
公式:
在这里插入图片描述

u(t)——控制器(也称调节器)的输出。
e(t)——控制器的输入(常常是设定值与被控量之差,即e(t)=r(t)-c(t)。
Kp——控制器的比例放大系数。
Ti ——控制器的积分时间。
Td——控制器的微分时间。

PID三个最基本的参数:Kp、Ki、Kd:
Kp:比例,它的作用最明显,原理最简单,以加热水为例:
有设定值与当前值:
当两者差距不大时,就让加热器以小功率加热一下。 要是因为某些原因,温度降低了很多,就让加热器提高功率工作。要是当前温度比目标温度低得多,就让加热器全功率加热,尽快让水温到达目标附近。就让偏差(目标减去当前)与调节装置的“调节力度”,建立一个一次函数的关系,就可以实现最基本的比例控制了

Kp越大,调节作用越激进,Kp调小会让调节作用更保守。

Kd:微分的作用比较好理解。(仍以水温为例)
首先,由于P的作用,水温会在目标温度上下波动,整个系统不稳定。类似于弹簧振子,会在平衡位置震荡。
我们需要一个控制作用,让被控制的物理量的“变化速度”趋于0,即类似于阻力的作用。
因为,当比较接近目标时,P的控制作用就比较小了。越接近目标,P的作用越温柔。有很多内在的或者
外部的因素,使控制量发生小范围的摆动。D的作用就是让物理量的速度趋于0,
只要什么时候,这个量具有了速度,D就向相反的方向用力,尽力刹住这个变化。
Kd参数越大,减小波动的效果明显,在波动较小时,Kd较小。

Ki:积分过程使用于特殊情况,(以水温为例)
假如加热装置带到了非常冷的地方,开始烧水了。需要烧到50℃。在P的作用下,水温慢慢升高。
直到升高到45℃时,他发现了一个不好的事情:天气太冷,水散热的速度,和P控制的加热的速度相等。

“Kp:45度与50度差距小,只需要轻轻加热就可以了。
Kd:加热和散热相等,温度没有波动,不用调整什么。”

于是,水温永远地停留在45℃,永远到不了50℃。
因此:设置一个积分量。只要偏差存在,就不断地对偏差进行积分(累加),并反应在调节力度上。

这样一来,即使45℃和50℃相差不太大,但是随着时间的推移,只要没达到目标温度,这个积分量就不断增加。系统就会慢慢意识到:还没有到达目标温度,该增加功率啦!
到了目标温度后,假设温度没有波动,积分值就不会再变动。这时,加热功率仍然等于散热功率。
但是,温度是稳稳的50℃。Ki的值越大,积分时乘的系数就越大,积分效果越明显。

所以,i的作用就是,减小静态情况下的误差,让受控物理量尽可能接近目标值。
i在使用时还有个问题:需要设定积分限制。防止在刚开始加热时,就把积分量积得太大,难以控制。

PID一般可以用PI、PD控制,也可以PID全部。

三、绝对式(位置式)PID和增量式PID算法

位置式控制算法:
每次周期性计算出的 PID 为绝对的数值,是执行机构实际的位置。
公式:u(k)=Kp*e(k) + Ki∑e(i) + Kd * [e(k) - e(k - 1)]
由于计算机输出的u(k)可直接控制执行机构(如阀门),u(k)的值和执行机构的位置(如阀门开度)是一一对应的。
因此通常称该公式为位置式PID控制算法。

位置式控制算法的缺点:
当前采样时刻的输出与过去的各个状态有关,计算时要对e(k)进行累加,运算量大; 而且控制器的输出u(k)对应的是执行机构的实际位置,如果计算机出现故障, u(k)的大幅度变化会引起执行机构位置的大幅度变化。

增量式控制算法:
控制器的输出只是控制量的增量Δu(k)。计算机输出的控制量Δu(k)对应的是本次执行机构位置的增量。
公式:△u(k) = u(k) - u(k - 1)
△u(k) = Kp[e(k) - e(k - 1)] + Ki*e(k) + Kd[e(k ) - 2e(k - 1) + e(k - 2 )]

增量式控制算法的缺点:截断效应大,溢出影响大。

区别:
位置式PID控制的输出与整个过去的状态有关,有误差的累加值;
而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大。

增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。

由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。

从数学角度位置式和增量式没有差别,增量式通过做差免去了一直对e(k)做积分而已,并不是没有积分作用,只是没有积分这一运算过程。对于不同的控制模型,我们可以使用PI、PD、PID、甚至单P调节,就是说要根据实际对PID的三个部分进行取舍

代码部分

位置型PID的C语言实现:
第一步:定义PID变量结构体

typedef struct 
{
	float limit;	//积分限制
	float Kp;		
	float Ki;
	float Kd;
	float eSum;		//误差
	float e0;		
	float e1;		
}PID_AbsoluteType;//位置式PID

第二步:初始化变量

void PID_Struct_Init_abs(PID_AbsoluteType* PID,float kp,float ki,float kd,float out_max)
{
	PID->Kp = kp;//比例
	PID->Ki = ki;//积分
	PID->Kd = kd;//微分
	PID->e0 = 0;//现在的误差
	PID->e1 = 0;//上次的误差
	PID->eSum = 0;
	PID->limit = out_max;//自己设置积分限幅
}

第三步:编写控制算法

float PID_Update_Absolute3(PID_AbsoluteType* PID,float tar,float cur)    
{
	float pe, ie, de;
	float out=0;
	
	PID->e0 = tar - cur;
	PID->eSum += PID->e0;
	 //可以做一个积分限幅
	
	de = PID->e0 - PID->e1;

	pe = PID->e0;
	ie = PID->eSum;

	PID->e1 = PID->e0;
	
  out = pe*(PID->Kp) + ie*(PID->Ki) + de*(PID->Kd);
	//输出限幅也有时有必要做
	return out;
}

到此为止,PID的基本实现部分就初步完成了,当然pid的参数调节才是重中之重,这里我才疏学浅,还需进一步学习。

萌新初来报道,多多包涵,文章排版好丑,大家凑合看吧。拜谢支持

你可能感兴趣的:(对于pid控制的个人理解 附c语言代码)