上次我们了解了PID的基本工作原理,这次来学习离散PID和连续PID。
一.连续形式PID与离散形式PID
1.了解
连续形式的PID里面是有积分和微分操作的。这些操作直接放在单片机里是不太好写程序的。连续形式的PID需要用模拟电路来实现。模拟电路时时刻刻都在工作,对于单片机而言,我们需要用离散形式的PID,离散后单片机需要设定一个调控周期T,单片机每隔T周期才会进行一次PID计算和调控。单片机里的调控是间隔进行的。我们本节的任务就是,将这个连续形式的PID进行离散化。然后用单片机的C预言,来实现PID程序设计。

离散形式的公式就是:k的取值是0,1,2等等表示的是第几次调控,error(k)的意思就是第几次调控时当前的误差值。T是离散后的调控周期,也就是系统每隔T时间,调控一次。
这个符号是求和,然后error(j)是每一次的误差,j从0变到k意思就是把第k次调控之前,把所有的error累加起来。这里error(j)中的j是累加时候的临时变量,类似于C语言中的i,for(i=0;i<10; i++);和其中的i是一个道理。最后error(k)是本次误差,error(k-1)是上一次误差。
2.如何进行离散的
首先是P项,从Kp*t时刻的误差。现在是Kp*error(k)表示Kp*第k次调控时刻的误差。

之后是I项,Ki*从0-t时刻的积分

这就是积分和微分离散化的示意图。

这个是积分示意图,横轴表示时间,纵轴表示误差的变化。绿色线是连续形式下的误差曲线。然后横轴每个数字表示第K次调控。其中每次调控的时间间隔都是T,T就是调控周期。
比如说要求K=0-8范围的积分。连续形式就是积分符号。这个面积就约等于所有面积之和。所以这就解释了上面为什么这样子离散的。


之后我们看这个,某点的微分就是求该点切线的斜率
就是求T=5时刻的微分,也就是k=5时刻,绿线切线的斜率,只是绿色斜率在离散的情况下,我们需要借助上一次的误差值近似求,也就是在error5和error4之间连接一条线,这里用红线表示,这个红线近似为k=5时刻的切线。且T越小这个时刻越精确,和上面的T一个道理。斜率就是dx/dy,这里dx就是error5减error4,dx就是T,因此error5减error4再除以T=斜率如果大于的话斜率就是正的就是红色线,负值的话斜率就是负的,紫色线。
离散后公式多呆了一个T意味着积分和微分离散后和这个调控时间T是有关的,最后T其实是个常数Ki和Kd也是常数,为了让公式更简洁,我们可以把T合并到Ki和Kd中。这样就得到了最后一个公式

需要注意的是,Ki包含了*T,Kd包含了/T。
3.位置式PID和增量式PID是什么意思。

可以看到位置式PID和上面离散后的完全一样,因为将连续形式PID离散后得到的公式就叫做,位置式PID。
位置式PID减去k=k-1时候的位置式PID就是增量式PID。等号左边就是第K次的输出减去第k-1次的输出,结果意思就是,第k次的输出值,相比于上一次输出值的增量。我们可以用下面的三角out(k)表示。第一个化简就是直接相减,第二个就有意思了,上面的求和式0~k次的累加,下面的求和是0~k-1次的累加,下面的求和相比较上面,少了第k次的error。因此两个求和一相减,就是剩下的第k次的error。简称error(k)。D项也是直接相减,简单合并就行。

之后观察增量式PID计算公式。我们可以发现等号右边没有任何求和符号,全是最基础的加减乘除计算过程,非常清晰。并且其中只出现了error(k),error(k-1),error(k-2)这三个输入变量。因此我们可以有一个结论,增量式PID输出的结果三角out,只是本次,上次,上上次,这三次error的线性组合。
4.增量式PID和位置式PID的区别
为什么要有增量式PID呢,他和位置式PID有什么区别。之后是位置式PID和增量式PID的比较。

连续PID离散后是离散PID,而这个直接得到的离散PID就是位置式PID或者叫全量是PID,因为他每次计算得到的是全量的输出值,这个全量输出值可以作为调控力度。直接作用给大多数的执行机构。位置式PID适合大部分应用场景。速度控制,位置控制,姿态控制等等。位置式PID都可以完成。
位置式PID就是增量式PID进行k次和k-1次运算,之后互减就可以得到。所以输出值是增量。比如说步进电机,阀门控制。需要内部有积分功能。
位置式的就是固定位置,0 1 2 3....9。增量式就是,+1+2+3+4.....+9实际位置与初始位置有关。增量式每次告诉你的是变化量,位置式PID每次告诉你的是固定值。因此如果被控对象,不能记录上一次的状态,或者不能实现再上一次状态的基础上加减调节的功能,那么这个被控对象就不能直接接收输出值的增量。
位置式PID也可以实实施增量式的效果。就是我直接把上一次输入值存起来,然后本次计算后,用本次的输出值,减去上一次的输出值。结果也是输出值的增量。
第三条的意思就是可以再控制器里定义一个变量out,每次计算的到增量后,执行out+=三角out。将三角out累加到out变量上这样这个out变量就是全量输出。之后out变量就可以作为调控力度,输出给执行机构了。我们这样处理后增量式PID与位置式PID整体功能没有区别,因为他们现在输出的都是全量的输出值。
第四条的话,位置式PID的中间变量是误差积分,可以单独进行积分限幅,防止积分饱和,内部积分的增量式PID,没法单独对积分环节限幅。换一种说法就是内部积分的增量式PID,只需要对输出值进行限幅。就可以同时实现积分限幅和输出限幅两个功能,而位置式PID输出限幅和积分限幅得分开进行。另外位置式PID每次计算输出的是全量输出值,如果信号有噪声干扰,不同输出值可能会相差很大。这会导致执行机构大幅度变化。而增量式PID和内部积分式PID都可以单独对输出值增量进行限幅,防止执行机构大幅度变化。
二.PID程序实现
1.代码对比
调控周期取决于程序变化的快慢,比如倒立摆。但是也不能太快会受到硬件限制,比如电机测速的编码器。过快的调控周期,编码器测速就会不准确。


这是我们经常用的方法。但是有一个弊端,解释下:进中断会执行软件层面的程序现场保护,但不保护硬件层面的现场,因此会导致硬件冲突。

稍微完善一点,这既是我们项目中用到的。可以防止硬件层次的冲突。但是也有个弊端,因为我们把程序写在主程序里面,所以我们的主程序要是堵塞的话,就会PID调控不及时,一定要防止主程序堵塞。
2.位置式PID的程序实现


因为可能会出现小数,所以变量用的都是float。误差是计算用到的中间变量。

然后定时中断里面是PID控制的核心代码。error1就是上次误差,error0就是本次误差=目标值-实际值。因为把误差存在error1里面后,第二次来的话error1里面存放的就是上一次误差,error0存放的是本次误差。
每次PID调控erroeint都会+=error0这样子就相当于所有误差的积分了。之后输出限幅,可以把out值限定在允许的范围内,比如PID调控一个200,你的电机只能接受0-100,那么肯定不能直接发送给电机,需要限幅一下。
3.增量式PID程序控实现
这里买呢是控制器内积分,输出全量。


还是先定义变量。![]()
这里是和1位置式PID不一样的地方。

之后误差传递也和位置式的不一样。

因为我们输出的是增量,要的是全量,我们需要在控制器内积分,所以我们选择直接+=赋值给输出。
3381

被折叠的 条评论
为什么被折叠?



