前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部。再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是智能算法与PID控制算法的结合,是基于PID控制器的智能化优化。

  在本章我们首先来探讨一下专家PID算法。正如前面所说,专家PID算法是专家系统与PID算法的结合与应用优化,所以我们接下来先简单了解专家控制。

1、专家控制的基本思想

  专家控制是智能控制的一个分支,是专家系统的理论和技术同控制理论、方法与技术相结合,在无对象模型的情况下,模仿领域专家的经验来实现对被控对象的控制。

  专家控制一般由知识库和推理机构构成主体框架,按照某种策略及时选用恰当的规则进行推理输出,实现控制。其基本结构如下:

  有上图我们不难发现影响专家控制器控制精确性的主要是知识库表达的准确性以及推理机的正确性。知识库越完备、越准确那么对你被控对像的状态识别也就越准确。当然,推理机设计的差别也会对控制结果有影响。

  专家控制器一般来说分为2中实现形式,被称之为直接型专家控制器和间接型专家控制器。所谓直接型专家控制器就是用专门设计的专家控制器直接对被控对象进行控制的方法。该控制器任务和功能都比较简单,一般都是实时在线运行,直接对被控对象进行控制。其结构图如下:

  而所谓间接型专家控制器是指专家控制器作为其他控制器的辅助方式或者相互结合的控制方式来实现的一种控制器。专家系统通过高层决策来影响控制器输出,而这种高层决策可以是在线也可以是离线,器不会直接控制被控对象。其结构图如下:

  所以我们所要讨论的专家PID算法应该是一种直接型专家控制器,因为专家系统决策与PID算法是结合在一起的,并没有独于PID算法的专家控制器,而是专家决策直接决定PID算法机器输出,这与直接型专家控制的定义是相符的。

2、专家PID的设计思路(  控制规则(规则))

  专家PID控制就是基于被控对象和控制规律的各种知识,而不需要知道被控对象的精确模型,利用专家经验来设计PID参数。怎么来实现这一过程呢?我们来分析并推导这一算法。

  我们假设当前为第k采样,当前偏差为e(k),同样前一采样时刻的偏差为e(k-1),而前两个采样时刻的偏差为e(k-1),则可以得到两次的偏差增量为:

  清楚了以上公式,我们再设定偏差的一个极大值,记为Mmax;设定一个偏差较大的中间值,记为Mmid;设定一个偏差的极小值,记为Mmin。根据以上偏差、偏差增量以及偏差极值的设定,我们分析如下:

规则一:

1)如果|e(k)|>Mmax

  这种情况说明偏差的绝对值已经很大了,不论偏差变化趋势如何,都应该考虑控制器的输入应按最大(或最小)输出,以达到迅速调整偏差的效果,使偏差绝对值以最大的速度减小。

  这种情况下其实相当于实施开环控制,是一种对偏差出现极限情况的快速响应。

2)如果|e(k)|≤Mmax

  这种情况我们需要更具系统的变化趋势来分析,具体的情况实施不同的控制方式,我们引入偏差增量来协助分析。

规则二:

2.1)当e(k)*e(k)>0或者e(k)=0

  这种情况说明偏差在朝向偏差绝对值增大的方向变化,或者偏差为某一固定值,此时我们再判断偏差的绝对值与偏差的中间值Mmid之间的关系。

  • (2.1.1)此时如果|e(k)|>Mmid说明偏差也较大,可考虑由控制器实施较强的控制作用,以达到扭转偏差绝对值向减小的方向变化,并迅速减小偏差的绝对值。

  • (2.1.2)此时如果|e(k)|≤Mmid,说明尽管偏差是向绝对值增大的方向变化,但是偏差绝对值本身并不是很大,可以考虑控制器实施一般的控制作用,只需要扭转偏差的变化趋势,使其向偏差绝对值减小的方向变化即可。

规则三:

(2.2)当e(k)*∆e(k)<0且∆e(k)*∆e(k-1)>0或者e(k)=0时,说明偏差的绝对值向减小的方向变化,或者已经达到平衡状态,此时保持控制器输出不变即可。即:U(k)=U(k-1)。

规则四:

(2.3)当e(k)*∆e(k)<0且∆e(k)*∆e(k-1)<0时,说明偏差处于极限状态。如果此时偏差的绝对值较大,|e(k)|>Mmid,可以考虑实施较强控制作用。

  如果此时偏差绝对值较小,|e(k)|<Mmid,可以考虑实施较弱控制作用。

  其中,k1为增益放大系数,k1取大于1的值;k2为增益抑制系数,取大于0而小于1的值。

规则五:

