天天看点

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

PID控制器

  • 小场景
  • PID控制器
    • 模拟PID的公式
    • PID的位置离散表达式
    • 增量式PID
    • PID参数的基本影响
    • PID参数的调节方法
    • PID算法的程序结构
    • MATLAB仿真
      • 问题(下面的仿真上面是误差,下面是输入)
    • c例子
      • 增量型PID
      • 积分分离的PID控制算法C语言实现
      • 抗积分饱和的PID控制算法C语言实现
  • 参考资料

小场景

经过了一天辛苦的学习,你终于回到了宿舍, 准备去洗个热水澡, 一开始是凉水,于是你开始逐步右旋,又感觉太慢了,于是转的幅度更大,忽然又感觉到烫,赶忙在回调, 往复几次, 达到自己想要的温度, 开始舒舒服服地洗澡。这个问题抽象一下,就是开始假设x℃的水温, 要调节到y℃。你有以下几种调节温度的行为:

1.每隔1秒3℃步进调节,或者逐步减小调节 (比例系数, 当前误差);

2.逐步加大调节(积分增益, 过去误差的积累);

3.温度过热, 回调 (微分增益, 误差变化趋势)。

PID控制器

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

模拟PID的公式

U ( t ) = k p ( e ⁡ ( t ) + 1 T I ∫ e ⁡ ( t ) d t + T D de ⁡ ( t ) d t ) \mathrm{U}(t)=k p\left(\operatorname{e}(t)+\frac{1}{T_{I}} \int \operatorname{e}(t) d t+\frac{T_{D} \operatorname{de}(t)}{d t}\right) U(t)=kp(e(t)+TI​1​∫e(t)dt+dtTD​de(t)​)

U ( t ) ⟶ \mathrm{U}(\mathrm{t})\longrightarrow U(t)⟶ 调节(控制)器的输出信号

e ( t ) ⟶ \mathrm{e}(t) \longrightarrow e(t)⟶ 调节器的偏差信号, 它等于测量值与给定值的差 (e=error误差)

K p ⟶ K p \longrightarrow Kp⟶ 调节器的比例系数;

T I ⟶ T_{I} \longrightarrow TI​⟶ 调节器的积分时间;其物理意义是偏差恒定时,控制量加倍所需的时间。

T D ⟶ T_{D} \longrightarrow TD​⟶ 调节器的微分时间

没有比例时间这个说法。因为Kp*e里面误差信号e的单位和被控量是一样的。比例系数的单位是1

对模拟公式进行离散化处理

离散化:把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

∫ 0 n e ( t ) d t = ∑ j = 0 n E ( j ) Δ t = T ∑ j = 0 n E ( j ) d e ( t ) d t ≈ E ( k ) − E ( k − 1 ) Δ t = E ( k ) − E ( k − 1 ) T \int_{0}^{n} e(t) d t=\sum_{j=0}^{n} E(j) \Delta t=T \sum_{j=0}^{n} E(j)\\ \frac{d e(t)}{d t} \approx \frac{E(k)-E(k-1)}{\Delta t}=\frac{E(k)-E(k-1)}{T} ∫0n​e(t)dt=j=0∑n​E(j)Δt=Tj=0∑n​E(j)dtde(t)​≈ΔtE(k)−E(k−1)​=TE(k)−E(k−1)​

用人话来说就是:你不可能一直知道系统的参数,只能是离散的采样

PID的位置离散表达式

P ( k ) = K p { E ( k ) + T T D ∑ j = 0 k E ( j ) + T D T [ E ( k ) − E ( k − 1 ) ] } \large P(k)=K_{p}\left\{E(k)+\frac{T}{T_{D}} \sum\limits_{j=0}^{k} E(j)+\frac{T_{D}}{T}[E(k)-E(k-1)]\right\} P(k)=Kp​{E(k)+TD​T​j=0∑k​E(j)+TTD​​[E(k)−E(k−1)]}

Δ t = T ⟶ \Delta t=T \longrightarrow Δt=T⟶ 采样周期, 必须使 T T T 足够小, 才能保证系统有一定的精度;

E ( k ) ⟶ E(k) \longrightarrow E(k)⟶ 第k次采样时候的偏差值

k ⟶  采样序号  k \longrightarrow \text { 采样序号 } k⟶ 采样序号 

E ( k − 1 ) ⟶ E(k-1) \longrightarrow E(k−1)⟶ 第 ( k − 1 ) (\mathrm{k}-1) (k−1) 次采样时的偏差值

P ( k ) ⟶ P(k) \longrightarrow P(k)⟶ 第k次采样时候调节器的输出

位置式PID的计算不仅需要本次和上一次的偏差信号,而且还要在积分项把历次的偏差信号进行相加。这样,不仅计算繁琐,而且为保存E(j)还需要占用很多内存,因此位置式PID的控制用的很少,采用增量式PID来控制系统。

