(1)滤波的选择:可以对输入加一个前置滤波器,使得进入控制算法的给定值不突变,而是有一定惯性延迟的缓变量。
(2)系统的动态过程加速:如果被控量继续偏离给定值,则这两项符号相同,而当被控量向给定值方向变化时,则这两项的符号相反。由于这一性质,当被控量接近给定值的时候,反号的比例作用阻碍了积分作用,因而避免了积分超调以及随之带来的振荡,这显然是有利于控制的。但如果被控量远未接近给定值,仅刚开始向给定值变化时,由于比例和积分反向,将会减慢控制过程。
2,PID增量算法的饱和作用及其抑制:在PID增量算法中,由于执行元件本身是机械或物理的积分储存单元,如果给定值发生突变时,由算法的比例部分和微分部分计算出的控制增量可能比较大,如果该值超过了执行元件所允许的最大限度,那么实际上执行的控制增量将时受到限制时的值,多余的部分将丢失,将使系统的动态过程变长,因此,需要采取一定的措施改善这种情况。
增量式PID:
typedef struct{float scope //输出限幅量
float aim //目标输出量
float real_out //实际输出量
float Kp
float Ki
float Kd
float e0 //当前误差
float e1 //上一次误差
float e2 //上上次误差
}PID_Type
#define min(a, b) (a<b? a:b)
#define max(a, b) (a>b? a:b)
#define limiter(x, a, b) (min(max(x, a), b))
#define exchange(a, b, tmp) (tmp=a, a=b, b=tmp)
#define myabs(x) ((x<0)? -x:x)
float pid_acc(PID_Type *pid)
{
float out
float ep, ei, ed
pid->e0 = pid->aim - pid->real_out
ep = pid->e0 - pid->e1
ei = pid->e0
ed = pid->e0 - 2*pid->e1 + pid->e2
out = pid->Kp*ep + pid->Ki*ei + pid->Kd*ed
out = limiter(out, -pid->scope, pid->scope)
pid->e2 = pid->e1
pid->e1 = pid->e0
return out
}
位置式PID:
typedef struct{float scope //输出限幅量
float aim //目标输出量
float real_out //反馈输出量
float Kp
float Ki
float Kd
float Sum
float e0 //当前误差
float e1 //上一次误差
}PID_Type
#define max(a, b) (a>b? a:b)
#define min(a, b) (a<b? a:b)
#define limiter(x, a, b) (min(max(x, a), b))
float pid_pos(PID_Type *p)
{
float pe, ie, de
float out = 0
p->e0 = p->aim - p->real_out //计算当前误差
p->Sum += p->e0 //误差积分
de = p->e0 - p->e1 //误差微分
pe = p->e0
ie = p->Sum
p->e1 = p->e0
out = pe*(p->Kp) + ie*(p->Ki) + de*(p->Kd)
out = limiter(out, -p->scope, p->scope) //输出限幅
return out
}
亲手移植到我的stm32小车上 调试3个参数后正常使用。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)