PID连续控制算法的表达式以及C语言实现

来源:互联网 发布:美国大学统计 知乎 编辑:程序博客网 时间:2024/05/18 03:38


1.      数字(离散)PID控制算法的表达式:

将PID调节器离散化,用差分方程来代替连续系统的微分方程,分为位置式和增量式两类。

重点理解概念如下:

a)  基本偏差e(t):表示当前测量值与设定目标值间的差,设定目标是被减数,结果可为正或负值,正值表示未达到目标,负值表示超过设定值。(代表比例)

b)  偏差和:即每次测量的差值总和,注意正负(代表积分)

c)  基本偏差的相对偏差:即e(t)-e(t-1)用本次的基本偏差减去上一次的基本偏差。(代表微分)


位置式:


增量式:


位置式和增量式三个参数的作用:

1.      Kp参数:能迅速反映误差,从而减小误差,但他不能消除稳态误差,加大Kp还会引起系统的不稳定。

2.      Ki参数:只要有足够的时间,积分作用将能完全消除误差。但其缺点积分控制是偏差累积控制,控制作业缓慢,但是如果积分作用太强会使系统的超调量加大,甚至出现振荡。

3.      Kd参数:预测误差变化趋势,减小超调量,克服振荡,使系统的稳定性提高,还能加快系统的动态响应速度,减小调整时间,从而改善系统的动态性能。


参考代码如下:

[cpp] view plain copy print?/*      位置型pid  */  #include <stdio.h>  #include<ioctl.h>    struct _pid{  float SetSpeed;         //定义设定值  float ActualSpeed;      //定义实际值  float err;              //定义偏差值  float err_last;         //定义上一个偏差值  float Kp,Ki,Kd;         //定义比例、积分、微分系数  float voltage;          //定义电压值(控制执行器的变量)  float integral;         //定义积分值  }pid;    //项目中获取到的参数  void PID_init(){      printf("PID_init begin \n");      pid.SetSpeed=0.0;      pid.ActualSpeed=0.0;      pid.err=0.0;      pid.err_last=0.0;      pid.voltage=0.0;      pid.integral=0.0;      pid.Kp=0.2;             //自己设定      pid.Ki=0.015;           //自己设定      pid.Kd=0.2;             //自己设定      printf("PID_init end \n");  }    float PID_realize(float speed){      pid.SetSpeed=speed;                     //设定值      pid.err=pid.SetSpeed-pid.ActualSpeed;   //设定值-实际值      pid.integral+=pid.err;                  //积分值,偏差累加      pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);      pid.err_last=pid.err;                   //上一个偏差值      pid.ActualSpeed=pid.voltage*1.0;        //算出实际值      return pid.ActualSpeed;                 //返回  }    int main(){      printf("System begin \n");      PID_init();      int count=0;      while(count<1000)      {      float speed=PID_realize(200.0);      printf("%f\n",speed);      count++;      }      return 0;  }  


增量式代码:

[cpp] view plain copy print?/*     增量型pid */  #include<stdio.h>  #include<stdlib.h>  struct _pid{      float SetSpeed; //定义设定值      float ActualSpeed; //定义实际值      float err; //定义偏差值      float err_next; //定义上一个偏差值      float err_last; //定义最上前的偏差值      float Kp,Ki,Kd; //定义比例、积分、微分系数  }pid;  void PID_init(){      pid.SetSpeed=0.0;      pid.ActualSpeed=0.0;      pid.err=0.0;      pid.err_last=0.0;      pid.err_next=0.0;      pid.Kp=0.2;      pid.Ki=0.015;      pid.Kd=0.2;  }  float PID_realize(float speed){      pid.SetSpeed=speed;      pid.err=pid.SetSpeed-pid.ActualSpeed;      float      incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);      pid.ActualSpeed+=incrementSpeed;      pid.err_last=pid.err_next;      pid.err_next=pid.err;      return pid.ActualSpeed;  }  int main(){      PID_init();      int count=0;      while(count<1000)      {      float speed=PID_realize(200.0);      printf("%f\n",speed);      count++;      }      return 0;  }  


原文链接http://blog.csdn.net/xiao2yizhizai/article/details/51025726



原创粉丝点击