设计pid控制器并设定参数,pid控制器参数设置

  设计pid控制器并设定参数,pid控制器参数设置

  我们发表了一系列与PID控制器相关的文章,包括经典PID控制器和参数自适应PID控制器。虽然该系列PID控制器实现了主要功能,在实际使用中取得了良好的效果,但仍有许多细节可以改进,以提高性能和灵活性。在本文中,我们将讨论改进PID控制器参数设置的问题。

  1.问题就提出来了。在上一篇文章中,我们推导了PID控制器的公式,并将其离散化以适合程序实现。具体的离散化公式如下:

  编写程序时,我们将比例项的系数设为Kp,积分项的系数设为Ki,微分项的系数设为Kd,其中:

  其中t是采样周期,Ti是积分时间,Td是微分时间。所以在设置参数时,我们需要先去掉比例系数Kp,然后根据采样周期和积分微分时间计算Ki和Kd。虽然公式变得简单,但是和我们传统的参数设置相比就没有那么直观了,所以有些用户希望用传统比例中的PB,积分时间Ti,微分时间Td来配置相应的参数。本文将对这一问题进行分析和解决。

  2.针对上述问题的分析与设计,我们需要弄清楚Kp,Ki,Kd与PB,Ti,Td之间的关系。其实他们之间的关系并不复杂。首先,比例系数Kp是比例带的倒数,知道其中一个就可以得到另一个。ti和Ki的关系以及Td和Kd的关系前面已经给出了。

  接下来我们要做的,其实就是让我们的PID控制器在不同的应用需求下呈现不同的参数设置,然后我们就可以设置不同的参数形式。

  3.软件实现我们已经分析了需要实现什么。接下来,我们来考虑如何实现。在这方面,我们考虑我们的PID控制器的设计形式,它需要在三个方面进行修改。首先需要修改的地方是PID控制器对象的定义。我们定义一个宏来实现条件编译,以实现不同要求下的不同参数定义,所以我们定义PID控制器的对象类型如下:

  /*定义PID对象类型*/

  typedef结构经典

  {

  float * pPV//测量值指针

  float * pSV//设置值指针

  float * pMV//输出值指针

  uint16 _ t * pMA//手动自动操作指针

  \#if PID_PARAMETER_STYLE (0)

  float * pKp//比例系数指针

  float * pKi//整型系数指针

  float * pKd//微分系数指针

  \#else

  float * pPb//比例带

  float * pTi//积分时间,单位为秒

  float * pTd//差分时间,以秒为单位

  浮动ts;//采样周期,以秒为单位

  \#endif

  浮动设定值;//设置值

  float lasterror//前一节拍偏差

  浮点预误差;//前两拍的偏差

  浮动死区;//死区

  浮点结果;//PID控制器//的计算结果

  浮点输出;//输出值为0-100%

  浮动最大值;//输出值的上限

  浮动最小值;//输出值的下限

  浮点误差absmax;//最大偏差绝对值

  float errorabsmin//绝对偏差的最小值

  浮动;//不完全微分系数

  浮点deltadiff//差分增量

  浮点integralValue//累计积分金额

  浮动伽马;//差分第一滤波器系数

  float lastPv//最后一拍的过程测量值

  float lastDeltaPv//前一个节拍的过程测量值的增量

  ClassicPIDDRType direct//正面和负面影响

  经典sm;//将值设置为平滑

  ClassicPIDCSType cas//级联设置

  } CLASSICPID我们定义了对象类型,可以得到我们需要的对象变量,但是这个对象变量需要初始化后才能使用。所以第二个需要修改的是PID控制器对象的初始化函数。我们使用条件编译,我们在不同的应用需求下初始化不同的对象参数。具体实现如下:

  /* PID初始化应该在修改vPID对象的值之前完成*/

  /* CLASSICPID vPID,一个常用的PID对象变量,实现数据交换和存储*/

  /*浮点vMax、浮点vMin、过程变量的最大值和最小值(范围*/

  void PID para initial ization(经典PID * vPID,//PID控制器对象

  float *pPV,//测量值指针

  float *pSV,//设定值指针

  float *pMV,//输出值指针

  \#if PID_PARAMETER_STYLE (0)

  float *pKp,//比例系数指针

  float *pKi,//积分系数指针

  float *pKd,//微分系数指针

  \#else

  float * pPb//比例带

  float * pTi//积分时间

  float * pTd//微分时间

  浮点ts,//采样周期,单位为秒

  \#endif

  uint16_t *pMA,//手自动操作指针

  浮点vMax,//控制变量量程

  浮点vMin,//控制变量的零点

  ClassicPIDDRType direct,//正反作用

  ClassicPIDSMType sm,//设定值平滑

  ClassicPIDCSType cas //串级设定

  )

  {

  if((vPID==NULL) (pPV==NULL) (pSV==NULL) (pMV==NULL) (pMA==NULL))

  {

  返回;

  }

  vPID-pPV=pPV;

  vPID-pSV=pSV;

  vPID-pMV=pMV;

  vPID-pMA=pMA;

  \#if PID_PARAMETER_STYLE (0)

  if((pKp==NULL) (pKi==NULL) (pKd==NULL))

  {

  返回;

  }

  vPID-pKp=pKp;

  vPID-pKi=pKi;

  vPID-pKd=pKd;

  如果(*vPID- pKp=0.00001)

  {

  * vPID-pKp=1.0;//比例系数

  * vPID-pKi=0.01;//积分系数

  * vPID-pKd=0.01;//微分系数

  }

  \#else

  if((pPb==NULL) (pTi==NULL) (pTd==NULL))

  {

  返回;

  }

  vPID-pPb=pPb;

  vPID-pTi=pTi;

  vPID-pTd=pTd;

  vPID-ts=ts;

  如果(*vPID- pPb=0.00001)

  {

  * vPID-pPb=1.0;//比例带

  * vPID-pTi=1.0;//积分时间,单位为秒

  * vPID-pTd=0.0001;//微分时间,单位为秒

  }

  \#endif

  vPID-maximum=vMax;//控制变量的量程

  vPID-minimum=vMin;//控制变量的零点

  * vPID-pSV=* pPV;//设定值

  vPID-setpoint=* pPV;//设定值

  * vPID-pMA=1;//初始化为自动模式

  vPID-direct=direct;//设定PID对象的正反作用

  vPID-cas=cas;//设定是否启用串级

  vPID-sm=sm;//设定是否启用设定值平滑

  if(vPID- cas==CASCADE)

  {

  vPID-sm=SMOOTH _ DISABLE;

  }

  vPID-lasterror=0.0;//前一拍偏差

  vPID-preerror=0.0;//前两拍偏差

  vPID-result=vMin;//PID控制器结果

  vPID-output=0.0;//输出值,百分比

  * vPID-pMV=vPID-output;//输出值,百分比

  vPID-errorabsmax=(vMax-vMin)* 0.9;

  vPID-errorabsmin=(vMax-vMin)* 0.1;

  vPID-死区=(vMax-vMin)* 0.001;//死区

  vPID-alpha=0.2;//不完全微分系数

  vPID-delta diff=0.0;//微分增量

  vPID-积分值=0.0;

  }第三个需要修改的是PID控制器对象的实现。在前面我们已经描述铅、钛、总镉与Kp、Ki、Kd之间的数学关系。为了方便处理,我们通过条件编译在不同应用需求下将参数均转化为统一的Kp、Ki、Kd来进行计算。具体的实现方式如下:

  /* 通用PID控制器,采用增量型算法,具有变积分,梯形积分和抗积分饱和功能*/

  /* 微分项采用不完全微分,一阶滤波,阿尔法值越大滤波作用越强*/

  /* CLASSICPID vPID,PID对象变量,实现数据交换与保存*/

  /*浮动pv,过程测量值,对象响应的测量数据,用于控制反馈*/

  无效PID调节器(经典PID *vPID)

  {

  浮动此错误

  浮点结果;

  浮动系数;

  浮动增量;

  浮点pError、dError、iError

  浮动kp,ki,KD;

  \#if PID_PARAMETER_STYLE (0)

  kp=*vPID-

  ki=*vPID-

  kd=*vPID-

  \#else

  if((*vPID- pTi) vPID- ts)

  {

  *vPID- pTi=vPID-

  }

  KP=1/(* vPID-pPb);

  ki=KP *(vPID-ts/(* vPID-pTi));

  KD=KP *(vPID-pTd)/vPID-

  \#endif

  if(*vPID- pMA 1) //手动模式

  {

  识输出=*vPID-

  //设置无扰动切换

  vPID-结果=(vPID-最大值-vPID-最小值)*vPID-输出/100.0 vPID-最小值;

  *vPID- pSV=*vPID-

  vPID-设定点=*vPID-

  }

  else //自动模式

  {

  if(vPID- sm==SMOOTH_ENABLE) //设定值平滑变化

  {

  平滑设定点(vPID);

  }

  其他

  {

  if(vPID- cas==CASCADE) //串级处理

  {

  vPID-设定点=(vPID-最大值-vPID-最小值)*(*vPID- pSV)/100.0 vPID-最小值;

  }

  其他

  {

  vPID-设定点=*vPID-

  }

  }

  这个误差=vPID-设定点-(* vPID-pPV);//得到偏差值

  结果=vPID-结果;

  if (fabs(thisError) vPID-死区)

  {

  pError=this error-vPID-lasterror;

  I error=(thisError vPID-lasterror)/2.0;

  dError=this error-2 *(vPID-lasterror)vPID-preerror;

  //变积分系数获取

  factor=VariableIntegralCoefficient(this error,vPID- errorabsmax,vPID-error absmin);

  //计算不完全微分的微分项增量

  vPID-delta diff=KD *(1-vPID-alpha)* dError vPID-alpha * vPID-delta diff;

  increment=KP * pError ki * factor * I error vPID-delta diff;//增量计算

  }

  其他

  {

  if((fabs(vPID-设定点-vPID-最小值)vPID-死区)(fabs((*vPID- pPV)-vPID-最小值)vPID-死区))

  {

  结果=vPID-最小值;

  }

  增量=0.0;

  }

  //正反动作设置

  if(vPID- direct==DIRECT)

  {

  结果=结果增量;

  }

  其他

  {

  结果=结果-增量;

  }

  /*对于输出限制,避免过冲和积分饱和*/

  if(结果=vPID-最大值)

  {

  result=vPID-maximum;

  }

  if(结果=vPID-最小值)

  {

  结果=vPID-最小值;

  }

  vPID-preerror=vPID-lasterror;//为下一次操作存储偏差。

  vPID-lasterror=this error;

  vPID-result=结果;

  vPID-output=(vPID-result-vPID-minimum)/(vPID-maximum-vPID-minimum)* 100.0;

  * vPID-pMV=vPID-output;

  }

  }4.总结在本文中,我们只是修改了PID控制器的参数定义,以满足不同用户的需求,但控制器本身的功能并没有改变。这样原应用不会受到影响,新应用也可以根据需要定义参数,使用Kp,Ki,Kd或者PB,Ti,Td根据应用设计的需要进行选择。

  这里需要说的是,无论我们如何定义参数,采样周期的选择都需要慎重考虑。即使采用相同的参数设置,当采样周期不同时,效果也可能相差很大,所以在设置参数前要根据系统的特点采用合适的采样周期。

  欢迎关注:

  想更方便及时的阅读相关文章,请关注我的微信微信官方账号【木南创智】

  转载请联系作者取得转载授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • waitpid函数作用,c wait函数
  • waitpid函数作用,c wait函数,详解C语言中的wait()函数和waitpid()函数
  • ,,javascript SpiderMonkey中的函数序列化如何进行
  • spiderfoot安装,spiderfoot会被对手反扫描
  • PySpider,pyspider官方文档
  • C语言PID,pid控制算法的c语言实现
  • pid控制死区范围,带死区的pid控制方法有何优点
  • pid控制器中微分的作用,pid控制微分方程
  • 微分先行的pid控制算法课程设计,什么是微分先行pid控制
  • PID控制器百科,PID控制实现
  • PID控制算法原理,pid 控制算法
  • pid控制中积分控制指什么,数字pid控制器积分项的改进有哪些
  • pid控制器的调节原则,试说明pid控制器的优点
  • 通过进程名查找进程的pid,linux根据程序名查进程
  • 串级控制系统pid怎么调,串级控制pid参数怎么调节
  • 留言与评论(共有 条评论)
       
    验证码: