PID的概念
- Proportion(比例)——对输入偏差乘以一个常数
P的作用是以最快的速度达到目标值 - Integral (积分)——对输入偏差进行积分运算
I是使误差为0而起调和作用 - Derivative(微分)——对输入偏差进行微分运算
D是加快调节过程的作用
PID的分类
- 增量式
增量式的位置输出并不是绝对数值,而是一个△,代表增多少,减多少。 - 位置式
位置式PID的输出与过去的所有状态有关,计算时要对e(每一次的控制误差)进行累加。
PID参数的整定
- 经验试凑口诀:
参数整定找最佳, 从小到大顺序查。
先是比例后积分, 最后再把微分加。
曲线振荡很频繁, 比例度盘要放大。
曲线漂浮绕大弯, 比例度盘往小扳。
曲线偏离回复慢, 积分时间往下降。
曲线波动周期长, 积分时间再加长。
曲线振荡频率快, 先把微分降下来。
动差大来波动慢, 微分时间应加长。
理想曲线两个波, 前高后低四比一。
一看二调多分析, 调节质量不会低。
Note:PID控制并不一定要三者都出现,也可以只是PI、PD控制,关键决定于控制的对象。
代码中理解PID
- 定义PID结构体并进行初始化
extern PID_Type PID_steer; //全局
typedef struct
{
float Kp;
float Ki;
float Kd;
float dst; //目标控制位置
float cur; //当前控制位置
float error_k; //当前误差
float error_k1; //前一次控制误差
float error_i; //误差积分
float error_k2; //前前次控制误差(只适用于增量式PID)
}PID_Type;
PID_Type PID_steer; //声明
void PID_INIT(PID_Type* p,float Kp,float Ki,float Kd)
{
p->Kp = Kp;
p->Ki = Ki;
p->Kd = Kd;
p->cur = 0;
p->dst = 0;
p->error_k = 0;
p->error_k1 = 0;
p->error_k2 = 0;
}
- 增量式
float PID_Increment_CALC(PID_Type* p)
{
float pid_real;
p->error_k = p->dst - p->cur; //当前误差
pid_real = p->Kp*(p->error_k-p->error_k1) + p->Ki*p->error_k + p->Kd*(p->error_k-2*p->error_k1+p->error_k2);
p->error_k2 = p->error_k1; //前前次无控制误差
p->error_k1 = p->error_k;
return pid_real;
}
- 位置式
float PID_Position_CALC(PID_Type* p)
{
float pid_real;
p->error_k = p->dst - p->cur; //calculate the error of dest and current
p->error_i += p->error_k;
pid_real = p->Kp*p->error_k + p->Ki*p->error_i + p->Kd*(p->error_k-p->error_k1);
p->error_k1 = p->error_k;
return pid_real;
}