增量式PID

根据位置式PID的递推原理,可以写出(k-1)次的PID输出表达式:

P ( k − 1 ) = K p { E ( k − 1 ) + T T D ∑ j = 0 k − 1 E ( j ) + T D T [ E ( k − 1 ) − E ( k − 2 ) ] } \large P(k-1)=K_{p}\left\{E(k-1)+\frac{T}{T_{D}} \sum_{j=0}^{k-1} E(j)+\frac{T_{D}}{T}[E(k-1)-E(k-2)]\right\} P(k−1)=Kp​{E(k−1)+TD​T​∑j=0k−1​E(j)+TTD​​[E(k−1)−E(k−2)]}

P ( k ) = K p { E ( k ) + T T D ∑ j = 0 k E ( j ) + T D T [ E ( k ) − E ( k − 1 ) ] } \large P(k)=K_{p}\left\{E(k)+\frac{T}{T_{D}} \sum_{j=0}^{k} E(j)+\frac{T_{D}}{T}[E(k)-E(k-1)]\right\} P(k)=Kp​{E(k)+TD​T​∑j=0k​E(j)+TTD​​[E(k)−E(k−1)]}

用P(k)-P(k-1)得到

P ( k ) = P ( k − 1 ) + K p [ E ( k ) − E ( k − 1 ) ] + K l E ( k ) + K D [ E ( k ) − 2 E ( k − 1 ) + E ( k − 2 ) ] \large P(k)=P(k-1)+K_{p}[E(k)-E(k-1)]+K_{l} E(k)+K_{D}[E(k)-2 E(k-1)+E(k-2)] P(k)=P(k−1)+Kp​[E(k)−E(k−1)]+Kl​E(k)+KD​[E(k)−2E(k−1)+E(k−2)]

式子中: K I = K P T T I K D = K P T D T \quad K_{I}=K_{P} \frac{T}{T_{I}} \quad K_{D}=K_{P} \frac{T_{D}}{T} KI​=KP​TI​T​KD​=KP​TTD​​

PID参数的基本影响

稳定性:在平衡状态下,系统受到某个干扰后,经过一段时间其被控量可以达到某一稳定状态(能稳住)PI- D+

准确性:系统稳定时,与目标值的偏差(残差)小。PI+

快速性:加入扰动后,重新进入稳态的时间短。PD+ I-

P控制对系统性能的影响:

开环增益越大,稳态误差减小(无法消除,属于有差调节)

过渡时间缩短,稳定程度变差,偏差一旦产生,立刻控制

I控制对系统性能的影响:

消除系统稳态误差(能够消除静态误差,属于无差调节),稳定程度变差,T1越大积分作用越强

D控制对系统性能的影响:

减小超调量

减小调节时间(与P控制相比较而言)(反映偏差信号的变化趋势,能够在偏差信号变得过大之前加入调节信号以此缩短时间)增强系统稳定性

PID简化控制系统的设计,不需要考虑中间的系统结构

PD提高稳定性改善瞬态

PI改善稳态误差

PID参数的调节方法

滚球式控制系统调试

只加P,令D、I值为0。不断尝试不同的P值,直到球可以以目标点为中心等幅振荡。

保持上一步调好的P值不变,不断尝试不同的D值,直到球在目标点附近小幅度抖动。

保持上一步调好的P、D值不变,直到小球可以进入目标点并基本静止(消除静态误差)。

DI=0,调节P使目标出现等幅振荡

保留P值,加入D,使目标出现小幅振荡

保留PD,加入I,消除静态误差。

PID算法的程序结构

定时中断中进行PID计算

高速单片机执行PID算法耗时可以忽略,故PID定时中断优先级略低于目标值采集的相关中断。

根据控制对象来确定定时时间,如电机等,一般为10-30ms,电源中的MOS管可采用10-20ms,但无论如何,PID定时时间>=目标值采集时间

对于目标采集值,由于有采集顺序存在,可采用双缓冲来进行存储。

PID参数最好采用宏定义或源程序代码起始处进行赋值,不要直接在程序代码中赋值,便于修改和明确。

MATLAB仿真

Simulink中

transfer function带初始状态

Constant参考值

Sum 表示比较器

Pid有封装好的模块,可以调节三个增益

Band-limit白噪音

Scope看图,

view,layout可以分成两个图

P无法消除稳态误差

Mux可以连接多个图,

I超调量更多,稳定时间更长,

pid超调小,调节快,但是初始输入状态变化非常大,同时微分对高频噪音特别敏感,0.001sin1000t

问题(下面的仿真上面是误差,下面是输入)

f ( s ) = x ( s ) u ( s ) ) = 1 s 2 + 0.8 s + 1 \large f(s)=\frac{x_{(s)}}{\left.u_{(s)}\right)}=\frac{1}{s^{2}+0.8s+1} f(s)=u(s)​)x(s)​​=s2+0.8s+11​

