学习PID

时间:2022-05-22 10:08:11

最近在想自己的文章有些是不是写的太难以理解了呢.........竟然好多人看了还是会直接问我很多问题.......

其实PID哈靠自己想像就能自己写出来自己的代码,也许是网上的讲的太过的高深什么积分微分,搞的晕头转向,本来这么实用的想法为什么偏偏说的那么的琢磨不透......感觉那些人根本就没有真正的自己动脑思考,PID最初肯定是人们在做控制的时候不断的思考,不断的尝试然后总结出来的...现在咱们也来思考一下啊

咱举一个例子就是控制电机----控制电机的转速

学习PID

咱们先规定好

对了其实事先会规定一个PWM的周期,,假设是10KHZ,,,,周期的大小会对电机的转速有影响,这是必然的,讲到后面就知道如何选择周期了.....

设置PWM占空比的函数 PWMSet(0-10000(PWM变量));0的时候占空比为0%,,也就是那个引脚一直输出低电平,5000的时候占空比为50%,,也就是那个引脚半周期低电平半周期高电平,10000的时候占空比为100%,也就是那个引脚一直输出高电平

采集到的电机的转速 V采集

设置的电机的速度  V设置

现在想怎么样才能根据采集的和设置的控制电机的速度呢?????

电机转的快的时候要减速控制PWM变量变小,电机转的慢的时候要加速控制PWM变量增大,

可以让设置的速度和采集的速度做差

让  V偏差 = V设置 - V采集;

电机转的快的时候 V采集 > V设置  V偏差一直是负值

电机转的慢的时候 V采集 < V设置  V偏差一直是正值

但是呢如果直接  PWMSet(V偏差);这是瞎胡闹......

但是呢   如果

V偏差 = V设置 - V采集;

V控制PWM = V偏差累加和  + V偏差;

PWMSet(V控制PWM);

上面的这3句话假设是每间隔10ms执行一次哈!!!又会有疑问,,为什么10ms执行一次哈??这是假设的,,,但是这个也会影响到控制电机的速度,,讲到后面就知道了

现在分析一下,,假设设置的速度是90

刚启动的时候采集的速度是0,,然后呢速度再没有达到90之前,,,V控制PWM一直在增加,,,,PWMSet(V控制PWM),,所以电机一直在加速

然后采集的速度到达90之后V偏差是0,设置电机的PWM不变,假设超过了设置的速度呢V偏差是小于0,,,V控制PWM = V控制PWM  + V偏差;所以V控制PWM又会减小PWMSet(V控制PWM),最终呢电机又会减速,,,所以就会这样的反反复复了

现在呢再想一下,,,,难道这样就行了吗???

假设PWMSet(V控制PWM),这里面控制速度的变量在7000的时候才能达到咱设置的速度90......

这样的话其实V控制PWM = V控制PWM  + V偏差;第一次V控制PWM是90,然后后面的肯定比90小,,,因为电机开始转了,,,有没有什么感觉不好的地方????V控制PWM变化的太慢.......这样就会出现问题...达到自己设定的速度需要的时间太长......要是中途我出现了事故需要赶紧控制电机的速度为230吧,,,,那家伙还是慢吞吞的....实在是受不了.....

学习PID

      受不了这么慢(图1)

所以呢!需要控制它变化的快一些对吧,,也就是让V控制PWM = V控制PWM  + V偏差;这个程序吧让它每次累加的大一点

直接加上一个常数肯定不行....但是可以乘以一个常数

V控制PWM = V控制PWM  + V偏差*P;

现在就开始考虑这个常数了.....

咱就想一想如果常数太小的话,,起不到作用....

常数慢慢增大....假设设置的是3,

其实就会发现即使偏差是1那么调整的会是3,,就是控制占空比变化3,,,,如果再大就会出现电机抖动的厉害...理所当然因为越大PWM变化的越厉害.....导致电机一停一转的人眼都看出来了.............

学习PID

        受不了你的不稳定(图2)

现在就在想怎么样确定这个比例值呢.......

咱做的程序肯定能打印电机的速度哈....

咱们可以看着速度慢慢的增加比例P,,,亲们感觉速度的变化成什么样子就行了呢??????

在增加P的时候肯定有一个值是电机出现抖动...当然咱是看电机的速度数据,那个速度呢一增一减的而且最大速度和最小速度距离设置的速度很大.....咱们要的是速度立马加上去,,但是呢也能够在很短时间内平稳下来...绝对不能出现来回的抖动

学习PID

这样还算可以

但是呢!电机有惯性或者比例还是有点大,导致会出现一个波峰..............然后呢又慢慢的平稳下来.....

学习PID

现在要做的是想办法消除这个波峰,,,或者呢能不能把这个波峰往下降一降...

怎么样才能对付这个波峰呢!!!怎样才能在速度快要达到的时候,或者已经达到了,,别在过度的增加PWM了,,,肯定是在偏差上下功夫,,在变化的时候想办法再给他一个变化的变量,,能够抑制住

学习PID

就整体趋势来讲,,偏差是越来越小,,然后变为负值越来越小,,然后到顶.....我们想的是能不能把前面的变为负值开始到到顶,,抑制一下

