增量式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个参数后正常使用。
PID结构体
位置式PID结构体比增量式PID结构体多了一个SumError成员,用于记录当前量与目标值的累积误差,位置式PID是不需要PrevError成员的。
LocPIDCalc函数
上述函数是位置式PID算法实现方法。首先求出目标值与当前量的偏差保存在iError变量中,这个偏差量亮中缓将作为位置式PID运算的比例项因子。把这个偏差值加到PID结构体成培闹员SumError计算累积误差,这个累敬模积误差将作为PID运算的积分项因子。把偏差值减去上次偏差值的结果作为PID运算的微分项因子。
数字PID位置型控制算式如下:u(k)=Kp[
e(k)
+??e(i)T/T??
+
Td(
e(k)-e(k)
)/T
]
Kp为比例增益,T为采样周此盯轿期,T??为积分森肆时间常数,Td为微分时间则敏常数,k采样序号,??为累加器(i从0到k),由于该控制算法提供了执行机构的位置u(k),如阀门的开度,所以被成为数字PID位置型控制算法。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)