小明接到这样一个使命:
有一个水缸点漏水(并且漏水的速度还不必定固定不变),
要求水面高度维持在某个方位,
一旦发现水面高度低于要求方位,就要往水缸里加水。
小明接到使命后就一向守在水缸周围,
时刻长就觉得无聊,就跑到房里看小说了,
每30分钟来查看一次水面高度。水漏得太快,
每次小明来查看时,水都快漏完了,离要求的高度相差很远
,小明改为每3分钟来查看一次,成果每次来水都没怎样漏
,不需求加水,来得太频频做的是无用功。几回实验后,
确认每10分钟来查看一次。这个查看时刻就称为采样周期。
开端小明用瓢加水,水龙头离水缸有十几米的间隔,
常常要跑好几趟才加够水,所以小明又改为用桶加,
一加便是一桶,跑的次数少了,加水的速度也快了,
但好几回将缸给加溢出了,不小心弄湿了几回鞋,小明又动脑筋,
我不必瓢也不必桶,老子用盆,几回下来,发现刚刚好,不必跑太屡次,
也不会让水溢出。这个加水东西的巨细就称为份额系数。
小明又发现水尽管不会加过量溢出了,有时会高过要求方位比较多
,仍是有打湿鞋的风险。他又想了个方法,在水缸上装一个漏斗,
每次加水不直接倒进水缸,而是倒进漏斗让它渐渐加。这样溢出的问题解决了,
但加水的速度又慢了,有时还赶不上漏水的速度。
所以他试着改换不同巨细口径的漏斗来操控加水的速度
,最终总算找到了满足的漏斗。漏斗的时刻就称为积分时刻 。
小明总算喘了一口,但使命的要求忽然严了,
水位操控的及时性要求大大进步,一旦水位过低,
有必要立行将水加到要求方位,并且不能高出太多,不然不给工钱。
小明又为难了!所以他又开努脑筋,总算让它想到一个方法,常放一盆备用水在周围,
一发现水位低了,不通过漏斗便是一盆水下去,这样及时性是确保了,但水位有时会高多了。
他又在要求水面方位上面一点将水凿一孔,再接一根管子到下面的备用桶里这样多出的水会从上面的孔里漏出来。
这个水漏出的快慢就称为微分时刻。
大学年代做机器人时用的PID算法源代码:
#define PID_Uint struct pid_uint
PID_Uint
{
int U_kk;
int ekk;
int ekkk;
int Ur; //限幅输出值,需初始化
int Un; //不灵敏区
//int multiple; //PID系数的扩大倍数,用整形数据的情况下,进步PID参数的设置精度 固定为256
int Kp; //份额,从小往大调
int Ti; //积分,从大往小调
int Td; //微分,用巡线板时设为0
int k1; //
int k2;
int k3;
};
/********************************************************************
函 数 名:void Init_PID_uint(PID_uint *p)
功 能:初始化PID参数
说 明:调用本函数之前,应该先对Kp,Ti,Td做设置 ,简化了公式
进口参数:PID单元的参数结构体 地址
返 回 值:无
***********************************************************************/
void Init_PID_uint(PID_Uint *p)
{
p->k1=(p->Kp)+(p->Kp)*1024/(p->Ti)+(p->Kp)*(p->Td)/1024;
p->k2=(p->Kp)+2*(p->Kp)*(p->Td)/1024;
p->k3=(p->Kp)*(p->Td)/1024;
}
/********************************************************************
函 数 名:void reset_Uk(PID_Uint *p)
功 能:初始化U_kk,ekk,ekkk
说 明:在初始化时调用,改动PID参数时有或许需求调用
进口参数:PID单元的参数结构体 地址
返 回 值:无
***********************************************************************/
void reset_Uk(PID_Uint *p)
{
p->U_kk=0;
p->ekk=0;
p->ekkk=0;
}
/********************************************************************
函 数 名:int PID_commen(int set,int jiance,PID_Uint *p)
功 能:通用PID函数
说 明:求恣意单个PID的操控量
进口参数:期望值,实测值,PID单元结构体
返 回 值:PID操控量
***********************************************************************/
int PID_common(int set,int jiance,PID_Uint *p)
{
int ek,U_k=0;
ek=jiance-set;
if((ek>(p->Un))||(ekUn))) //积分不灵敏区
U_k=(p->U_kk)+(p->k1)*ek-(p->k2)*(p->ekk)+(p->k3)*(p->ekkk);
p->U_kk=U_k;
p->ekkk=p->ekk;
p->ekk=ek;
if(U_k>(p->Ur)) //约束最大输出量,
U_k=p->Ur;
if(U_kUr))
U_k=-(p->Ur);
return U_k/1024;
}