初 始 条 件 x ( 0 ) = x ˙ ( 0 ) = 0 目 标 参 考 r = 10 初始条件 x_{(0)}=\dot x_{(0)}=0\\ 目标参考r=10 初始条件x(0)​=x˙(0)​=0目标参考r=10

PID之前的是误差

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

首先是只有P=10作用下的图形

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料
PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

View选项的layout可以分离图形

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

可以看到误差无法到0

如果P的系数为10,I的系数为5,D的系数为0

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

可以看到波形最终误差更小,但是到达稳态的时间延长了许多

比例存在稳态误差

积分不存在,但稳定时间更长,且超调量大

再来考虑P=10,I=5,D=3的情况下

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

单独看波形其实很好,再来看看对比

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料
PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

微分误差很小,超调很小,调节很快

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

但是最初的输出相当大,在实际运用中,电气设备的电压电流容量,有可能不支持,另外它对于白噪音的反应相当敏感,现在我们对整个系统加入一个扰动,快速高频变化但很小的量,模拟大自然中的噪声。

PID控制器及MATLAB和c测试简介小场景PID控制器参考资料
PID控制器及MATLAB和c测试简介小场景PID控制器参考资料

对于误差调节的部分变化不大,但是输入调节的部分出现了最多3100的信号

对0.001sin1000t求导,频率越高扩大程度越大

c例子

增量型PID

# include <stdio.h>
# include <stdlib.h>
struct _pid {
	float SetSpeed; //定义设定值
	float ActualSpeed; //定义实际值
	float err;  //定义偏差值
	float err_next;//定义上一个偏差值
	float err_last;//定义最上前的偏差值
	float Kp,Ki,Kd;//定义比例、积分、微分系数
} pid;

void PID_init () {
	pid.SetSpeed=0.0;
	pid.ActualSpeed=0.0;
	pid.err=0.0;
	pid.err_last=0.0 ;
	pid.err_next=0.0 ;
	pid.Kp=0.2;
	pid.Ki=0.015;
	pid.Kd=0.2;
}

float PID_realize(float speed) {
	pid.SetSpeed=speed;
	pid.err=pid.SetSpeed-pid.ActualSpeed;
	float incrementSpeed=pid.Kp*(pid.err-pid.err_next) + pid.Ki*pid.err + pid.Kd*(pid.err-2*pid.err_next+pid.err_last) ;
	pid.ActualSpeed+=incrementSpeed;
	pid.err_last=pid.err_next;
	pid.err_next=pid.err;
	return pid.ActualSpeed;
}

int main () {
	PID_init ();
	int count=0;
	while (count < 1000) {
		float speed=PID_realize (200.0);
		printf("%f\n",speed);
		count++;
	}
	return 0;
}
           

初始化小程序不需要写出来,但大的工程中很有必要,规范格式还是搞出来

积分分离的PID控制算法C语言实现

在启动、结束或大幅度增减设定时,短时间内系统输出有很大的偏差,会造成PID运算的积分积累,导致控制量超过执行机构可能允许的最大动作范围对应的极限控制量,从而引起较大的超调,甚至是振荡。

为了克服这个问题,引入积分分离的概念,即当被控量和设定值偏差较大时,取消积分作用;当被控量接近设定值时,引入积分控制,以消除静差,提高精度。

if (abs (pid.err) >200 )
	index=0;
} else {
	index =1;
	       pid.integral+=pid.err;
}
pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last) //算法具体实现过程 
           

abs :绝对值

令index=0使积分环节失效

抗积分饱和的PID控制算法C语言实现

积分饱和现象:如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置。此时计算器输出量超出正常运行范围而进入饱和区,一旦系统出现反向偏差,输出量将逐渐从饱和区退出,进入饱和区越深则退出饱和区时间越长,在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应改变,造成性能恶化。

抗饱和积分法:防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在计算 u (k) 时,首先判断上一时刻的控制量 u (k-1) 是否已经超出了极限范围: 如果 u(k-1)>umax,则只累加负偏差; 如果 u (k-1) <umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。

参考资料

1.理解概念:正点原子PID算法详解http://www.openedv.com/forum.php?mod=viewthread&tid=273313&highlight=PID

2.学习仿真:DR_CAN的【自动控制原理】12_PID控制器_Matlab/Simulink仿真https://www.bilibili.com/video/BV1xQ4y1T7yv?from=search&seid=1522568478703671336

3.取材

详细讲解PID,取表格https://zhuanlan.zhihu.com/p/82344845

维基百科,PID控制器,变化图形https://zh.wikipedia.org/wiki/PID%E6%8E%A7%E5%88%B6%E5%99%A8

PID算法的C语言实现

https://www.jianshu.com/p/10d5e476c700

PID控制算法的C语言实现

https://blog.csdn.net/u010312937/article/details/53363831

继续阅读