PID学习

基础知识点

场景:

速度信息可以以m/s为单位,或者也可以转换成转速 r/s,而电机的转速是由PWM脉冲宽度来控制的,如何根据速度信息量化成合适的PWM值呢?

比如:现有一辆行驶中的无人车,要求将车速调整至100KM/h,那么应该如何向电机输出PWM值?或换言之,如何控制油门?

调速实现策略由多种,PID其中较为常用。

PID简介

PID算法是一种经典、简单、高效的动态速度调节方式,P代表比例,I代表积分,D代表微分。

PID控制原理框架图:

PID学习_第1张图片

PID学习_第2张图片

模拟式PID公式如下:

PID学习_第3张图片

  • e(t)作为 PID 控制的输入;
  • u(t)作为 PID 控制器的输出和被控对象的输入;
  • Kp 控制器的比例系数;
  • Ki控制器的积分时间,也称积分系数;
  • Kd控制器的微分时间,也称微分系数。

 位置式PID公式如下:

format,png

  • Kp,Ki,Kd为比例,积分,微分的三个重要参数
  • k是采样序列号,k=0,1,2,3…
  • Uk第k次采样时刻控制器输出值,直接对应执行机构的输出值
  • ek第k次采样时刻偏差,e(k-1)第k-1次采样偏差值,e(k-2)第k-2次采样偏差值
  • 位置式pid控制器的输入为系统的偏差值,输出为uk,即偏差的组合

位置式PID是根据编码器的脉冲累加测量电机的位置信息,并与目标值进行比较,得到控制偏差,然后通过对偏差的比例、积分、微信进行控制,使偏差趋向于零的过程。

1.P(比例)——尽快的到达目标值(狠)
如果实现上述场景中的车速控制,一种简单的实现方式是: 确定目标速度,获取当前速度,使用(目标速度-当前速度)*某一系数 计算结果为输出的PWM,再获取当前速度,使用(目标速度-当前速度)*某一系数 计算结果为输出的PWM并输出...如此循环在上述模型中,调速实现是一个闭环,每一次循环都会根据当前时速与目标时速的差值,再乘以以固定系数,计算出需要输出的PWM值,这其中的系数,称之为比例

2.I(积分)——大限度的接近目标值(准)
上述模型算法中,最终速度与预期速度存在稳态误差,这意味着最终结果可能永远无法达成预期,解决的方法就是使用积分I。每次调速时,输出的PWM还要累加根据积分I计算的结果,以消除静态误差。
①每次循环执行P运算时,会累加运算的结果
②基本算法:I*(误差1+误差2+……)

3.D(微分)——控制目标值的波动范围(稳)
当I值设置的过大时,可能会出先"超速"的情况,超速之后可能需要多次调整,产生系统震荡,解决这种情况可以使用D微分,当速度越是接近目标速度时,D就会越施加反方向力,减弱P的控制,起到类似”阻尼“的作用。通过D的使用可以减小系统震荡。

  • 每次循环执行P和I后,都会累加D的运算结果
  • 基本算法:D*(本次误差-上次误差)

         综上,PID闭环控制实现是结合了比例、积分和微分的一种控制机制,通过P可以以比例的方式计算输出,通过I可以消除稳态误差,通过D可以减小系统震荡,三者相结合,最终是要快速、精准且稳定的达成预期结果,而要实现该结果,还需要对这三个数值反复测试、调整……

PID调试技巧:

参数整定找最佳,从小到大顺序查

先是比例后积分,最后再专把微分加

曲线振属荡很频繁,比例度盘要放大

曲线漂浮绕大湾,比例度盘往小扳

曲线偏离回复慢,积分时间往下降

曲线波动周期长,积分时间再加长

曲线振荡频率快,先把微分降下来

动差大来波动慢。微分时间应加长

理想曲线两个波,前高后低4比1

一看二调多分析,调节质量不会低

变量区:

FUNCTION_BLOCK PID_INC
VAR_INPUT
	MeasurePoint :REAL;(*测量值*)//现在的位置
	SetPoint :REAL;(*目标值*)//目标的位置
	P :REAL;
	I :REAL;
	D :REAL;
	Ramp :WORD;(*控制周期*)
	(*PAR_ZengLiangMax :WORD;(*增量最大值*)*)
	PAR_ControlMAX :DINT;(*控制最大值,用于保护被控对象*)
	Reset :BOOL;(*停止PID*)
	encoderDaoZhuang:BOOL;
