单片机实现增量式PID控制,求指点,有没有错误,为什么运行结果不对?
int error1=0;
int error2=0;
double kp=1;
double ki=0.1;
double kd=0.1;
int PID_control(unsigned int e)
{
int pid_output;
error0=e;
pid_output=(error0-error1)*kp-error0*ki+(error0-2*error1+error2)*kd;
pwm=pid_output*(1023/28.00);
error2=error1;
error1=error0;
return pid_output;
} 展开
公式错了
原式如下:
第二项为加
另外友情提示一下:这里的Kp,Ki,Kd不是真正的PID参数,这里的K们是离散后的常系数,不同的采样周期如果用相同的PID参数,离散后的K们不相同。所以建议写参数的时候用原始的PID参数。然后对应的计算离散后的K们。这样在调参数的时候直接调PID参数就行,不用考虑离散后的K们。而且参数辨识和建模仿真等一些操作中都是用的PID参数。
代码修改如下(参考):
float pid_output = 10; //初始化一个控制器输出
int error0=0;
int error1=0;
int error2=0;
double Kp=1; //PID中的P,越大系统响应越快
double Ti = 0.1; //积分时间常数,越小积分作用越强,系统响应越快,系统越不稳定
double Td = 0.1; //微分时间常数
double T = 0.1; //采样周期
double ki=Kp*T/Ti; //离散后常数
double kd=Kp*Td/T;
int PID_control(unsigned int e)
{
int pid_output;
error0=e;
delta=(error0-error1)*kp+error0*ki+(error0-2*error1+error2)*kd;
pid_output = delta; //原文中的(1023/28.00)直接考虑到PID参数中,无需单独乘
error2=error1;
error1=error0;
return pid_output;
}
上面函数中定义你的PID参数和采样周期后,对应的就可以算出离散后的Kp,Ki,Kd参与计算。调参数只需调PID参数和采样周期即可。
由上面公式可以看出,增量式PID当误差为0时,控制器输出也为零。这就要求执行机构有积分保持特性,你确定你的执行机构在控制器输出为零时,能保持输出吗?如果不能,则应该用位置式PID。
上面公式得到的只是增量,位置式输出是上一时刻的PID输出加上这个增量。即
u(k)=u(k-1)+Δu(k)