打印
[STM8]

【转】最简单的自动控制PID算法研究

[复制链接]
770|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一代掌门|  楼主 | 2016-11-27 13:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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  
  •     }  
  • }  


发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

191

帖子

4

粉丝