END_VAR
VAR_OUTPUT
	Control :DINT;(*输出量*)//速度
	ZengLiang :INT;(*PID增量*)
END_VAR
VAR
	E :REAL :=0;(*当前误差*)
	E1 :REAL :=0;(*上次误差*)
	E2 :REAL :=0;(*上上次误差*)
	INTEGRAL:REAL:=0;(*误差积分*)
	count :WORD :=0;(*用于计时*)
	PID_Y :DINT :=0;
	PIDMax :REAL :=0;
	out: INT;
END_VAR

代码区:

IF Reset THEN
	E :=0;
	E1 :=0;
	E2 :=0;
	count :=0;
	PID_Y:=0;
	Control:=0;
	INTEGRAL:=0;
ELSE
	IF(count >= Ramp)THEN (*Ramp就是控制周期,用count进行循环计时*)
		
		E := -SetPoint + MeasurePoint;
		IF encoderDaoZhuang THEN		// MeasurePoint 与 SetPoint 输反了 TRUE
			E:=-E;
		END_IF
		INTEGRAL:=E1+E2+E;//积分项为偏差的累计
		PID_Y:=REAL_TO_INT( E*P + INTEGRAL*I+((E-E1)*D)) ;(*位置式*)
		E2 := E1;
		E1 := E;

		IF(PID_Y > PAR_ControlMAX)THEN
			PID_Y := PAR_ControlMAX;
		END_IF
		IF(PID_Y < -PAR_ControlMAX)THEN
			PID_Y := -PAR_ControlMAX;
		END_IF

		Control:=PID_Y;
		count := 0;
		
	ELSE
		count := count + 1;
	END_IF
END_IF

调用: 

		No1PID(
			MeasurePoint:=DINT_TO_REAL(g_No1Signedposition) ,
			SetPoint:=DINT_TO_REAL(g_Motor.No1Screw.No1SetPositionNormValue),
			P:=g_No1MotorPID.KP,
			I:=g_No1MotorPID.KI,
			D:=g_No1MotorPID.KD,
			Ramp:=10,
			PAR_ControlMAX:=100000,
			Reset:=Reset_PID ,
			encoderDaoZhuang:=TRUE,
			Control=>No1PIDOUT
		);

视频总结:

从不懂到会用!PID从理论到实践~
学会PID

PID学习_第4张图片
PID学习_第5张图片
PID学习_第6张图片

        偏差量从传感器而来,执行量要给传感器,两个不同设备之间的单位不同,数值范围可能会存在差异,可以通过比例系数 p 放大或缩小两者的关系,最后把比例 P 给执行量即可实现比例环节。

        偏差量是有正负的,如果偏差量不断朝一个方向出现,说明小球的位置一直达不到目标值,说明比例P小了。

PID学习_第7张图片

 比例P过小,由增幅器I补充;比例P过大,由抑制器削减。

PID学习_第8张图片

        如果比例P小了,偏差量会不断朝一个方向,这时积分I就会不断累加到一个很大的值,来影响执行量,从而对P进行补充;如果在目标附近抖动,偏差量一会正一会负,累加到积分I时,积分I就会不断趋近于0,积分项就不会产生效果了。

PID学习_第9张图片

 增幅器I需要限制,因为如果系统出现意外或者错误,增幅器可能会累加到无线大,会使系统无法运行。

PID学习_第10张图片

 抑制器D:  下一次的偏差量 = 当前偏差量 - 上一次的偏差量,一般经过P的调节后,小球位置会不断接近目标量,所以偏差通常会越来越小,所以,当前偏差量 <上一次的偏差量,即下一次的偏差量常为负值。因此用下一次的偏差量提前参与到计算中,可以防止P过大产生超出目标的问题。 

一般开始时P项为正的,D项为负的,调节时,如果小球位置超过目标位置(超调),导致P项为负的,则D项就会变成正的。

P、I 同向,D项相反?

PID学习_第11张图片

超调是指控制系统在初始阶段产生的超出目标值的响应。

P项和I项过大都会导致系统超调