3)如果|e(k)|<Mmin

  这种情况实际上说明偏差绝对值很小,这种偏差有可能是系统静差引起的,此时必须要引入积分作用,实施PID控制或者PI控制。

  Kp和Ki可以适当减小,以减小控制作用。当偏差小到一定程度后,甚至可以引入死区的概念,是系统稳定下来而不需要去进行调节。

3、专家PID算法实现

  前面我们了解了专家PID控制器的基本原理,并分析了一个较为常见的专家PID的控制规则。分析规则的过程其实也是一个推理的基本过程,所以我们得到了基本的规则库同时也有相应的推理机,接下来我们就来实现这一算法。

  首先定义一个专家PID的结构体对象:

 1 #include <stdio.h>
2
3 /*定义结构体和公用体*/
4 typedef struct
5 {
6 float setpoint; /*设定值*/
7 float kp; /*比例系数*/
8 float ki; /*积分系数*/
9 float kd; /*微分系数*/
10 float lasterror; /*前一拍偏差*/
11 float preerror; /*前两拍偏差*/
12 float result; /*PID控制器结果*/
13 float output; /*输出值,0-100,为百分比值*/
14 float maximum; /*输出值上限*/
15 float minimum; /*输出值下限*/
16 float errorabsmax; /*偏差绝对值最大值*/
17 float errorabsmid; /*偏差绝对值中位值*/
18 float errorabsmin; /*偏差绝对值最小值*/
19 }EXPERTPID;
20
21 //控制器 在上面分析的基础上我们很容易写出来一个专家PID的控制器如下:
22 void ExpertPID(EXPERTPID *vPID, float pv)
23 {
24 float thiserror;
25 float deltaerror;
26 float lastdeltaerror;
27 float result;//本次调节输出值
28
29 thiserror = vPID->setpoint - pv;
30 deltaerror = thiserror - vPID->lasterror;
31 lastdeltaerror = vPID->lasterror - vPID->preerror;
32
33 if (abs(thiserror) >= vPID->errorabsmax)
34 {/*执行规则1*/
35 if (thiserror > 0)
36 {
37 result = vPID->maximum;
38 }
39
40 if (thiserror < 0)
41 {
42 result = vPID->minimum;
43 }
44 }
45
46 if ((thiserror*deltaerror > 0) || (deltaerror == 0))
47 {/*执行规则2*/
48
49 if (abs(thiserror) >= vPID->errorabsmid)
50 {
51 result = vPID->result + 2.0*(vPID->kp*deltaerror + vPID->ki*thiserror + vPID->kd*(deltaerror - lastdeltaerror));
52 }
53 else
54 {
55 result = vPID->result + 0.4*(vPID->kp*deltaerror + vPID->ki*thiserror + vPID->kd*(deltaerror - lastdeltaerror));
56 }
57 }
58
59 if (((thiserror*deltaerror < 0) && (deltaerror*lastdeltaerror > 0)) || (thiserror == 0))
60 {/*执行规则3*/
61 result = vPID->result;
62 }
63
64 if ((thiserror*deltaerror < 0) && (deltaerror*lastdeltaerror < 0))
65 {/*执行规则4*/
66 if (abs(thiserror) >= vPID->errorabsmid)
67 {
68 result = vPID->result + 2.0 * vPID->kp * thiserror;
69 }
70 else
71 {
72 result = vPID->result + 0.6 * vPID->kp * thiserror;
73 }
74 }
75
76 if ((abs(thiserror) <= vPID->errorabsmin) && (abs(thiserror) > 0))
77 {/*执行规则5*/
78 result = vPID->result + 0.5*vPID->kp*deltaerror + 0.3*vPID->ki*thiserror;
79 }
80
81 /*对输出限值,避免超调*/
82 if (result >= vPID->maximum)
83 {
84 result = vPID->maximum;
85 }
86
87 if (result <= vPID->minimum)
88 {
89 result = vPID->minimum;
90 }
91
92 vPID->result = result;
93 vPID->preerror = vPID->lasterror;
94 vPID->lasterror = thiserror;
95 vPID->output = (result / (vPID->maximum - vPID->minimum)) * 100;
96 }

专家PID应用举例

设置输入为200,观察输出

  1 #include <stdio.h>
