一个直接用于项目开发的PID库分享

描述

最近有朋友问到有没有现成的C语言PID库。

当然有了!现在我就准备给大家安利一下了。一般同学会去某度上搜,看到各种各样版本的PID示例,或者去GitHub上白嫖。

其实一些芯片公司会提供一些控制领域的解决方案了,这里面就会包括PID库。

比如ST的"ST Motor Control Sdk",或者TI的C2000系列的control suite。

不过目前TI官方对于control suite已经不再提供相应的更新,可以继续下载这个套件.

目前control suite已经更新为C2000WARE-MOTORCONTROL-SDK.

那本文主要介绍TI的control suite,这里面除了PID外有很多控制类算法,并且配置了丰富的文档。

如何安装?

进入ti的官网,输入control suite进行搜索,就可以找到相应的安装包。

C语言

这里有离线安装包,和在线安装包。直接基于在线安装包进行操作即可。我们先下载安装包。

C语言

下面就是一路疯狂点击Next即可;

C语言界面 1C语言界面 2C语言界面 3C语言界面 4C语言耐心等待C语言安装成功

源码和文档

进入主界面,这里基本的例子都是基于TI的C2000系列的MCU进行开发的,具体如下图所示;

C语言主界面

进入主界面之后,我们可以看到左侧这边包含了软硬件文档,项目示例还有相应的文档。


C语言

其实我们要找的是基于C2000系列MCU的数学算法库,可以在下列列表中找到;

C语言

当然也可以在安装目录C: icontrolSUITElibsapp_libsmotor_controlmath_blocksv4.2下面找到相应的PID算法;

C语言

至于如何使用这几个文件,这里也提供了相应的文档,在Docs中找到,

C语言

例如pid_grando.h文件,这里介绍了对应的平台,当然是TI系列的MCU,并且依赖于IQMath库,其实这里我们做一些简单的改动,就可以移植到自己所需的平台上去了,具体源码如下:

/* =================================================================================
File name:       PID_GRANDO.H 
===================================================================================*/


#ifndef __PID_H__
#define __PID_H__

typedef struct {  _iq  Ref;      // Input: reference set-point
      _iq  Fbk;      // Input: feedback
      _iq  Out;      // Output: controller output 
      _iq  c1;      // Internal: derivative filter coefficient 1
      _iq  c2;      // Internal: derivative filter coefficient 2
    } PID_TERMINALS;
    // note: c1 & c2 placed here to keep structure size under 8 words

typedef struct {  _iq  Kr;    // Parameter: reference set-point weighting 
      _iq  Kp;    // Parameter: proportional loop gain
      _iq  Ki;       // Parameter: integral gain
      _iq  Kd;           // Parameter: derivative gain
      _iq  Km;           // Parameter: derivative weighting
      _iq  Umax;   // Parameter: upper saturation limit
      _iq  Umin;   // Parameter: lower saturation limit
    } PID_PARAMETERS;

typedef struct {  _iq  up;    // Data: proportional term
      _iq  ui;    // Data: integral term
      _iq  ud;    // Data: derivative term
      _iq  v1;    // Data: pre-saturated controller output
      _iq  i1;    // Data: integrator storage: ui(k-1)
      _iq  d1;    // Data: differentiator storage: ud(k-1)
      _iq  d2;    // Data: differentiator storage: d2(k-1) 
      _iq  w1;    // Data: saturation record: [u(k-1) - v(k-1)]
    } PID_DATA;


typedef struct {  PID_TERMINALS term;
      PID_PARAMETERS param;
      PID_DATA  data;
    } PID_CONTROLLER;

/*-----------------------------------------------------------------------------
Default initalisation values for the PID objects
-----------------------------------------------------------------------------*/                     

#define PID_TERM_DEFAULTS {    
         0,    
                           0,    
                           0,    
                           0,    
         0    
                   }

#define PID_PARAM_DEFAULTS {   
                           _IQ(1.0), 
                           _IQ(1.0),  
                           _IQ(0.0), 
                           _IQ(0.0), 
                           _IQ(1.0), 
                           _IQ(1.0), 
                           _IQ(-1.0)  
                   }

#define PID_DATA_DEFAULTS {       
                           _IQ(0.0), 
                           _IQ(0.0),  
                           _IQ(0.0), 
                           _IQ(0.0), 
                           _IQ(0.0),  
                           _IQ(0.0), 
                           _IQ(0.0), 
                           _IQ(1.0)  
                   }


/*------------------------------------------------------------------------------
  PID Macro Definition
------------------------------------------------------------------------------*/

#define PID_MACRO(v)                    
                         
 /* proportional term */                   
 v.data.up = _IQmpy(v.param.Kr, v.term.Ref) - v.term.Fbk;          
                         
 /* integral term */                    
 v.data.ui = _IQmpy(v.param.Ki, _IQmpy(v.data.w1, (v.term.Ref - v.term.Fbk))) + v.data.i1;  
 v.data.i1 = v.data.ui;                   
                         
 /* derivative term */                    
 v.data.d2 = _IQmpy(v.param.Kd, _IQmpy(v.term.c1, (_IQmpy(v.term.Ref, v.param.Km) - v.term.Fbk))) - v.data.d2; 
 v.data.ud = v.data.d2 + v.data.d1;                
 v.data.d1 = _IQmpy(v.data.ud, v.term.c2);              
                         
 /* control output */                    
 v.data.v1 = _IQmpy(v.param.Kp, (v.data.up + v.data.ui + v.data.ud));       
 v.term.Out= _IQsat(v.data.v1, v.param.Umax, v.param.Umin);          
 v.data.w1 = (v.term.Out == v.data.v1) ? _IQ(1.0) : _IQ(0.0);         
 
#endif // __PID_H__


这里面不仅仅做了积分抗饱和,还有对微分环节的滤波处理,所以应用到项目中是没有问题的。

代码中需要了解Q格式的相关的知识,可以参考一下我的这篇文章《一文教你搞懂C语言的Q格式》 

另外,这个路径下的文档中,还提供了相应的Example,以及PID的信号流图,具体如下所示:

C语言C语言

审核编辑 :李倩


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分