当P增益设置得过高时,控制器的输出会迅速增大,以尽快减小误差。然而,由于系统的惯性和延迟,过大的输出信号可能会导致系统产生过冲。系统会超过目标值,然后再逐渐回到稳定状态。 

当I增益设置过大时,即使系统存在较小的误差,控制器也会累积大量的误差积分。随着时间的推移,误差积分项会趋向于无限增大,这可能导致控制器输出超出合理范围,进而引起系统的超调。

同时,如果系统具有较大的反馈延迟,而I增益设置过大时,控制器对误差的积分响应会滞后于实际需求。当控制器试图通过增加输出来消除误差时,由于滞后效应,控制器可能会过度积累误差,导致系统产生超调。

PID参数调节方式:

为了防止系统产生超调,P一开始要小一点,然后不断调大,把Kp调到某一程度后,会发现实际值不断接近目标值,但一直到不了目标值,存在稳态误差,这时候调节I项,消除稳态误差,I项大一点,消除误差的效果好一点。如果对系统的响应时间有要求(快速响应),则可以适当增大I项。

如果系统出现了超调,导致系统震荡,调节D项,让震荡减弱。但D项不能太大,否则会加大系统的响应时间。

一般的系统用P I就可以了,D只用在震荡明显的系统。

PID学习_第12张图片

举例1

小车运动到目标位置(100m) 后停止

PID学习_第13张图片
PID学习_第14张图片

假设一个控制周期为 1s

 如果小车的期望的目标位置为100,现在的实际位置为0,则偏差E=100-0=100,若调节P=0.1,则P控制器输出 P*E=0.1*100=10m/s 的速度给电机,小车向前运动10m;

 如果小车的期望的目标位置为100,现在的实际位置为10,则偏差E=100-10=90,若调节P=0.1,则P控制器输出 P*E=0.1*90=9m/s 的速度给电机,小车又向前运动9m;

 如果小车的期望的目标位置为100,现在的实际位置为50,则偏差E=100-50=50,若调节P=0.1,则P控制器输出 P*E=0.1*50=5m/s 的速度给电机,小车又向前运动5m;

若希望小车快速的运动到目标位置,则增大p,增加速度。

举例2

无人机悬停高度调节

PID学习_第15张图片

 假设无人机悬停时,4个螺旋桨的转速为100rpm

刚开始时,调节P,开始时偏差E=100-0,若 p=1, 则P控制器输出 P*E=1*100=100rpm 的速度给螺旋桨,此时飞机会在0m悬停。

为了使飞机上升,令p=2,偏差E=100-0,P控制器输出 P*E=2*100=200rpm 的速度给螺旋桨,飞机上升。当上升到P*E=100时,飞机再次悬停。此时E=50,飞机的实际高度为100-50=50m;

当p=100时,偏差E=100-实际位置,P控制器输出 P*(100-实际位置)rpm 的速度给螺旋桨,飞机上升。当上升到P*E=100时,飞机再次悬停。此时E=1,飞机的实际高度为100-1=99m;

可以发现,为了使飞机能够悬停,即 P*(100-实际位置)=100成立,则(100-实际位置)不可能为0,所以只调节 P 飞机悬停的实际高度永远达不到100,系统存在稳态误差。

因此,需要引入 I 项,消除稳态误差。

当 P=100 时,只使用 P 项,飞机最终会悬停在 99m 处,此时系统的偏差 E=1 ,系统的输出P*E=100,如果再引入 I 项,用 I 项将之前的偏差E累加起来,此时系统的输出为 P*E+I*\sum Ei,大于100rpm,使得飞机再次上升。

当飞机飞到100m时,P*E项=0,P项不起作用了。虽然悬停后偏差E=100-100=0,但 I 项由于也累加了悬停前的偏差E,所以 I 项不是0,悬停的工作就交给了I项。

若P=100,刚开始时E=100-0=100,P*E=10000,飞机会飞的巨快,同理积分项累计的偏差E也会很大(100 90 80 70····),可能会导致飞机飞的超过100m,出现超调。

此时,再引入D项,下一次的偏差量=当前偏差量 - 上一次的偏差量,90-100=-10,80-90,70-80,为负值,微分项 D*(E2-E1)<0,调节D即可消除超调,阻碍无人机的飞行速度。 

你可能感兴趣的:(学习)