2 #include <math.h>
3
4 /*定义结构体和公用体*/
5 typedef struct
6 {
7 float setpoint; /*设定值*/
8 float kp; /*比例系数*/
9 float ki; /*积分系数*/
10 float kd; /*微分系数*/
11 float lasterror; /*前一拍偏差*/
12 float preerror; /*前两拍偏差*/
13 float result; /*PID控制器结果*/
14 float output; /*输出值,0-100,为百分比值*/
15 float maximum; /*输出值上限*/
16 float minimum; /*输出值下限*/
17 float errorabsmax; /*偏差绝对值最大值*/
18 float errorabsmid; /*偏差绝对值中位值*/
19 float errorabsmin; /*偏差绝对值最小值*/
20 }EXPERTPID;
21
22 int i = 0; // 测第几次调试设置值
23 float result = 0.0; //本次的输出值 设置成全局变量 在内部设置需要初始化,而每次循环都会初始化,有时会影响结果
24
25 void ExpertPID(EXPERTPID *vPID, float pv)
26 {
27 float thiserror;
28 float deltaerror;
29 float lastdeltaerror;
30 //float result ;//本次调节输出值
31 printf("ExpertPid第%d次调节\n", i);
32 printf("setpoint = %f\n", vPID->setpoint);
33 printf("pv = %f\n", pv);
34 thiserror = vPID->setpoint - pv;
35 deltaerror = thiserror - vPID->lasterror;
36 lastdeltaerror = vPID->lasterror - vPID->preerror;
37 printf("abs(thiserror) = %f\n", thiserror);
38 //printf("vPID->errorabsmax = %f", vPID->errorabsmax);
39 if (fabs(thiserror) >= vPID->errorabsmax)
40 {/*执行规则1*/
41 if (thiserror > 0)
42 {
43 result = vPID->maximum;
44 }
45
46 if (thiserror < 0)
47 {
48 result = vPID->minimum;
49 }
50 }
51
52 if ((thiserror*deltaerror > 0) || (deltaerror == 0))
53 {/*执行规则2*/
54
55 if (fabs(thiserror) >= vPID->errorabsmid)
56 {
57 result = vPID->result + 2.0*(vPID->kp*deltaerror + vPID->ki*thiserror + vPID->kd*(deltaerror - lastdeltaerror));
58 }
59 else
60 {
61 result = vPID->result + 0.4*(vPID->kp*deltaerror + vPID->ki*thiserror + vPID->kd*(deltaerror - lastdeltaerror));
62 }
63 }
64
65 if (((thiserror*deltaerror < 0) && (deltaerror*lastdeltaerror > 0)) || (thiserror == 0))
66 {/*执行规则3*/
67 result = vPID->result;
68 }
69
70 if ((thiserror*deltaerror < 0) && (deltaerror*lastdeltaerror < 0))
71 {/*执行规则4*/
72 if (fabs(thiserror) >= vPID->errorabsmid)
73 {
74 result = vPID->result + 2.0 * vPID->kp * thiserror;
75 }
76 else
77 {
78 result = vPID->result + 0.6 * vPID->kp * thiserror;
79 }
80 }
81
82 if ((fabs(thiserror) <= vPID->errorabsmin) && (abs(thiserror) > 0))
83 {/*执行规则5*/
84 result = vPID->result + 0.5*vPID->kp*deltaerror + 0.3*vPID->ki*thiserror;
85 }
86
87 /*对输出限值,避免超调*/
88 if (result >= vPID->maximum)
89 {
90 result = vPID->maximum;
91 }
92
93 if (result <= vPID->minimum)
94 {
95 result = vPID->minimum;
96 }
97
98 vPID->result = result;
99 vPID->preerror = vPID->lasterror;
100 vPID->lasterror = thiserror;
101 vPID->output = (result / (vPID->maximum - vPID->minimum)) * 100;
102 i++;
103 }
104
105 void PID_init(EXPERTPID *vPID)
106 {
107 printf("PID_init begin \n");
108 vPID->setpoint = 200.0; //设定值
109
110 vPID->kp = 0.2; //比例系数
111 vPID->ki = 0.15; //积分系数
112 vPID->kd = 0.2; //微分系数
113 vPID->lasterror = 0.0; //前一拍偏差
114 vPID->preerror = 0.0; //前两拍偏差
115 //死区
116 vPID->result = 190.0; //输出值
117 vPID->maximum = 200.0;
118 vPID->minimum = -200.0;//偏差检测阈值
119 vPID->errorabsmax = 180.0;
120 vPID->errorabsmid = 100.0;
121 vPID->errorabsmin = 20.0;
122 printf("PID_init end \n");
123 }
124
125 int main()
126 {
127 printf("System begin \n");
128 EXPERTPID vPID;
129 PID_init(&vPID);
130 int cout = 1000;
131 132 ExpertPID(&vPID, 180.0);
133 while (cout)
134 {
135 ExpertPID(&vPID, vPID.result);
136 printf("————最终结果--------\n");
137 printf("%f\n", vPID.result);
138 cout--;
139 printf("-----------------------\n\n");
140 }
141 return 0;
142 }

