查看: 11284|回复: 20

[其他] Debug连载帖第八帖——PID算法(2)

[复制链接]
  • TA的每日心情
    郁闷
    2021-3-10 19:44
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    126

    主题

    525

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2018
    最后登录
    2023-12-25
    发表于 2015-8-24 10:25:11 | 显示全部楼层 |阅读模式
    上一帖我们主要介绍了PID的概念,增量式PID算法和积分分离算法,这一贴我们主要讲PID的其他几种进阶算法。


    一:抗积分饱和的PID控制

    所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制量超出了正常运行范围而进入饱和区。一旦系统出现反向偏差,u(k)逐渐从饱和区退出。进入饱和区越深则退出饱和区时间越长。在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应的改变,这时系统就像失控一样,造成控制性能恶化,这种现象称为积分饱和现象或积分失控现象。

      防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在计算u(k)时,首先判断上一时刻的控制量u(k-1)是否已经超出了极限范围: 如果u(k-1)>umax,则只累加负偏差; 如果u(k-1)<umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。

    C语言代码如下:
    1. <font size="3">#include<stdio.h>
    2. #include<stdlib.h>
    3. #include<math.h>
    4. double IncreasementSpeed;
    5. int count;
    6. double Speed;
    7. struct _pid
    8. {
    9. double SetSpeed;//定义设定值
    10. double ActualSpeed;//定义实际值
    11. double err;//定义误差
    12. double err_last;//定义上上一次误差
    13. double Ki,Kp,Kd;//定义三个比例系数
    14. double err_next;//定义上一次误差
    15. double umax;
    16. double umin;
    17. double voltage;//定义执行机构的电压值
    18. double intergral;//定义积分值
    19. }pid;
    20. void pid_init()
    21. {
    22. pid.ActualSpeed=0.0;
    23. pid.err=0.0;
    24. pid.err_last=0.0;
    25. pid.err_next=0.0;
    26. pid.SetSpeed=0.0;
    27. pid.Kp=0.2;
    28. pid.Ki=0.1;
    29. pid.Kd=0.2;
    30. pid.umax=400;
    31. pid.umin=-200;
    32. }
    33. double PID_realize(double Speed)
    34. {
    35. int index;
    36. pid.SetSpeed=Speed;
    37. pid.err=pid.SetSpeed-pid.ActualSpeed;
    38. if(pid.ActualSpeed>pid.umax)
    39. {
    40. if(fabs(pid.err)>200)
    41. index=0;
    42. else
    43. {
    44. index=1;
    45. if(pid.err<0)
    46. pid.intergral+=pid.err;
    47. }
    48. }
    49. else if(pid.ActualSpeed<pid.umin)
    50. {
    51. if(fabs(pid.err)>200)
    52. index=0;
    53. else
    54. {
    55. index=1;
    56. if(pid.err>0)
    57. pid.intergral+=pid.err;
    58. }
    59. }
    60. else
    61. {
    62. if(fabs(pid.err)>200)
    63. index=0;
    64. else
    65. {
    66. index=1;
    67. pid.intergral+=pid.err;
    68. }
    69. }
    70. pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.intergral+pid.Kd*(pid.err-pid.err_last);
    71. pid.err_last=pid.err;
    72. pid.ActualSpeed=pid.voltage;
    73. return pid.ActualSpeed;
    74. }
    75. int main()
    76. {
    77. pid_init();
    78. while(count<1500)
    79. {
    80. double Speed=PID_realize(200.0);
    81. printf("%lf\t",Speed);
    82. count++;
    83. }
    84. return 0;
    85. }</font>
    复制代码


    结论:前后两次对比,我们发现系统的稳定速度明显加快。


    二:积分优化——梯形积分

    首先,我们要阐述一下什么是梯形积分。我们用的积分都是矩形积分,而梯形积分积分的优势就是可以消除余差,提高运算精度。画一个图理解
    file:///C:\Users\john\AppData\Local\Temp\ksohtml\wpsC48D.tmp.png
    QQ截图20150824101953.png b      
                        a
    矩形我们对其积分是∫(a+b)/2 dx换成梯形积分为∫(c+a)/2,积分空出来的那两个地方就是余差。

    我们仅仅需要改动一个地方:pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last);  
    代码就不贴了,可以发现积分精度提高了不少。


    三:变积分的PID控制算法C语言实现
       变积分PID可以看成是积分分离的PID算法的更一般的形式。在普通的PID控制算法中,由于积分系数ki是常数,所以在整个控制过程中,积分增量是不变的。但是,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。因此,根据系统的偏差大小改变积分速度是有必要的。

       变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。

       当abs(err)<180时,index=1;
       当180<abs(err)<200时,index=(200-abs(err))/20;(此时快要达到阈值,放缓积分速度)
       当abs(err)>200时,index=0;
       最终的比例环节的比例系数值为ki*index;

    1. <font size="3"> #include<stdio.h>
    2. #include<stdlib.h>
    3. #include<math.h>
    4. double IncreasementSpeed;
    5. int count;
    6. double Speed;
    7. struct _pid
    8. {
    9.         double SetSpeed;//定义设定值
    10.         double ActualSpeed;//定义实际值
    11.         double err;//定义误差
    12.         double err_last;//定义上上一次误差
    13.         double Ki,Kp,Kd;//定义三个比例系数
    14.         double err_next;//定义上一次误差
    15.         double voltage;//定义执行机构的电压值
    16.         double intergral;//定义积分值
    17. }pid;
    18. void pid_init()
    19. {
    20.         pid.ActualSpeed=0.0;
    21.         pid.err=0.0;
    22.         pid.err_last=0.0;
    23.         pid.err_next=0.0;
    24.         pid.SetSpeed=0.0;
    25.         pid.Kp=0.4;
    26.         pid.Ki=0.2;
    27.         pid.Kd=0.2;
    28. }
    29. double PID_realize(double Speed)
    30. {        
    31.         double index;
    32.         pid.SetSpeed=Speed;
    33.         pid.err=pid.SetSpeed-pid.ActualSpeed;
    34.         if(fabs(pid.err)>200)
    35.                 index=0;
    36.         else if(fabs(pid.err)<180)
    37.         {
    38.                 index=1;
    39.                 pid.intergral+=pid.err;
    40.         }
    41.         else
    42.         {
    43.                 index=(200-fabs(pid.err))/20;
    44.                 pid.intergral+=pid.err;
    45.         }
    46.         pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.intergral+pid.Kd*(pid.err-pid.err_last);
    47.         pid.err_last=pid.err;
    48.         pid.ActualSpeed=pid.voltage;
    49.         return pid.ActualSpeed;
    50. }
    51. int main()
    52. {
    53.         pid_init();
    54.         while(count<1500)
    55.         {
    56.                 double Speed=PID_realize(200.0);
    57.                         printf("%lf\t",Speed);
    58.                         count++;
    59.         }
    60.         return 0;
    61. }</font>
    复制代码

    结果如图所示:

    图片3.png



    结论:系统稳定的时间非常快!
    今天写到这里结束,PID的所有算法已经介绍完毕,下一篇介绍模糊算法和专家算法的控制理念。



    我知道答案 目前已有20人回答
    很开心
    回复

    使用道具 举报

    该用户从未签到

    5

    主题

    22

    帖子

    0

    注册会员

    Rank: 2

    积分
    57
    最后登录
    2018-6-20
    发表于 2015-8-24 11:35:26 | 显示全部楼层
    写的不错,学习了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2016-11-9 09:28
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    9

    主题

    351

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1472
    最后登录
    1970-1-1
    发表于 2015-8-25 15:37:36 | 显示全部楼层
    好东西,顶楼主
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-5-27 11:02
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    15

    主题

    566

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1890
    最后登录
    2017-5-27
    发表于 2015-8-25 17:19:48 | 显示全部楼层
    学习一下,很有用
    klntuo累
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16866
    最后登录
    1970-1-1
    发表于 2015-8-25 21:21:35 | 显示全部楼层
    这个结合曲线更完美了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-10-18 11:35
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    21

    主题

    945

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2001
    最后登录
    2020-6-8
    发表于 2015-8-26 09:51:37 | 显示全部楼层
    好东西,一定要学习,顶一个。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    11

    帖子

    0

    注册会员

    Rank: 2

    积分
    58
    最后登录
    2017-2-18
    发表于 2015-8-26 15:22:11 | 显示全部楼层
    不错。这么多的分类,关键还是对PID的理解与实现的问题。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-6-24 18:51
  • 签到天数: 6 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    17

    主题

    565

    帖子

    0

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2011
    最后登录
    2021-3-10
    发表于 2015-8-27 16:52:37 | 显示全部楼层
    支持一下 不知道有没有实战过.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-1-30 19:52
  • 签到天数: 19 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    19

    主题

    628

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1515
    最后登录
    2018-5-28
    发表于 2015-8-29 21:22:40 | 显示全部楼层
    支持一下
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    39
    最后登录
    2015-12-31
    发表于 2015-9-1 09:43:42 | 显示全部楼层
    顶一下 很实用
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-7 15:41 , Processed in 0.108779 second(s), 31 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表