PID积分饱和 和 积分分离

PID积分饱和 和 积分分离

1.积分饱和:积分是当前误差的累加ei_sum=ei_sum +err_now;积分饱和则是当你pid输出到了你想要的最大值,但存在外界干扰造成err_now当前误差仍然存在。这时积分还在不断增加,pid输出最大值不变,如果在该时刻你想要降低pid输出,就不会得到立马响应,要消除刚刚一直在加得积分积分饱和通俗讲就是系统在一个偏差方向上的饱和,比如一个系统设定了输出不会超过100,但因为出现一个方向上的偏差积分使得输出超过了100,此时达到了饱和状态,如果继续在这个方向上积分会导致PID控制超过100系统却运行在100,相当于积分调节对系统输出没有作用,就出现失控的状态,这是系统不能接受的,而且饱和积分越深,退出饱和就越久。上面是在正向的饱和,负向的饱和类似!

2.积分分离:在系统正常情况下,如果你突然设置目标值太大即err_now=(set_value-now_value)太大,这时积分一下就迅速增大,会造成系统不和谐。如刚开机时,误差就特别大。

3.解决方案:积分饱和是当你积分累加过大时,选择不累加下次积分,当出现反向积分时则累加。
积分分离是当你当前误差太大时,选择不使用积分。增量式pid没有积分,绝对式pid才有积分.

4.代码

PID speed;//PID结构体

float speed_pid()
{
	u8 index=0;
	
	//速度输入限幅
	if(speed.f_set >=200.0) {speed.f_set =200.0;}
	if(speed.f_set <=-200.0){speed.f_set =-200.0;}
	
	speed.err_now = speed.f_set - speed.f_now;//err_now=float设置值 - float当前值
	
	if(speed.ei_sum>=speed.umax) //正向积分饱和处理  speed.umax这个值需要根据自己的系统调出
	{
			if(fabsf(speed.err_now)>speed.err_now_max) //积分分离  speed.err_now_max这个值需要根据自己的系统调出
			{
				index=0;//当误差大于speed.err_now_max 舍弃积分
			}
			else
			{
				index=1;
				if(speed.err_now<0) //当误差小于speed.err_now_max时,且是反向积分则积分累加否则不加
				speed.ei_sum = speed.ei_sum + speed.err_now;
			}
	}
	else if(speed.ei_sum<-speed.umin) //负向积分饱和处理  speed.umin这个值需要根据自己的系统调出
	{
			if(fabsf(speed.err_now)>speed.err_now_max) //积分分离  speed.err_now_max这个值需要根据自己的系统调出
			{
				index=0;//当误差大于speed.err_now_max 舍弃积分
			}
			else
			{
				index=1;
				if(speed.err_now>0) //当误差小于speed.err_now_max时,且是反向积分则积分累加否则不加
				speed.ei_sum = speed.ei_sum + speed.err_now;
			}
	}
	else//积分正常不饱和
	{
			if(fabsf(speed.err_now)>speed.err_now_max) //积分分离
			{
				index=0;//当误差大于speed.err_now_max 舍弃积分
			}
			else
			{
				index=1;
				speed.ei_sum = speed.ei_sum + speed.err_now;//积分不处于饱和状态,积分正常累加
			}
	}
	
	//标准绝对式  pwm_temp = P*err + i*(ei+=err) + d*(e_now-e_old);
	speed.value_out = speed.Kp*speed.err_now
					  + speed.Ki*speed.ei_sum*index
					  + speed.Kd*(speed.err_now -speed.err_next);
				
    speed.err_next = speed.err_now;//上次偏差
	
	//pid输出限幅
	if(speed.value_out>=32000.0) {speed.value_out=32000;}
	if(speed.value_out<=-32000.0){speed.value_out=-32000;}
	
	return (speed.value_out); //最终输出值
	}
  • 14
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值