【Day27】:STM32实际应用1—马达精准控速(PID初浅教学(上))

前言

这里要先声明,我没有修过专业的控制相关课程,如果想要学习更专业的PID相关内容可能这里不适合,我只是将我这个暑假所研究的成果记录下来分享给大家,对於最基础的马达控速应该是没问题啦。

PID是什麽?

PID是「控制方法」,是根据目前状态与预设值的偏差值,按比例、积分、微分等运算,运算结果用以输出来进行控制。以马达来说,我们需要的是马达以一个恒定的速度转动,因此先透过之前介绍过的encoder(编码器),来得知目前的转速,再以上述的运算,最後根据计算的结果来输出电压。
https://ithelp.ithome.com.tw/upload/images/20210927/20141525tpV9O6H0FU.png

控制方法

我们先不要管PID,我们来想想看:假设要控制房间到一个恒定的温度20度,冷气应该要怎麽设定?(假设室温30度)
思路如下:
起初为了让室温快速降低,可以先开冷一点,那先开个15度好了。
过了5分钟,室温果真快速降低,现在已经到20度,赶快把冷气调成20度。
再过了2分钟,ㄨㄚˊ怎麽变19度了...,那我再调成21度
过了几分钟,阿又变成20.5度...

当室温与目标值差异很大的时候,我们会输出较低的温度(假设室温>目标值),而等到温差很小,或是温度显示已经达目标值时,我们就输出与目标值相当接近的温度。
但问题来了,为什麽我们在显示为20度时,将冷气设为20度,温度却还会继续下降呢?
一般的感测器都会有延迟的现象,像实验室时常用的酒精温度计,总是要放一阵子以等待温度平衡。因此当它显示20度时,实际上很可能室温是小於20度的。

比例控制

事实上,上面的这个控制的思路很类似P的运算。再举另外一个例子,假设初始时刻,水缸里的水位是0.2米,那麽当前时刻的水位和目标水位之间是存在一个误差的(error),。假设旁边站着一个人,这个人通过往缸里加水的方式来控制水位。如果单纯的用比例控制演算法,就是指加入的水量u和误差error是成正比的。
u=kperror
假设kp取0.5,现在的水位高度是0.2,目标值为1
t=1时,error=1-0.2=0.8,u=0.5
0.8=0.4,因此水位从0.2上升到0.6
t=2时,error=1-0.6=0.4,u=0.5*0.4=0.2,因此水位从0.6上升到0.8
如此这麽循环下去,最终水位会到达我们所设定的1。

但是,单单的比例控制存在着一些不足,其中一点就是–稳态误差!
像上述的例子,根据kp取值不同,系统最後都会达到1米,只不过kp大,到达的快,kp小了到达的慢一些。不会有稳态误差。但是,考虑另外一种情况,假设这个水缸在加水的过程中,存在漏水的情况,假设每次加水的过程,都会漏掉0.1米高度的水。仍然假设kp取0.5,那麽会存在着某种情况,假设经过几次加水,水缸中的水位到0.8时,水位将不会再变换!!!因为,水位为0.8,则误差error=0.2. 所以每次往水缸中加水的量为u=0.5*0.2=0.1.同时,每次加水,缸里又会流出去0.1米的水!!!加入的水和流出的水相抵消,水位将不再变化!!
实际上,这种类似於「漏水」的情况相当常见,以马达来说,摩擦力就相当於是这个例子中的「漏水」。

积分控制

还是用上面的例子,如果仅仅用比例会存在稳态误差,最後的水位就卡在0.8了。於是,在控制中,我们再引入一个分量,该分量和误差的积分是正比关系。所以,比例+积分控制演算法为:
u=kp*error+ ki∗∫ error
大家可能会好奇实际写程序要怎麽做积分?又不是已经知道的一个函数。没错,事实上我们并不是在做积分,而是在离散情况下做累加(sigma)。

还是用上面的例子来说明,
第一次的误差error是0.8,第二次的误差是0.4,∫error=0.8+0.4=1.2. 这个时候的控制量,除了比例的那一部分,还有一部分就是一个系数ki乘以这个积分项。由於这个积分项会将前面若干次的误差进行累计,所以可以很好的消除稳态误差(假设在仅有比例项的情况下,系统卡在稳态误差了,即上例中的0.8,由於加入了积分项的存在,会让输入增大,从而使得水缸的水位可以大於0.8,渐渐到达目标的1.0.)这就是积分项的作用。

微分控制

换一个另外的例子,考虑刹车情况。平稳的驾驶车辆,当发现前面有红灯时,为了使得行车平稳,基本上提前几十米就放松油门并踩刹车了。当车辆离停车线非常近的时候,则使劲踩刹车,使车辆停下来。整个过程可以看做一个加入微分的控制策略。
与积分控制类似,在离散的情况下,我们没办法做到真正的「微分」,我们实际上在做的是error的差值,就是t时刻和t-1时刻error的差,即u=kd*(error(t)-error(t-1))/T,其中的kd是一个系数项。可以看到,在刹车过程中,因为error是越来越小的,所以这个微分控制项一定是负数,在控制中加入一个负数项,他存在的作用就是为了防止汽车由於刹车不及时而闯过了线。
切换到上面给水缸加水的例子,就是当发现水缸里的水快要接近1的时候,加入微分项,可以防止给水缸里的水加到超过1米的高度,说白了就是减少控制过程中的震荡。

最後附上一个公式作为今天的结尾
https://ithelp.ithome.com.tw/upload/images/20210927/20141525HKh2sxc5Ds.jpg


<<:  【Day26】:从struct进化成class的物件导向技巧(下)

>>:  【Day28】:STM32实际应用1—马达精准控速(PID初浅教学(下))

[Day2]C# 鸡础观念- 与C#开发千里来相见

开发工具: 我们这边使用Visual Studio 2017来做为程序的编译工具, 其他版本来做练习...

[day12]Heroku 基本使用

如果你有自己的固定IP,可以在本机进行部署,或着使用免费版本的Heroku Platform在云端建...

​ 疫情下的BCP对策

企业或机构日常管理铁三角 1. 合理化:做该做的事、花该花的钱 (1). 省小钱花大钱,乱省一通得不...

Day 03: Python开发环境 Spyder初探

那麽在上一篇已经有安装好了Anaconda了,我们就可以开始使用Anaconda开发环境底下的各式功...

Day 1 - 前言

前言 大家好,我是毛毛。ヾ(´∀ ˋ)ノ 第二次参加IT铁人赛,希望可以透过这次铁人赛纪录Leetc...