增量式PID指数字控制器的输出只是控制量的增量∆uk。当执行机构需要的控制量是增量,而不是位置量的绝对数值时,可以使用增量式PID控制算法进行控制。
1、公式推导:
增量式PID控制算法可以通过位置式PID公式推导出。
①:当前误差采样后的输出值
μ k = K p e k + K i ∑ j = 0 k e j + K d ( e k − e k − 1 ) \mu_{k} = K_{p}e_{k}+K_{i}\sum_{j=0}^{k}{e_{j}}+K_{d}(e_{k}-e_{k-1}) μk=Kpek+Kij=0∑kej+Kd(ek−ek−1)
②:上一次误差采样后的输出值
μ k − 1 = K p e k − 1 + K i ∑ j = 0 k − 1 e j + K d ( e k − 1 − e k − 2 ) \mu_{k-1} = K_{p}e_{k-1}+K_{i}\sum_{j=0}^{k-1}{e_{j}}+K_{d}(e_{k-1}-e_{k-2}) μk−1=Kpek−1+Kij=0∑k−1ej+Kd(ek−1−ek−2)
①-② 得出增量式PID的公式为:
Δ μ k = u k − u k − 1 = K p ( e k − e k − 1 ) + K i e k + K d ( e k − 2 e k − 1 + e k − 2 ) \Delta\mu_{k} = u_{k} - u_{k-1} =K_{p}(e_{k}-e_{k-1}) + K_{i}e_{k}+K_{d}(e_{k}-2e_{k-1}+e_{k-2}) Δμk=uk−uk−1=Kp(ek−ek−1)+Kiek+Kd(ek−2ek−1+ek−2)
简化后得:
Δ μ k = P ∗ e k − I ∗ e k − 1 + D ∗ e k − 2 \Delta\mu_{k} = P*e_{k}-I*e_{k-1}+D*e_{k-2} Δμk=P∗ek−I∗ek−1+D∗ek−2
2.代码实现:
/********************结构体定义********************/
typedef struct
{
__IO int32_t SetPoint; //设定目标 Desired Value
__IO float Proportion; //比例常数 Proportional Const
__IO float Integral; //积分常数 Integral Const
__IO float Derivative; //微分常数 Derivative Const
__IO int LastError; //Error[-1]
__IO int PrevError; //Error[-2]
}PID_TypeDef;
/********************PID参数初始化********************/
PID_TypeDef sPID; // PID参数结构体
void PID_ParamInit()
{
sPID.LastError = 0; // Error[-1]
sPID.PrevError = 0; // Error[-2]
sPID.Proportion = 0; // 比例常数 Proportional Const
sPID.Integral = 0; // 积分常数 Integral Const
sPID.Derivative = 0; // 微分常数 Derivative Const
sPID.SetPoint = 0; // 设定目标Desired Value
}
/********************PID算法实现********************/
/**
* 输入参数:当前控制量
* 返 回 值:目标控制量
*/
int32_t SpdPIDCalc(float NextPoint)
{
float iError,iIncpid;
iError = (float)sPID.SetPoint - NextPoint; //偏差
/* 消除抖动误差 */
if((iError<0.05f )&& (iError>-0.05f))
iError = 0.0f;
iIncpid=(sPID.Proportion * iError) //E[k]项
-(sPID.Integral * sPID.LastError) //E[k-1]项
+(sPID.Derivative * sPID.PrevError); //E[k-2]项
sPID.PrevError = sPID.LastError; //存储误差,用于下次计算
sPID.LastError = iError;
return(iIncpid); //返回增量值
}