专家PID的更多相关文章

  1. PID控制器开发笔记之十一:专家PID控制器的实现

    前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...

  2. 专家PID控制

    1.专家PID控制原理 PID专家控制的实质是,基于受控对象和控制规律的各种知识,无需知道被控对象的精确模型,利用专家经验来设计PID参数.专家PID控制是一种直接型专家控制器. 典型的二阶系统单位阶 ...

  3. PID控制算法的C语言实现十 专家PID与模糊PID的C语言实现

    本节是PID控制算法的C语言实现系列的最后一节,前面8节中,已经分别从PID的实现到深入的过程进行了一个简要的讲解,从前面的讲解中不难看出,PID的控制思想非常简单,其主要问题点和难点在于比例.积分. ...

  4. 专家PID控制仿真学习

    目录 专家控制 专家系统 专家控制 学习笔记,用于记录学习 资料:<智能控制>(第四版)--刘金琨 专家系统 一.专家系统的定义 专家系统是一类包含知识和推理的智能计算机程序,其内部包含某 ...

  5. 四轴飞行器1.5 各种PID对比分析及选择

    原创文章,欢迎转载,转载请注明出处 这篇文章主要介绍我对PID的理解,以及选择PID算法的过程. 一 PID的理解和学习过程 二 飞控的PID效果 先上个飞控PID的响应的视频:介绍在后面 地址:ht ...

  6. PID控制算法的C语言实现十一  模糊算法简介

    在PID控制算法的C语言实现九中,文章已经对模糊PID的实质做了一个简要说明.本来打算等到完成毕业设计,工作稳定了再着力完成剩下的部分.鉴于网友的要求和信任,抽出时间来,对模糊PID做一个较为详细的论 ...

  7. PID控制算法的C语言实现

    参考: PID控制器开发笔 浅谈位置式PID 专家PID控制在快速系统中的仿真及应用(这篇了论文介绍的积分分离PID.专家PID(脚本实现和simulink实现)很详细) PID控制算法的C语言实现一 ...

  8. 两轮自平衡小车双闭环PID控制设计

                                                                                            两轮自平衡小车的研究意义 ...

  9. [译]GC专家系列2:Java 垃圾回收的监控

    原文链接:http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/ 这是"成为GC专家系 ...

随机推荐

  1. Docker入坑系列(一)

    Docker入坑系列(一) 引用嘛,当然是来引用别人说的东西啦. Docker 是一个开源项目,诞生于 2013 年初,它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux ...

  2. SVN库文件上传操作步骤

    SVN库文件上传步骤: 1,sv st  或 svn status  查看本地库与远程库的差别(M代表文件有修改,?代表目录中有文件本地新增加) 2,根据1步骤中的查看结果:svn diff  差异文 ...

  3. Spring系列20:注解详解和Spring注解增强(基础内功)

    有部分小伙伴反馈说前面基于注解的Spring中大量使用注解,由于对Java的注解不熟悉,有点难受.建议总结一篇的Java注解的基础知识,那么,它来了! 本文内容 什么是注解? 如何定义注解 如何使用注 ...

  4. laravel redis操作大全

    字符串操作 普通得set/get操作,set操作,如果键名存在,则会覆盖原有得值 $redis = app("redis.connection"); $redis->set( ...

  5. mixin混入

    mixin(混入) 功能:可以把多个组件共用的配置提取成一个混入对象 使用方式: 第一步定义混合,例如: { data(){.........}, methods:{.........} ...... ...

  6. 36 异常机制 自定义异常 实际应用中的经验总结 尽量添加finally语句块去释放占用的资源

    自定义异常 概念 使用Java内置的异常可以描述在编辑时出现的大部分异常情况.除此之外,用户还可以自定义异常.用户自定义异常类,只需继承Exception类即可. 在程序中使用自定义异常类,大体可分为 ...

  7. 全量、增量数据在HBase迁移的多种技巧实践

    作者经历了多次基于HBase实现全量与增量数据的迁移测试,总结了在使用HBase进行数据迁移的多种实践,本文针对全量与增量数据迁移的场景不同,提供了1+2的技巧分享. HBase全量与增量数据迁移的方 ...

  8. LGP6694题解

    第一眼似乎很困难,实际上非常简单( 好吧这题我做了一个小时( 首先期望具有线性性,我们转化为计算点对对答案的贡献. 发现相对位置一样的点对对答案的贡献是一样的.我们把相对位置一样的点对铃出来,乘了之后 ...

  9. 《Shader入门精要》第11章-11.3.1流动的河流中的offset.x的解释

    在我学习入门精要的时候,经常遇到不解释api,甚至是关键代码的实现原理. 11.3.1流动的河流中的offset.x的sin函数查了一下好像大家也都是书上原话直接复制,现在好不容易想明白了希望能帮到和 ...

  10. CSS 选择器学习总结

    1.id 选择器 #idname{color:red;} 2.class选择器 .classname{} 3.标签选择器 div{} 4.通配符选择器 *{} 5. 属性选择器 [id]{ } 5.选 ...