PID算法分为两种:
位置式PID
增量式PID
位置式PID算的是当前控制系统应该输出的值,增量式PID算的是当前控制系统该输出值的变化值。
以下仅介绍增量式PID。
PID公式解析
PID公式:
u(t)输出曲线,pid输出值随时间的变化曲线
K_p比例系数
e(t)偏差曲线,设定值与实际值的偏差随时间的变化曲线
T_i积分时间
T_d微分时间
Kp比例系数放到括号外面:
比例: P = K_p
积分: I = K_p*{1\over T_i}
微分: P = K_p*T_d
int_0^t e(t)dt是求时间0到时间t,偏差曲线e(t)与X轴围起来的面积值的代数和
de(t) \over dt求偏差曲线e(t)的斜率
即:
偏差=设定值-实际值,因此偏差曲线e(t)=SET-实际值曲线,也就是实际值曲线的x轴向上平移SET便是误差曲线e(t)。
根据高等数学的知识我们可以知道,在曲线SET下围成的面积为正的,在上面围成的面积为负的,即:面积A和面积C符号为正面积B符号为负,假设P、I、D都不为零,且都大于零。
可以发现:
比例项是纠正偏差的主力,越远离偏差绝对值就越大,快速把偏差纠正回来。
积分项和以往的状态有关,面积的绝对值越大它的绝对值就越大,它的作用是消除累计偏差。
微分项跟斜率有关,比较难解释,总的来说它的作用是:当目标靠近设定值时加速它靠近,当目标远离设定值时阻止它远离。因此微分可以增加系统稳定性,因为到达目的之后,离开会受到阻碍。
PID公式离散化
因为实际应用中我们用到的都是离散的数据,因此对PID进行编程之前我们得先把模拟公式转换成离散公式。
其实就是把积分求面积、微分求斜率的方法换成离散的求面积和斜率的方法,离散转换后:
其中:
u_k输出曲线,pid输出值随时间的变化曲线
K_p比例系数
e_k偏差曲线,设定值与实际值的偏差随时间的变化曲线
T_i积分时间
T_d微分时间
T调节周期
离散化后,多了参数T。
如果T为定值,则:
换算后公式:
如果T不为定值,则换算后公式:
C语言实现
#define I_MAX 100.0
#define I_MIN -100.0
float kP = 0;
float kI = 0;
float kD = 0;
float PID(float current, float target)
{
static float iValue = 0;
static float errorLast = 0;
float pValue, dValue;
float error = target - current; //误差
pValue = kP * error; //比例值
iValue = iValue + kI * error; //积分值
if (iValue >= I_MAX) //积分限幅,可选
iValue == I_MAX;
if (iValue <= I_MIN)
iValue = I_MIN;
dValue = (error - errorLast) * kD; //微分值
errorLast = error; //记录上一次误差
}
void MainPIDHandler_10ms()
{
float target = 0; //设定目标值
float current = 0; //获取当前值
float out = PID(current, target); //计算执行量
}
致敬:PID公式通俗理解_灵魂Maker的博客-CSDN博客_pid公式
附: