在这里暂且将其归为模拟技术吧!
前一段时间由于开关电源的控制,做了一下PID的控制算法,和之前自己的方法对比了一下,感觉效果确实要好不好,关键是参数调好了之后就会很稳定,电压波动比较小,因此有一定的使用价值和实用价值!由于没有学过自动控制原理,所以很多的东西还是从网上看到的,理解起来还是比较生硬,昨天晚上遇到一个问题,现在想拿出来和大家一起思考一下,望大家批评指正!
首先还是拿出公式:
(1)式为PID控制的离散公式,其中e(k)为目标值和输出反馈值的误差。
由(1)式可以得到(2)式,然后将两者想减,得到(3)式。
其次,对公式进行简单的介绍。PID控制在实际应用广泛主要分为两种控制方式:位置式和增量式。
(1)式是简单的求和公式的使用方式,这个也是位置式的控制依据,(3)式为对(1)式的变形,是增量式的控制依据。由于依据的公式的形式不一样,所以具体的实现形势不一样。
由公式(1)的实现形式可以看到,其中有求和项,也就是积分项,而公式(3)则没有求和项。但是注意 一点,后者的得出的是相邻的两者的差值,所以这个不是实际的控制量,实际的控制量是对(u(k)-u(k-1))进行求和得到的。由公式可知,(1)式是能够直接给出控制量的,而(3)式需要多次控制量的累加得到的,这样就导致了我们实现的时间相对长一些,响应速度也就慢一些。
两者实现各有优点,位置式相当于是一个指南针吧,始终向着设定的目标值,而增量式就是一点点想着目标值靠近。前者实现的过程中要求反馈量比较精确,或是说你的采样量比较干净,反馈比例误差小,否则指南针就会指偏了方向。而增量式则是相当于一个死缠难打求婚的男士,一点点向你靠近,不是直接达到,先是靠近你朋友,然后未来的丈母娘,搞渗透,最后才慢慢达到目标。这个原因很简单,因为现在他现在没有信息的反馈渠道,也就是反馈量不准确,他必须要先去获得反馈量,想一蹴而就,要是反馈量不准确,那肯定就会超调,就会吃闭门羹的。所以说增量式还是适合反馈量不准确,反馈噪声大,或是要求输出尽可能比较稳定的情况下面。
现在拿出程序,看看吧!
先看位置式。 *==================================================================================================== PID计算部分 =====================================================================================================*/ 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); // 微分项 } /*********************************************************** 位置式在实现的过程中,一目了然,清楚明白,看一下公式就能知道实现过程。因此没有什么好说的。还是先看看增量式。(以下是我的一个搞智能汽车的同学帮我修改的增量式的程序,但是我一直觉得有点问题,虽然也能实现控制,但是和公式对着看了一下还是不对应,而在进行累加的时候,我发现那样根本就不行,因为累加得到的结果一直是负值,这个是不能直接给我的pwm控制寄存器的。然后我人为修改为进行累减,然后就可以进行控制了)。我不知道问题是不是出在这里,所以还是拿出来和大家讨论讨论。
先看程序:
float PIDCalc( struct PID *pp, unsigned int NextPoint ) { float dError,Error,temp; temp=(NextPoint*3.3/4096.0)*7.5;//将采样电压值转换位输出电压值
pp->SumError = pp->SetPoint-temp ; //积分 Error = pp->SumError-pp->LastError; // 偏差 dError = Error - pp->PrevError; // 当前微分 pp->PrevError = Error; pp->LastError = pp->SumError; temp=(pp->Proportion * Error//比例 + pp->Integral * pp->SumError //积分项 + pp->Derivative * dError); // 微分项 return temp; }
现在我们对应这个公式和微分项看看,由于增量式中微分项为e(k)-e(k-1)-(e(k-1)-e(k-2)=e(k)-2e(k-1)+e(k-2);
那么在我的这个程序实现的过程中,这是直接将e(k)-e(k-1)作为微分项,显然这个公式的差距很大,即便是工程应用上有很大的简约或是其他处理,但是这个已经严重超出等效的范围。
另外昨天晚上转载了一文章,在空间里面,也就将PID的增量控制的,但是实现方式和这个却不大相同,大家也参考一下,这个在理解的时候可能要简单一些,但是初期的跳出合理的参数会更难一点,因为简化后和简化前的关系并不是线性关系。因为有更加线性条件下,适当使用二分法还是能迅速找到最佳参数的位置。
希望大家批评指正哈!