改进式PID控制以及C语言实现过程

改进式PID控制

         如果是在低速模式下,标准的PID基本可以满足控制要求,但随着速度的提升,PID算法要进一步修改和完善才能达到控制要求。因此需要对PID算式进行适当的改进,从而提高控制质量。

         积分项的改进

         积分项的作用:消除稳态误差,提高控制系统的精度。

积分项存在的问题:偏差较大时,积分的滞后作用会影响系统的响应速度,引起较大的超调及加长过渡过程,尤其对时间常数较大,有时间滞后的被控对象,更加剧了振荡过程。

1.      积分分离法:

改进方案:当偏差大于某个规定的门限值时,取消积分作用,从而使积分不至于过大。只有当e(k)较小时,才引入积分作用,以消除静差。这样控制量不易进入饱和区;即使进入了饱和区,也能较快的退出,所以能使系统的输出特性得到改善。

 

2.      抗积分饱和法:

改进方案:当控制量进入饱和区后,只执行削弱积分项的累加,而不进行增大积分项的累加。即计算u(k)时,先判断u(k-1)是否超过限制范围,若已超过umax,则只累计负偏差;若小于umin,则只累计正偏差,这种方法也可以避免控制量长期停留在饱和区。

算法案例如下:

[cpp]  view plain  copy
 print ?
  1. /* 
  2.     积分分离的pid控制算法c语言实现 
  3.     系统所用时间是原来时间的一半 
  4.     系统的快速性得到了提高 
  5. */  
  6.   
  7. #include<stdio.h>  
  8. #include<stdlib.h>  
  9.   
  10. struct _pid{  
  11.     float SetSpeed;         //定义设定值 //24V   1100-1900  
  12.     float ActualSpeed;      //定义实际值  
  13.     float err;              //定义偏差值  
  14.     float err_last;         //定义上一个偏差值  
  15.     float Kp,Ki,Kd;         //定义比例、积分、微分系数  
  16.     float voltage;          //定义电压值(控制执行器的变量)  
  17.     float integral;         //定义积分值  
  18. }pid;  
  19.   
  20. //项目中获取到的参数  
  21. void PID_init(){  
  22.     printf("PID_init begin \n");  
  23.     pid.SetSpeed=0.0;  
  24.     pid.ActualSpeed=0.0;  
  25.     pid.err=0.0;  
  26.     pid.err_last=0.0;  
  27.     pid.voltage=0.0;  
  28.     pid.integral=0.0;  
  29.     pid.Kp=0.2;             //自己设定  
  30.     pid.Ki=0.04;            //自己设定  
  31.     pid.Kd=0.2;             //自己设定  
  32.     printf("PID_init end \n");  
  33. }  
  34.   
  35.   
  36. float PID_realize(float speed){  
  37.     pid.SetSpeed=speed;                     //设定值  
  38.     pid.err=pid.SetSpeed-pid.ActualSpeed;   //设定值-实际值  
  39.     int index;  
  40.     if(abs(pid.err)>200)  
  41.     {  
  42.         index=0;  
  43.     }else{  
  44.         index=1;  
  45.         pid.integral+=pid.err;  
  46.     }  
  47.     pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.  
  48.     err-pid.err_last); //算法具体实现过程  
  49.       
  50.     pid.err_last=pid.err;                   //上一个偏差值  
  51.     pid.ActualSpeed=pid.voltage*1.0;        //算出实际值  
  52.     return pid.ActualSpeed;                 //返回  
  53. }  
  54.   
  55. int main(){  
  56.     PID_init();  
  57.     int count=0;  
  58.     while(count<1000)  
  59.     {  
  60.     float speed=PID_realize(200.0);  
  61.     printf("%f\n",speed);  
  62.     count++;  
  63.     }  
  64.     return 0;  
  65. }  


[cpp]  view plain  copy
 print ?
  1. /* 
  2.     抗击分饱和的pid控制算法 
  3.      
  4. */  
  5.   
  6. #include<stdio.h>  
  7. #include<stdlib.h>  
  8. struct _pid{  
  9.     float SetSpeed; //定义设定值  
  10.     float ActualSpeed; //定义实际值  
  11.     float err; //定义偏差值  
  12.     float err_last; //定义上一个偏差值  
  13.     float Kp,Ki,Kd; //定义比例、积分、微分系数  
  14.     float voltage; //定义电压值(控制执行器的变量)  
  15.     float integral; //定义积分值  
  16.     float umax;  
  17.     float umin;  
  18. }pid;  
  19.   
  20. void PID_init(){  
  21.     printf("PID_init begin \n");  
  22.     pid.SetSpeed=0.0;  
  23.     pid.ActualSpeed=0.0;  
  24.     pid.err=0.0;  
  25.     pid.err_last=0.0;  
  26.     pid.voltage=0.0;  
  27.     pid.integral=0.0;  
  28.     pid.Kp=0.2;  
  29.     pid.Ki=0.1; //注意,和上几次相比,这里加大了积分环节的值  
  30.     pid.Kd=0.2;  
  31.     pid.umax=400;  
  32.     pid.umin=-200;  
  33.     printf("PID_init end \n");  
  34. }  
  35.   
  36. float PID_realize(float speed){  
  37.     int index;  
  38.     pid.SetSpeed=speed;  
  39.     pid.err=pid.SetSpeed-pid.ActualSpeed;  
  40.     if(pid.ActualSpeed>pid.umax) //灰色底色表示抗积分饱和的实现  
  41.     {  
  42.         if(abs(pid.err)>200) //蓝色标注为积分分离过程  
  43.         {  
  44.         index=0;  
  45.         }else{  
  46.             index=1;  
  47.             if(pid.err<0)  
  48.             {  
  49.             pid.integral+=pid.err;  
  50.             }  
  51.         }  
  52.     }else if(pid.ActualSpeed<pid.umin){  
  53.         if(abs(pid.err)>200) //积分分离过程  
  54.         {  
  55.             index=0;  
  56.         }else{  
  57.             index=1;  
  58.             if(pid.err>0)  
  59.             {  
  60.                 pid.integral+=pid.err;  
  61.             }  
  62.         }  
  63.     }else{  
  64.             if(abs(pid.err)>200) //积分分离过程  
  65.             {  
  66.                 index=0;  
  67.             }else{  
  68.                 index=1;  
  69.                 pid.integral+=pid.err;  
  70.             }  
  71.         }  
  72. //  pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);  
  73. pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last);//梯形积分  
  74.     pid.err_last=pid.err;  
  75.     pid.ActualSpeed=pid.voltage*1.0;  
  76.     return pid.ActualSpeed;  
  77. }  
  78.   
  79. int main(){  
  80.     PID_init();  
  81.     int count=0;  
  82.     while(count<1000)  
  83.     {  
  84.     float speed=PID_realize(200.0);  
  85.     printf("%f\n",speed);  
  86.     count++;  
  87.     }  
  88.     return 0;  
  89. }  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值