一、什么是PID:
创新互联自2013年创立以来,先为新城等服务建站,新城等地企业,进行企业商务咨询服务。为新城企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
PID即:Proportional(比例)、Integral(积分)、Differential(微分)的缩写。顾名思义,PID控制算法是结合比例、积分和微分三种环节于一体的控制算法,它是连续系统中技术最为成熟、应用最为广泛的一种控制算法,该控制算法出现于20世纪30至40年代,适用于对被控对象模型了解不清楚的场合。 ---百度百科
二、PID是否难学:
在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。 ---【1】
三、PID算法的C语言源码:
PID 控制算法可以分为位置式 PID 和增量式 PID 控制算法
详细见参考【1】【2】
参考:
【1】PID算法
【2】简易PID算法的快速扫盲(超详细+过程推导+C语言程序)
#includeunistd.h
#includestdio.h
int main(int argc,int **argv)
{
int pid=fork();
if(pid==-1)
{
printf("error");
}
else if(pid==0)
{
printf("This is the child process!\n");
}
else
{
printf("This is the parent process! child process id=%d\n",pid);
}
return 0;
}
首先为什么这段代码gcc编译不了,只能用g++编译,gcc编译显示结果如下
Undefined first referenced
symbol in file
__gxx_personality_v0 /var/tmp//ccuHN8IS.o
ld: fatal: Symbol referencing errors. No output written to t5
collect2: ld returned 1 exit status
其次,g++编译后运行结果如下
This is the parent process! child process id=27406
This is the child process!
基本流程
积分环节:主要是用来消除 静差 (系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累积的过程,把累积的误差加到原来系统上以抵消系统造成的静差)
微分环节:反映了偏差信号的变化规律,根据偏差信号的变化规律来进行超前调节,从而增加系统的快速性
对上述公式进行离散化(采样):两个公式
增量型PID:
通过增量型PID公式可以看出,最终表达结果和最近三次的偏差有关,最终输出结果应该为:
首先定义结构变量体:
然后初始化变量
最后编写控制算法
基本算法,没有考虑死区问题,没有设定上下限
在启动、结束或大幅度增减设定时,短时间内系统输出有很大的偏差,会造成PID运算的积分积累,导致控制量超过执行机构可能允许的最大动作范围对应的极限控制量,从而引起较大的超调,甚至是振荡。
为了克服这个问题,引入积分分离的概念,即当被控量和设定值偏差较大时,取消积分作用;当被控量接近设定值时,引入积分控制,以消除静差,提高精度。
abs :绝对值
令index=0使积分环节失效
积分饱和现象:如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置。此时计算器输出量超出正常运行范围而进入饱和区,一旦系统出现反向偏差,输出量将逐渐从饱和区退出,进入饱和区越深则退出饱和区时间越长,在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应改变,造成性能恶化。
采用梯形积分能够减小余差,提高精度
改变积分系数,若偏差大,积分作用减弱,系数减小;若偏差小,积分作用增强,系数增大。
变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小对应。
使整个系统的稳定速度非常快
比例系数Kp的作用是加快系统的响应速度提高系统的调节精度
积分系数Ki的作用是消除系统的稳态误差
微分系数Kd的作用是改善系统的动态特性
反应系统性能的两个参数是系统误差和误差变化律
就是一般的排序算法,与查找算法一样,这个的都不会吗floata[3],max=0;for(i=0;i=2;i++){printf("Pleaseenterthemark:");scanf("%f",a[i]);if(maxintsort(intnum[5]);voidmain(){intnumm[5],i,a;for(i=0;i5;i++)scanf("%d",numm[i]);sort(numm);//调用排序for(i=0;i5;i++)printf("%d",numm[i]);}intsort(intnum[5]){intm,n,t;for(m=0;m4;m++)for(n=m+1;n5;n++)//冒泡排序{if(num[m]