PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻):
1.输入量为rin(t);
2.输出量为rout(t);
3.偏差量为err(t)=rin(t)-rout(t);
1,PID是一个闭环控制算法。因此要实现PID算法,必须在硬件上具有闭环控制,就是得有反馈。比如控制一个电机的转速,就得有一个测量转速的传感器,并将结果反馈到控制路线上,下面也将以转速控制为例。
2,PID是比例(P)、积分(I)、微分(D)控制算法。但并不是必须同时具备这三种算法,也可以是PD,PI,甚至只有P算法控制。我以前对于闭环控制的一个最朴素的想法就只有P控制,将当前结果反馈回来,再与目标相减,为正的话,就减速,为负的话就加速。现在知道这只是最简单的闭环控制算法。
3,比例(P)、积分(I)、微分(D)控制算法各有作用:
比例,反应系统的基本(当前)偏差e(t),系数大,可以加快调节,减小误差,但过大的比例使系统稳定性下降,甚至造成系统不稳定;
积分,反应系统的累计偏差,使系统消除稳态误差,提高无差度,因为有误差,积分调节就进行,直至无误差;
微分,反映系统偏差信号的变化率e(t)-e(t-1),具有预见性,能预见偏差变化的趋势,产生超前的控制作用,在偏差还没有形成之前,已被微分调节作用消除,因此可以改善系统的动态性能。但是微分对噪声干扰有放大作用,加强微分对系统抗干扰不利。
积分和微分都不能单独起作用,必须与比例控制配合。
最简单的PID程序:
[cpp] view plain copy
- =====================================================================================================*/
- #include <string.h>
- #include <stdio.h>
- /*====================================================================================================
- PID Function
-
- The PID (比例、积分、微分) function is used in mainly
- control applications. PIDCalc performs one iteration of the PID
- algorithm.
-
- While the PID function works, main is just a dummy program showing
- a typical usage.
- =====================================================================================================*/
-
- typedef struct PID {
-
- double SetPoint; // 设定目标 Desired Value
-
- double Proportion; // 比例常数 Proportional Const
- double Integral; // 积分常数 Integral Const
- double Derivative; // 微分常数 Derivative Const
-
- double LastError; // Error[-1]
- double PrevError; // Error[-2]
- double SumError; // Sums of Errors
-
- } PID;
-
- /*====================================================================================================
- PID计算部分
- =====================================================================================================*/
- double PIDCalc( PID *pp, double NextPoint )
- {
- double 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 // 微分项
- );
- }
-
- /*====================================================================================================
- Initialize PID Structure
- =====================================================================================================*/
-
- void PIDInit (PID *pp)
- {
- memset ( pp,0,sizeof(PID));
- }
-
- /*====================================================================================================
- Main Program
- =====================================================================================================*/
-
- double sensor (void) // Dummy Sensor Function
- {
- return 100.0;
- }
-
- void main(void)
- {
- PID sPID; // PID Control Structure
- double rOut; // PID Response (Output)
- double rIn; // PID Feedback (Input)
-
- PIDInit ( &sPID ); // Initialize Structure
- sPID.Proportion = 0.5; // Set PID Coefficients
- sPID.Integral = 0.5;
- sPID.Derivative = 0.0;
- sPID.SetPoint = 100.0; // Set PID Setpoint
-
- for (;;) { // Mock Up of PID Processing
-
- rIn = sensor (); // Read Input
- rOut = PIDCalc ( &sPID,rIn ); // Perform PID Interation
- actuator ( rOut ); // Effect Needed Changes
- }
- }
|