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

改进式PID控制

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

         积分项的改进

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

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

1.      积分分离法:

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

 

2.      抗积分饱和法:

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

算法案例如下:

/*
	积分分离的pid控制算法c语言实现
	系统所用时间是原来时间的一半
	系统的快速性得到了提高
*/

#include<stdio.h>
#include<stdlib.h>

struct _pid{
	float SetSpeed; 		//定义设定值	//24V   1100-1900
	float ActualSpeed; 		//定义实际值
	float err; 				//定义偏差值
	float err_last; 		//定义上一个偏差值
	float Kp,Ki,Kd; 		//定义比例、积分、微分系数
	float voltage; 			//定义电压值(控制执行器的变量)
	float integral;		    //定义积分值
}pid;

//项目中获取到的参数
void PID_init(){
	printf("PID_init begin \n");
	pid.SetSpeed=0.0;
	pid.ActualSpeed=0.0;
	pid.err=0.0;
	pid.err_last=0.0;
	pid.voltage=0.0;
	pid.integral=0.0;
	pid.Kp=0.2;				//自己设定
	pid.Ki=0.04;			//自己设定
	pid.Kd=0.2;				//自己设定
	printf("PID_init end \n");
}


float PID_realize(float speed){
	pid.SetSpeed=speed;						//设定值
	pid.err=pid.SetSpeed-pid.ActualSpeed;	//设定值-实际值
	int index;
	if(abs(pid.err)>200)
	{
		index=0;
	}else{
		index=1;
		pid.integral+=pid.err;
	}
	pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.
	err-pid.err_last); //算法具体实现过程
	
	pid.err_last=pid.err;					//上一个偏差值
	pid.ActualSpeed=pid.voltage*1.0;		//算出实际值
	return pid.ActualSpeed;					//返回
}

int main(){
	PID_init();
	int count=0;
	while(count<1000)
	{
	float speed=PID_realize(200.0);
	printf("%f\n",speed);
	count++;
	}
	return 0;
}


/*
	抗击分饱和的pid控制算法
	
*/

#include<stdio.h>
#include<stdlib.h>
struct _pid{
	float SetSpeed; //定义设定值
	float ActualSpeed; //定义实际值
	float err; //定义偏差值
	float err_last; //定义上一个偏差值
	float Kp,Ki,Kd; //定义比例、积分、微分系数
	float voltage; //定义电压值(控制执行器的变量)
	float integral; //定义积分值
	float umax;
	float umin;
}pid;

void PID_init(){
	printf("PID_init begin \n");
	pid.SetSpeed=0.0;
	pid.ActualSpeed=0.0;
	pid.err=0.0;
	pid.err_last=0.0;
	pid.voltage=0.0;
	pid.integral=0.0;
	pid.Kp=0.2;
	pid.Ki=0.1; //注意,和上几次相比,这里加大了积分环节的值
	pid.Kd=0.2;
	pid.umax=400;
	pid.umin=-200;
	printf("PID_init end \n");
}

float PID_realize(float speed){
	int index;
	pid.SetSpeed=speed;
	pid.err=pid.SetSpeed-pid.ActualSpeed;
	if(pid.ActualSpeed>pid.umax) //灰色底色表示抗积分饱和的实现
	{
		if(abs(pid.err)>200) //蓝色标注为积分分离过程
		{
		index=0;
		}else{
			index=1;
			if(pid.err<0)
			{
			pid.integral+=pid.err;
			}
		}
	}else if(pid.ActualSpeed<pid.umin){
		if(abs(pid.err)>200) //积分分离过程
		{
			index=0;
		}else{
			index=1;
			if(pid.err>0)
			{
				pid.integral+=pid.err;
			}
		}
	}else{
			if(abs(pid.err)>200) //积分分离过程
			{
				index=0;
			}else{
				index=1;
				pid.integral+=pid.err;
			}
		}
//	pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last);//梯形积分
	pid.err_last=pid.err;
	pid.ActualSpeed=pid.voltage*1.0;
	return pid.ActualSpeed;
}

int main(){
	PID_init();
	int count=0;
	while(count<1000)
	{
	float speed=PID_realize(200.0);
	printf("%f\n",speed);
	count++;
	}
	return 0;
}




评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值