#include "PID.h" #define Motor_ECD_MAX 8192.0f /* *函数简介:位置式PID初始化结构体 *参数说明:位置式PID参数结构体 *参数说明:预期值 *返回类型:无 *备注:无 */ void PID_PositionStructureInit(PID_PositionInitTypedef* PID_InitStructure,float NeedValue) { PID_InitStructure->Need_Value=NeedValue; PID_InitStructure->Ek=0; PID_InitStructure->Ek_Sum=0; PID_InitStructure->Ek_Min=0; PID_InitStructure->Ek_Max=0; PID_InitStructure->Kp=0; PID_InitStructure->Ki=0; PID_InitStructure->Kd=0; PID_InitStructure->OUT_Min=0; PID_InitStructure->OUT_Max=0; } /* *函数简介:位置式PID设置参数 *参数说明:位置式PID参数结构体 *参数说明:单精度浮点型Kp *参数说明:单精度浮点型Ki *参数说明:单精度浮点型Kd *返回类型:无 *备注:无 */ void PID_PositionSetParameter(PID_PositionInitTypedef* PID_InitStructure,float kp,float ki,float kd) { PID_InitStructure->Kp=kp; PID_InitStructure->Ki=ki; PID_InitStructure->Kd=kd; } /* *函数简介:位置式PID设置误差为0阈值 *参数说明:位置式PID参数结构体 *参数说明:误差为0阈值下限 *参数说明:误差为0阈值上限 *返回类型:无 *备注:无 */ void PID_PositionSetEkRange(PID_PositionInitTypedef* PID_InitStructure,float Ek_Min,float Ek_Max) { PID_InitStructure->Ek_Min=Ek_Min; PID_InitStructure->Ek_Max=Ek_Max; } /* *函数简介:位置式PID设置输出限幅 *参数说明:位置式PID参数结构体 *参数说明:输出限幅下限 *参数说明:输出限幅上限 *返回类型:无 *备注:无 */ void PID_PositionSetOUTRange(PID_PositionInitTypedef* PID_InitStructure,float OUT_Min,float OUT_Max) { PID_InitStructure->OUT_Min=OUT_Min; PID_InitStructure->OUT_Max=OUT_Max; } void PID_PositionSetNeedValue(PID_PositionInitTypedef* PID_InitStructure,float NeedValue) { PID_InitStructure->Need_Value=NeedValue; } /* *函数简介:位置式PID清理 *参数说明:位置式PID参数结构体 *返回类型:无 *备注:使Ek和Sum为0 */ void PID_PositionClean(PID_PositionInitTypedef* PID_InitStructure) { PID_InitStructure->Ek=0; PID_InitStructure->Ek_Sum=0; } /* *函数简介:位置式PID计算 *参数说明:位置式PID参数结构体 *参数说明:当前值 *返回类型:无 *备注:OUT=POUT+IOUT+DOUT=Kp*Ek+Ki*ΣEk+Kd*(Ek-Ek_Last) *备注:计算结果保存在位置式PID参数结构体中 */ void PID_PositionCalc(PID_PositionInitTypedef* PID_InitStructure,float NowValue) { PID_InitStructure->Now_Value = NowValue; PID_InitStructure->Ek_Last = PID_InitStructure->Ek; PID_InitStructure->Ek = PID_InitStructure->Need_Value - PID_InitStructure->Now_Value; if(PID_InitStructure->Ek_Min < PID_InitStructure->Ek && PID_InitStructure->Ek < PID_InitStructure->Ek_Max)//误差为0检测 { PID_InitStructure->Ek = 0; } PID_InitStructure->Ek_Sum += PID_InitStructure->Ek; PID_InitStructure->Ek_Del = PID_InitStructure->Ek - PID_InitStructure->Ek_Last;//误差差分 if (PID_InitStructure->Ek_Sum > PID_InitStructure->OUT_Max) PID_InitStructure->Ek_Sum = PID_InitStructure->OUT_Max; else if (PID_InitStructure->Ek_Sum < PID_InitStructure->OUT_Min) PID_InitStructure->Ek_Sum = PID_InitStructure->OUT_Min; PID_InitStructure->P_OUT = PID_InitStructure->Kp * PID_InitStructure->Ek; PID_InitStructure->I_OUT = PID_InitStructure->Ki * PID_InitStructure->Ek_Sum; PID_InitStructure->D_OUT = PID_InitStructure->Kd * PID_InitStructure->Ek_Del; PID_InitStructure->OUT = PID_InitStructure->P_OUT + PID_InitStructure->I_OUT + PID_InitStructure->D_OUT; if(PID_InitStructure->OUTOUT_Min)//输出限幅 PID_InitStructure->OUT = PID_InitStructure->OUT_Min; if(PID_InitStructure->OUT>PID_InitStructure->OUT_Max) PID_InitStructure->OUT = PID_InitStructure->OUT_Max; } /* *函数简介:位置式PID计算 *参数说明:位置式PID参数结构体 *参数说明:当前值 *返回类型:无 *备注:OUT=POUT+IOUT+DOUT=Kp*Ek+Ki*ΣEk+Kd*(Ek-Ek_Last) *备注:计算结果保存在位置式PID参数结构体中 */ void PID_PositionCalc_Motor(PID_PositionInitTypedef* PID_InitStructure,float NowValue) { PID_InitStructure->Now_Value = NowValue; float err = PID_InitStructure->Need_Value - PID_InitStructure->Now_Value; if (err > 8192/2) { // 8192 / 2 = 4096 err -= 8192; } else if (err < -8192/2) { err += 8192; } PID_InitStructure->Ek_Last = PID_InitStructure->Ek; PID_InitStructure->Ek = err; if(PID_InitStructure->Ek_Min < PID_InitStructure->Ek && PID_InitStructure->Ek < PID_InitStructure->Ek_Max)//误差为0检测 { PID_InitStructure->Ek = 0; } PID_InitStructure->Ek_Sum += PID_InitStructure->Ek; PID_InitStructure->Ek_Del = PID_InitStructure->Ek - PID_InitStructure->Ek_Last;//误差差分 if (PID_InitStructure->Ek_Sum > PID_InitStructure->OUT_Max) PID_InitStructure->Ek_Sum = PID_InitStructure->OUT_Max; else if (PID_InitStructure->Ek_Sum < PID_InitStructure->OUT_Min) PID_InitStructure->Ek_Sum = PID_InitStructure->OUT_Min; PID_InitStructure->P_OUT = PID_InitStructure->Kp * PID_InitStructure->Ek; PID_InitStructure->I_OUT = PID_InitStructure->Ki * PID_InitStructure->Ek_Sum; PID_InitStructure->D_OUT = PID_InitStructure->Kd * PID_InitStructure->Ek_Del; PID_InitStructure->OUT = PID_InitStructure->P_OUT + PID_InitStructure->I_OUT + PID_InitStructure->D_OUT; if(PID_InitStructure->OUTOUT_Min)//输出限幅 PID_InitStructure->OUT = PID_InitStructure->OUT_Min; if(PID_InitStructure->OUT>PID_InitStructure->OUT_Max) PID_InitStructure->OUT = PID_InitStructure->OUT_Max; } /* *函数简介:增量式PID初始化结构体 *参数说明:增量式PID参数结构体 *参数说明:预期值 *返回类型:无 *备注:无 */ void PID_IncrementalStructureInit(PID_IncrementalInitTypedef* PID_InitStructure,float NeedValue) { PID_InitStructure->Need_Value=NeedValue; PID_InitStructure->Ek=0; PID_InitStructure->Ek_Last=0; PID_InitStructure->Ek_Min=0; PID_InitStructure->Ek_Max=0; PID_InitStructure->Kp=0; PID_InitStructure->Ki=0; PID_InitStructure->Kd=0; PID_InitStructure->OUT_Min=-1e10; PID_InitStructure->OUT_Max=1e10; } /* *函数简介:增量式PID设置参数 *参数说明:增量式PID参数结构体 *参数说明:单精度浮点型Kp *参数说明:单精度浮点型Ki *参数说明:单精度浮点型Kd *返回类型:无 *备注:无 */ void PID_IncrementalSetParameter(PID_IncrementalInitTypedef* PID_InitStructure,float kp,float ki,float kd) { PID_InitStructure->Kp=kp; PID_InitStructure->Ki=ki; PID_InitStructure->Kd=kd; } /* *函数简介:增量式PID设置误差为0阈值 *参数说明:增量式PID参数结构体 *参数说明:误差为0阈值下限 *参数说明:误差为0阈值上限 *返回类型:无 *备注:无 */ void PID_IncrementalSetEkRange(PID_IncrementalInitTypedef* PID_InitStructure,float Ek_Min,float Ek_Max) { PID_InitStructure->Ek_Min=Ek_Min; PID_InitStructure->Ek_Max=Ek_Max; } /* *函数简介:增量式PID设置输出限幅 *参数说明:增量式PID参数结构体 *参数说明:输出限幅下限 *参数说明:输出限幅上限 *返回类型:无 *备注:无 */ void PID_IncrementalSetOUTRange(PID_IncrementalInitTypedef* PID_InitStructure,float OUT_Min,float OUT_Max) { PID_InitStructure->OUT_Min=OUT_Min; PID_InitStructure->OUT_Max=OUT_Max; } /* *函数简介:增量式PID计算 *参数说明:增量式PID参数结构体 *参数说明:当前值 *返回类型:无 *备注:OUT=POUT+IOUT+DOUT=Kp*ΔEk+Ki*ΣΔEk+Kd*(ΔEk-ΔEk_Last)=Kp*(Ek-Ek_Last)+Ki*Ek+Kd*(Ek-2*Ek_Last+Ek_Last2) *备注:计算结果保存在增量式PID参数结构体中 */ void PID_IncrementalCalc(PID_IncrementalInitTypedef* PID_InitStructure,float NowValue) { PID_InitStructure->Now_Value =NowValue; PID_InitStructure->Ek_Last2 =PID_InitStructure->Ek_Last; PID_InitStructure->Ek_Last =PID_InitStructure->Ek; PID_InitStructure->Ek =PID_InitStructure->Need_Value-PID_InitStructure->Now_Value; if(PID_InitStructure->Ek_Min < PID_InitStructure->Ek && PID_InitStructure->Ek < PID_InitStructure->Ek_Max)//误差为0检测 PID_InitStructure->Ek =0; PID_InitStructure->P_OUT =PID_InitStructure->Kp * (PID_InitStructure->Ek - PID_InitStructure->Ek_Last); PID_InitStructure->I_OUT =PID_InitStructure->Ki * PID_InitStructure->Ek; PID_InitStructure->D_OUT =PID_InitStructure->Kd * (PID_InitStructure->Ek-2*PID_InitStructure->Ek_Last+PID_InitStructure->Ek_Last2); PID_InitStructure->OUT =PID_InitStructure->P_OUT + PID_InitStructure->I_OUT+PID_InitStructure->D_OUT; if(PID_InitStructure->OUTOUT_Min)//输出限幅 PID_InitStructure->OUT=PID_InitStructure->OUT_Min; if(PID_InitStructure->OUT>PID_InitStructure->OUT_Max) PID_InitStructure->OUT=PID_InitStructure->OUT_Max; }