PID比较分析

https://blog.youkuaiyun.com/qq_38833931/article/details/80630960
位置型PID:
out=pid.Kp * pid.err + pid.Ki * pid.integral + pid.Kd * (pid.err - pid.err_last);
输出值:= P * 偏差 + I * 累计偏差 + D * (偏差 - 上次偏差)
偏差和P值越大输出越大,越小输出越小,接近目标时输出变小.
I值和累计偏差在第一次接近目标值时是正向作用, 当前值大于目标值后, I值开始起反作用, I值在目标值和当前值过大时在多次采样后, 累计偏差可能会溢出.
D值对输出的影响极其微小, 真实值接近目标值, D值的作用会逐渐放大.

增量型PID:
out=pid.Kp*(pid.err-pid.err_next)+pid.Kipid.err+pid.Kd(pid.err-2pid.err_next+pid.err_last);
输出值:=P
(偏差-上次偏差)+I*(偏差)+D*(偏差-2*上次偏差+上上次偏差)
这种PID更合是目标值在匀速变化的,I值作用变小,P值作用变小, 出现震荡 作用放大, D值作用相对变大.

积分分离的PID:
if(abs(pid.err)>200)
{
index=0;
}else{
index=1;
pid.integral+=pid.err;
}
out=pid.Kppid.err+indexpid.Kipid.integral+pid.Kd(pid.err-pid.err_last)

输出:=P * 偏差 + I * 累计偏差 * 偏差控制 + D * (偏差 - 上次偏差)
偏差过大, 把积分作用取消.
有抗积分饱和做用, 偏差过大时 累计偏差 不介入 也不继续累计.

抗积分饱和:
pid.umax = 400;
pid.umin = -200;
speed = 200;
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;
	}
}

out = pid.Kppid.err + indexpid.Kipid.integral + pid.Kd(pid.err - pid.err_last);
输出:= P*偏差+积分分离控制 * I * 累计偏差 + D * (偏差 - 上次偏差).
pid.err_last = pid.err;
}
当前值大于大于上限小于下限积分分离策略改变, 是当前值最快速接近目标值.

梯形积分:
pid.voltage = pid.Kp * pid.err + index * pid.Ki * pid.integral / 2+ pid.Kd * (pid.err - pid.err_last)
输出:= P * 偏差 + I * 累计偏差/2 + D * (偏差 - 上次偏差 )

变积分:
变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。
这里给积分系数前加上一个比例值index:

当abs(err) < 180时,index = 1;

当180< abs(err) <200时,index=(200-abs(err))/20;

当abs(err) > 200时,index=0;
float PID_realize (float speed)
{
float index;
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed;

if(abs (pid.err) > 200)          //变积分过程
{
	index = 0.0;
}
else if (abs (pid.err) < 180)
{
    index = 1.0;
	pid.integral += pid.err;
}
else
{
index = (200 - abs (pid.err)) / 20;
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的应用最终还是需要用到实践中, 在实践中不同的领域会用不同的效果.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值