PID算法(积分微分控制)

来源:互联网 发布:淘宝男装店知乎 编辑:程序博客网 时间:2024/06/05 03:29
PID算法(积分微分控制)
http://hi.baidu.com/lyzhangxiang/blog/item/671f1c3143709195a9018eed.html

          上一篇文章中和大家提到了一个关于温度控制的项目,既然涉及自动控制的过程必然需要PID算法来支撑。然而温度的PID算法和电机速度这一类的PID算法又有着很大的不同,电机速度这样的模拟量可以很快测得响应时间短最主要的是他可以在很短时间内控制。然而对于温度来说响应时间往往很慢而且温度是一个模糊量控制的难度可想而知,比如说你控制到50摄氏度但是此时电热丝还处于升温状态这样往往会加大算法的难度,控制的太紧不行太松了又不行。

举一个简单的例子来说,在仪器仪表行业中比如你做汽车的速度指针(这里是用TFT一类的显示器来模拟指针的可不是物理指针的那种啊)当速度在增加时等在接近你的速度值之前指针的转动速度会越来越慢,做一种阻尼运动。

设定指针转动速度旧值:OldValue

设定指针转动速度新值:NewValue

设定控制系数:K

整个过程可以描述为:新值=旧值+K(旧值-上一次新值)

NewValue=OldValue+K(OldValue-NewValue)   整个过程中控制系数K的选取至关重要。

PID算法部分,相关优化会进一步更新


/*==============================================================================  
在使用单片机作为控制cpu时,请稍作简化,具体的PID参数必须由具体对象通过实验确定。
由于单片机的处理速度和ram资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,
运算到最后再除以一个2的N次方数据(相当于移位),作类似定点数运算,可大大提高运算速度,
根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的“余数”,做好余数补偿。
这个程序只是一般常用pid算法的基本架构,没有包含输入输出处理部分。
==============================================================================*/

#include <string.h>
#include <stdio.h>


/*===============================================================================
PID Function       
The PID function is used in mainly   
control applications. PID Calc performs one iteration of the PID   
algorithm.
While the PID function works, main is just a dummy program showing
a typical usage.

PID功能
在PID功能主要用于控制应用。 PID 计算器执行一个PID的迭代算法。虽然PID功能的工程,
主要只是一个虚拟程序显示一个典型的使用。
================================================================================*/
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             // 微分项       
     );
}

/*======================= 初始化的PID结构 Initialize PID Structure===========================*/
void PIDInit (PID *pp)
{   
        memset ( pp,0,sizeof(PID));
}


/*======================= 主程序 Main Program=======================================*/
double sensor (void)                    // 虚拟传感器功能   Dummy Sensor Function{    return 100.0;}
void actuator(double rDelta)            // 虚拟驱动器功能   Dummy Actuator Function{}
void main(void)
{   
                PID         sPID;                   // PID控制结构   PID Control Structure   
                double      rOut;                   // PID响应(输出) PID Response (Output)   
                double      rIn;                    // PID反馈(输入) PID Feedback (Input)
    PIDInit ( &sPID );                  // 初始化结构 Initialize Structure   
    sPID.Proportion = 0.5;              // 设置PID系数 Set PID Coefficients   
    sPID.Integral   = 0.5;   
    sPID.Derivative = 0.0;   
    sPID.SetPoint   = 100.0;            // 设置PID设定 Set PID Setpoint
    for (;;)
    {                                   // 模拟最多的PID处理 Mock Up of PID Processing
        rIn = sensor ();                // 读取输入 Read Input       
        rOut = PIDCalc ( &sPID,rIn );   // 执行的PID迭代 Perform PID Interation       
        actuator ( rOut );              // 所需的更改的影响 Effect Needed Changes   
    }