备赛电赛学习软件篇(二):PID(2)持续更新中.....

注:本篇笔记承接备赛电赛学习软件篇(二):PID(1),且本笔记主要是代码部分

一、PID的基本实现

1、位置型PID

结构体部分 

/*定义结构体和公用体*/
typedef struct
{
  float setpoint;       //设定值
  float proportiongain;     //比例系数
  float integralgain;      //积分系数
  float derivativegain;    //微分系数
  float lasterror;     //前一拍偏差
  float result; //输出值
  float integral;//积分值
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{
  float thisError;
  thisError=vPID->setpoint-processValue;
  vPID->integral+=thisError;
  vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);
  vPID->lasterror=thisError;
}

2、增量型PID

 结构体部分 

/*定义结构体和公用体*/
typedef struct
{
  float setpoint;       //设定值
  float proportiongain;     //比例系数
  float integralgain;      //积分系数
  float derivativegain;    //微分系数
  float lasterror;     //前一拍偏差
  float preerror;     //前两拍偏差
  float deadband;     //死区
  float result; //输出值
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{
  float thisError;
  float increment;
  float pError,dError,iError;
 
  thisError=vPID->setpoint-processValue; //得到偏差值
  pError=thisError-vPID->lasterror;
  iError=thisError;
  dError=thisError-2*(vPID->lasterror)+vPID->preerror;
  increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量计算
 
  vPID->preerror=vPID->lasterror;  //存放偏差用于下次运算
  vPID->lasterror=thisError;
  vPID->result+=increment;
}

二、积分分离

1、位置型PID

结构体部分:

/*定义结构体和公用体*/
typedef struct
{
  floatsetpoint;       //设定值
  floatproportiongain;     //比例系数
  floatintegralgain;      //积分系数
  floatderivativegain;    //微分系数
  floatlasterror;     //前一拍偏差
  floatresult; //输出值
  floatintegral;//积分值
  float epsilon; //偏差检测阈值
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{
  floatthisError;
 thisError=vPID->setpoint-processValue;
 vPID->integral+=thisError;
  uint16_tbeta= BetaGeneration(error,vPID->epsilon);
 
  if(beta==0)
{
 vPID->result=vPID->proportiongain*thisError+vPID->derivativegain*(thisError-vPID->lasterror);
}
else
{
vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);
}
 
 vPID->lasterror=thisError;
 
}
static uint16_t BetaGeneration(float error,float epsilon)
{
  uint16_t beta=0;
 
  if(abs(error)<= epsilon)
{
  beta=1;
}
 
return beta;
 
}

2、增量式PID

结构体

/*定义结构体和公用体*/
typedef struct
{
  floatsetpoint;       //设定值
  floatproportiongain;     //比例系数
  floatintegralgain;      //积分系数
  floatderivativegain;    //微分系数
  floatlasterror;     //前一拍偏差
  floatpreerror;     //前两拍偏差
  floatdeadband;     //死区
  floatresult; //输出值
  float epsilon; //偏差检测阈值
}PID;

接下来实现PID控制器:

void PIDRegulation(PID *vPID, float processValue)
{
  floatthisError;
  floatincrement;
  floatpError,dError,iError;
 
 thisError=vPID->setpoint-processValue; //得到偏差值
 pError=thisError-vPID->lasterror;
 iError=thisError;
 dError=thisError-2*(vPID->lasterror)+vPID->preerror;
  uint16_tbeta= BetaGeneration(error,vPID->epsilon);
 
  if(beta==0)
{
increment=vPID->proportiongain*pError+vPID->derivativegain*dError;   //增量计算
}
else
{
increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量计算
}
 vPID->preerror=vPID->lasterror; //存放偏差用于下次运算
 vPID->lasterror=thisError;
 vPID->result+=increment;
}
static uint16_t BetaGeneration(float error,float epsilon)
{
  uint16_t beta=0;
 
  if(abs(error)<= epsilon)
{
  beta=1;
}
 
return beta;
 
}

三、抗积分饱和

1、思想

所谓积分饱和就是指系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而扩大,从而导致控制器输出不断增大超出正常范围进入饱和区。当系统出现反响的偏差时,需要首先从饱和区退出,而不能对反向的偏差进行快速的响应。

为了解决积分饱和的问题,人们引入了抗积分饱和的PID算法。所谓抗积分饱和算法,其思路是在计算U(k)的时候,先判断上一时刻的控制量U(k-1)是否已经超出了限制范围。若U(k-1)>Umax,则只累加负偏差;若U(k-1)<Umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。
 

2、流程图

 3、代码部分

3.1位置型

结构体

/*定义结构体和公用体*/
typedef struct
{
  floatsetpoint;       //设定值
  floatproportiongain;     //比例系数
  floatintegralgain;      //积分系数
  floatderivativegain;    //微分系数
  floatlasterror;     //前一拍偏差
  floatresult; //输出值
  floatintegral;//积分值
  floatmaximum;//最大值
  floatminimum;//最小值
}PID;

PID控制器

void PIDRegulation(PID *vPID, float processValue)
{
  floatthisError;
 thisError=vPID->setpoint-processValue;
 if(vPID->result>vPID->maximum)
  {
   if(thisError<=0)
    {
     vPID->integral+=thisError;
    }
  }
  elseif(vPID->result<vPID->minimum)
  {
   if(thisError>=0)
    {
     vPID->integral+=thisError;
    }
  }
  else
  {
   vPID->integral+=thisError;
  }
 
 vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);
 vPID->lasterror=thisError;
}

3.2增量式

结构体

/*定义结构体和公用体*/
typedef struct
{
  floatsetpoint;       //设定值
  floatproportiongain;     //比例系数
  floatintegralgain;      //积分系数
  floatderivativegain;    //微分系数
  floatlasterror;     //前一拍偏差
  floatpreerror;     //前两拍偏差
  floatdeadband;     //死区
  floatresult; //输出值
  floatmaximum;//最大值
  floatminimum;//最小值
}PID;

PID控制器

void PIDRegulation(PID *vPID, float processValue)
{
  floatthisError;
  floatincrement;
  floatpError,dError,iError;
 
 thisError=vPID->setpoint-processValue; //得到偏差值
 pError=thisError-vPID->lasterror;
  iError=0;
 dError=thisError-2*(vPID->lasterror)+vPID->preerror;
 
 if(vPID->result>vPID->maximum)
  {
   if(thisError<=0)
    {
     iError=thisError;
    }
  }
  elseif(vPID->result<vPID->minimum)
  {
   if(thisError>=0)
    {
     iError=thisError;
    }
  }
  else
  {
   iError=thisError;
  }
 
 increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量计算
 
 vPID->preerror=vPID->lasterror; //存放偏差用于下次运算
 vPID->lasterror=thisError;
 vPID->result+=increment;
}

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子ゆ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值