2022-10-31 20:20:16 +08:00
|
|
|
|
2022-10-20 17:13:02 +08:00
|
|
|
#include "controller.h"
|
2022-10-31 20:20:16 +08:00
|
|
|
#include <memory.h>
|
2022-10-20 17:13:02 +08:00
|
|
|
|
|
|
|
/******************************* PID CONTROL *********************************/
|
|
|
|
// PID优化环节函数声明
|
|
|
|
static void f_Trapezoid_Intergral(PID_t *pid);
|
|
|
|
static void f_Integral_Limit(PID_t *pid);
|
|
|
|
static void f_Derivative_On_Measurement(PID_t *pid);
|
|
|
|
static void f_Changing_Integration_Rate(PID_t *pid);
|
|
|
|
static void f_Output_Filter(PID_t *pid);
|
|
|
|
static void f_Derivative_Filter(PID_t *pid);
|
|
|
|
static void f_Output_Limit(PID_t *pid);
|
|
|
|
static void f_Proportion_Limit(PID_t *pid);
|
|
|
|
static void f_PID_ErrorHandle(PID_t *pid);
|
|
|
|
|
|
|
|
/**
|
2022-10-31 20:20:16 +08:00
|
|
|
* @brief
|
|
|
|
*
|
|
|
|
* @param pid
|
|
|
|
* @param config
|
2022-10-20 17:13:02 +08:00
|
|
|
*/
|
2022-10-31 20:20:16 +08:00
|
|
|
void PID_Init(PID_t* pid,PID_Init_config_s *config)
|
2022-10-20 17:13:02 +08:00
|
|
|
{
|
2022-10-31 20:20:16 +08:00
|
|
|
memcpy(pid, config, sizeof(PID_Init_config_s));
|
|
|
|
memset(&pid->Measure,0,sizeof(PID_t)-sizeof(PID_Init_config_s));
|
|
|
|
|
|
|
|
// // DWT定时器计数变量清零
|
|
|
|
// // reset DWT Timer count counter
|
|
|
|
// pid->DWT_CNT = 0;
|
2022-10-20 17:13:02 +08:00
|
|
|
|
2022-10-31 20:20:16 +08:00
|
|
|
// // 设置PID异常处理 目前仅包含电机堵转保护
|
|
|
|
// pid->ERRORHandler.ERRORCount = 0;
|
|
|
|
// pid->ERRORHandler.ERRORType = PID_ERROR_NONE;
|
2022-10-20 17:13:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief PID计算
|
|
|
|
* @param[in] PID结构体
|
|
|
|
* @param[in] 测量值
|
|
|
|
* @param[in] 期望值
|
|
|
|
* @retval 返回空
|
|
|
|
*/
|
|
|
|
float PID_Calculate(PID_t *pid, float measure, float ref)
|
|
|
|
{
|
|
|
|
if (pid->Improve & ErrorHandle)
|
|
|
|
f_PID_ErrorHandle(pid);
|
|
|
|
|
|
|
|
pid->dt = DWT_GetDeltaT((void *)&pid->DWT_CNT);
|
|
|
|
|
|
|
|
pid->Measure = measure;
|
|
|
|
pid->Ref = ref;
|
|
|
|
pid->Err = pid->Ref - pid->Measure;
|
|
|
|
|
|
|
|
if (abs(pid->Err) > pid->DeadBand)
|
|
|
|
{
|
|
|
|
pid->Pout = pid->Kp * pid->Err;
|
|
|
|
pid->ITerm = pid->Ki * pid->Err * pid->dt;
|
2022-10-31 20:20:16 +08:00
|
|
|
pid->Dout = pid->Kd * (pid->Err - pid->Last_Err) / pid->dt;
|
2022-10-20 17:13:02 +08:00
|
|
|
|
|
|
|
// 梯形积分
|
|
|
|
if (pid->Improve & Trapezoid_Intergral)
|
|
|
|
f_Trapezoid_Intergral(pid);
|
|
|
|
// 变速积分
|
|
|
|
if (pid->Improve & ChangingIntegrationRate)
|
|
|
|
f_Changing_Integration_Rate(pid);
|
|
|
|
// 微分先行
|
|
|
|
if (pid->Improve & Derivative_On_Measurement)
|
|
|
|
f_Derivative_On_Measurement(pid);
|
|
|
|
// 微分滤波器
|
|
|
|
if (pid->Improve & DerivativeFilter)
|
|
|
|
f_Derivative_Filter(pid);
|
|
|
|
// 积分限幅
|
|
|
|
if (pid->Improve & Integral_Limit)
|
|
|
|
f_Integral_Limit(pid);
|
|
|
|
|
|
|
|
pid->Iout += pid->ITerm;
|
|
|
|
pid->Output = pid->Pout + pid->Iout + pid->Dout;
|
|
|
|
|
|
|
|
// 输出滤波
|
|
|
|
if (pid->Improve & OutputFilter)
|
|
|
|
f_Output_Filter(pid);
|
|
|
|
// 输出限幅
|
|
|
|
f_Output_Limit(pid);
|
|
|
|
}
|
|
|
|
pid->Last_Measure = pid->Measure;
|
|
|
|
pid->Last_Output = pid->Output;
|
|
|
|
pid->Last_Dout = pid->Dout;
|
|
|
|
pid->Last_Err = pid->Err;
|
|
|
|
pid->Last_ITerm = pid->ITerm;
|
|
|
|
|
|
|
|
return pid->Output;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Trapezoid_Intergral(PID_t *pid)
|
|
|
|
{
|
|
|
|
|
|
|
|
pid->ITerm = pid->Ki * ((pid->Err + pid->Last_Err) / 2) * pid->dt;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Changing_Integration_Rate(PID_t *pid)
|
|
|
|
{
|
|
|
|
if (pid->Err * pid->Iout > 0)
|
|
|
|
{
|
|
|
|
// 积分呈累积趋势
|
|
|
|
// Integral still increasing
|
|
|
|
if (abs(pid->Err) <= pid->CoefB)
|
|
|
|
return; // Full integral
|
|
|
|
if (abs(pid->Err) <= (pid->CoefA + pid->CoefB))
|
|
|
|
pid->ITerm *= (pid->CoefA - abs(pid->Err) + pid->CoefB) / pid->CoefA;
|
|
|
|
else
|
|
|
|
pid->ITerm = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Integral_Limit(PID_t *pid)
|
|
|
|
{
|
|
|
|
static float temp_Output, temp_Iout;
|
|
|
|
temp_Iout = pid->Iout + pid->ITerm;
|
|
|
|
temp_Output = pid->Pout + pid->Iout + pid->Dout;
|
|
|
|
if (abs(temp_Output) > pid->MaxOut)
|
|
|
|
{
|
|
|
|
if (pid->Err * pid->Iout > 0)
|
|
|
|
{
|
|
|
|
// 积分呈累积趋势
|
|
|
|
// Integral still increasing
|
|
|
|
pid->ITerm = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (temp_Iout > pid->IntegralLimit)
|
|
|
|
{
|
|
|
|
pid->ITerm = 0;
|
|
|
|
pid->Iout = pid->IntegralLimit;
|
|
|
|
}
|
|
|
|
if (temp_Iout < -pid->IntegralLimit)
|
|
|
|
{
|
|
|
|
pid->ITerm = 0;
|
|
|
|
pid->Iout = -pid->IntegralLimit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Derivative_On_Measurement(PID_t *pid)
|
|
|
|
{
|
2022-10-31 20:20:16 +08:00
|
|
|
pid->Dout = pid->Kd * (pid->Last_Measure - pid->Measure) / pid->dt;
|
2022-10-20 17:13:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Derivative_Filter(PID_t *pid)
|
|
|
|
{
|
|
|
|
pid->Dout = pid->Dout * pid->dt / (pid->Derivative_LPF_RC + pid->dt) +
|
|
|
|
pid->Last_Dout * pid->Derivative_LPF_RC / (pid->Derivative_LPF_RC + pid->dt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Output_Filter(PID_t *pid)
|
|
|
|
{
|
|
|
|
pid->Output = pid->Output * pid->dt / (pid->Output_LPF_RC + pid->dt) +
|
|
|
|
pid->Last_Output * pid->Output_LPF_RC / (pid->Output_LPF_RC + pid->dt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_Output_Limit(PID_t *pid)
|
|
|
|
{
|
|
|
|
if (pid->Output > pid->MaxOut)
|
|
|
|
{
|
|
|
|
pid->Output = pid->MaxOut;
|
|
|
|
}
|
|
|
|
if (pid->Output < -(pid->MaxOut))
|
|
|
|
{
|
|
|
|
pid->Output = -(pid->MaxOut);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// PID ERRORHandle Function
|
|
|
|
static void f_PID_ErrorHandle(PID_t *pid)
|
|
|
|
{
|
|
|
|
/*Motor Blocked Handle*/
|
|
|
|
if (pid->Output < pid->MaxOut * 0.001f || fabsf(pid->Ref) < 0.0001f)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ((fabsf(pid->Ref - pid->Measure) / fabsf(pid->Ref)) > 0.95f)
|
|
|
|
{
|
|
|
|
// Motor blocked counting
|
|
|
|
pid->ERRORHandler.ERRORCount++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pid->ERRORHandler.ERRORCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pid->ERRORHandler.ERRORCount > 500)
|
|
|
|
{
|
|
|
|
// Motor blocked over 1000times
|
|
|
|
pid->ERRORHandler.ERRORType = Motor_Blocked;
|
|
|
|
}
|
2022-10-31 20:20:16 +08:00
|
|
|
}
|