图画的不一定是对的....只是讲一下整体的趋势

学习PID

有些人发现这时候的变化趋势之后就在想,,怎样把这种趋势应用到解决以上的问题中.....

然后有些人发现....斜率.....

学习PID

怎样计算每个点的斜率呢!!!!!!!!微分......

我的数学都忘干净了......有时候会发现,,没上大学的时候会的挺多的,,一上大学感觉什么东西都忘了.....

随着时间的推移,我可以通过那个斜率得到一个慢慢变化的值(开始挺小的(稍微有些抑制),慢慢变大(抑制作用越来越强) 或者开始挺大的(开始还能促进),慢慢变小(促进作用越来越小) ).......

所以这才引入了微分的概念........

但是呢有人又会想,我也同意微分确实可以描述,,,但是呢单片机程序怎么写呢??????????

您看哈,,,既然知道程序中一些变量的作用了,,,,咱们可以去百度一下别人写的程序哈,,,然后带着自己的想法思考一下别人的程序看一看是不是满足要求,而且PID都这么多年了,,肯定有人写,自学的能力在于勤于思考,擅于学习.....

注:拷贝您的程序无冒犯之意,只是为了学习一下,如果有什么问题您可以留言,我马上删掉....

看刚百度的第一个

学习PID

因为我们现在在意的是微分部分,,所以只看

学习PID

突然发现有点问题....说好的增量计算呢,,,,,,不管它了

V控制PWM = V控制PWM  + V偏差*P + (一个比例数)*上次偏差;

来感受感受....这好像......(一个比例数)*上次偏差     和   V偏差*P   有多大的区别呢........

算了看下一个...

unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)
{
unsigned int dError,Error ;
Error=pp->SetPoint-NextPoint ;//偏差 pp->SumError+=Error ;//偏差和 dError=pp->LastError-pp->PrevError ;//微分环节---上次偏差减去上上次偏差 pp->PrevError=pp->LastError ;
pp->LastError=Error ; return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError);//最后相加 }

现在我们关注的是

dError=pp->LastError-pp->PrevError ;//微分环节---上次偏差减去上上次偏差

咱们先假设偏差数据是这样的

90, 70, 55, 46,30,25,18,10,5,1,-1,-5,-13,-15(到顶)

上次偏差减去上上次偏差----好像大部分都是负值  而且这个负值越来越小

V控制PWM = V控制PWM + V偏差*P + (一个比例数)*(上次偏差-上上次偏差);

如果那个比例数是正的.....就相当于

V控制PWM = V控制PWM  + V偏差*P  - (一个越来越小的数).......(整体来说,,一开始抑制作用很强,,慢慢变弱)

然后到了后面的负值部分....就相当于

V控制PWM = V控制PWM  + V偏差*P  +(一个数).......(抑制了调节)

这是几乎永远的都在抑制调节呢.....还可以毕竟可以抑制....

如果那个比例值是负值

V控制PWM = V控制PWM  + V偏差*P  + (一个越来越小的数).......(整体来说,,一开始促进作用很强,然后慢慢变弱)

然后到了后面的负值部分....就相当于

V控制PWM = V控制PWM  + V偏差*P  - (一个数).......(促进了调节)

永远的在促进,但是促进作用在减弱

当然如果不想让那个比例值为负值..可以让 上上次偏差减去上次偏差嘛

就变成了

V控制PWM = V控制PWM  + V偏差*P + (一个比例数)*(上上次偏差-上次偏差);

但是呢!!!感觉现在应该要减小一点比例P了....因为后面也是促进.....如果不减小肯定达不到效果.....

既然还可以就再接着说----思想有了怎样实现就要自己动脑了......

有了上面的PD调节了...现在呢再说一下可能还有问题.....就是说到了稳定的状态以后呢,,还是有误差

怎么办呢,,,只要有误差就需要调节.....误差的累加,,只要有误差就一直累加

如果是这样

偏差的和 = 偏差的和  + V偏差

V控制PWM = V控制PWM  + V偏差*P + (一个比例数)*(偏差的和);

只要存在偏差,那么通过 偏差的和 一直在促进着去调节....

如果组合起来

V控制PWM = V控制PWM + V偏差*P + (一个比例数)*(上次偏差-上上次偏差) + (一个比例数)*(偏差的和);

应该还可以....

对了最后一个就是所谓的积分调节

学习PID

其实呢我也只是明白要这样做

最后别人总结的口诀

学习PID

一篇文章

http://baike.sogou.com/v108236.htm?fromTitle=PID

如果问我控制两个电机的速度一样怎么办???

写两个一样的PID,然后设置的速度写成一样哈

上面的呢叫增量式PID

还有一个叫做位置式PID---列如控制舵机

舵机是给占空比固定的PWM 舵机就一直转自身固定的角度

所以呢就没有了上面的累加的那部分

V控制PWM =  V偏差*P ;

假设是控制一个小车前进和急转弯,,,,我们希望的是在直道的时候呢,,舵机的比例不要那么的大,,弯道的时候可以大一些

其实可以

学习PID

V控制PWM =  V偏差*V偏差*P ;(用二次函数解决)

其实呢关键是思想