搜索
bottom↓
回复: 40

一种位置式PID的程序实现

  [复制链接]

出0入0汤圆

发表于 2012-4-1 17:11:21 | 显示全部楼层 |阅读模式
我在网上搜到一个PID的程序,看起来不错,而且微分环节还带低通滤波的,
然后稍加修改留给自己用,应该可以用吧,请大家看看怎么样

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-4-1 21:02:46 | 显示全部楼层
还没看 先顶一下

出0入0汤圆

发表于 2012-4-1 21:04:45 | 显示全部楼层
先顶一下

出0入0汤圆

 楼主| 发表于 2012-4-2 21:08:48 | 显示全部楼层
还是把程序贴出来方便看:
/*
        @struct        sPID
        @brief        manage all the parameters related to PID control
*/
typedef struct
{
        float                        kp;
        float                        ki;
        float                        kd;
        float                         dt;                                // delta time(sample time)
       
        float                        imax;
        float                        last_error;
        float                        integrator;                // integrator value
        float                        last_derivative;// last derivative for low-pass filter
        float                        derivative;
        float                        output;
        float                        ouput_max;

        /// Low pass filter cut frequency for derivative calculation.
        float           filter; // Set to  "1 / ( 2 * PI * f_cut )";
        // Examples for filter:
        // f_cut = 10 Hz -> _filter = 15.9155e-3
        // f_cut = 15 Hz -> _filter = 10.6103e-3
        // f_cut = 20 Hz -> _filter =  7.9577e-3
        // f_cut = 25 Hz -> _filter =  6.3662e-3
        // f_cut = 30 Hz -> _filter =  5.3052e-3
}sPID;


/*
        @function Get_PID()
        @brief    compute PID ouput value according to the error
        @param    error: current error between set point and point value
                          PID: the pointer of the PID structure
        @return   PID output value
*/
float Get_PID(float error, sPID *PID)
{
        // Compute proportional component
        PID->output = error * PID->kp;

        // Compute derivative component if time has elapsed
        if ((fabs(PID->kd) > 0) && (PID->dt > 0))
        {
                PID->derivative = (error - PID->last_error) / PID->dt;

                // discrete low pass filter, cuts out the
                // high frequency noise that can drive the controller crazy
                PID->derivative = PID->derivative +
                        (PID->dt / ( PID->filter + PID->dt)) * (PID->derivative - PID->derivative);

                // update state
                PID->last_error  = error;
                PID->last_derivative  = PID->derivative;

                // add in derivative component
                PID->output         += PID->kd * PID->derivative;
        }

        // Compute integral component if time has elapsed
        if ((fabs(PID->ki) > 0) && (PID->dt > 0))
        {
                PID->integrator                 += (error * PID->ki) * PID->dt;
                if (PID->integrator < -PID->imax)  
                        PID->integrator = -PID->imax;
                else if (PID->integrator > PID->imax)  
                        PID->integrator = PID->imax;
                PID->output         += PID->integrator;
        }

        //Limit output
        if(PID->output < -PID->ouput_max)
                PID->output = -PID->output_max;
        else if(PID->ouput > PID->ouput_max)
                PID->output = PID->ouput_max;

        return PID->output;
}

出0入0汤圆

发表于 2012-4-2 21:34:45 | 显示全部楼层
顶起来了

出0入0汤圆

发表于 2012-4-17 09:50:25 | 显示全部楼层
看了楼主的帖子后受益匪浅,绑定

出0入0汤圆

发表于 2012-4-17 09:52:00 | 显示全部楼层
PID->derivative = PID->derivative +
                         (PID->dt / ( PID->filter + PID->dt)) * (PID->derivative - PID->derivative);
这句话是不是后面有问题啊,这个滤波是怎么起作用的

出0入0汤圆

 楼主| 发表于 2012-4-17 10:11:24 | 显示全部楼层
这个式子有低通滤波的作用,具体原理我也不太清楚,不过应该是对的,我在很多地方都看到过。

出0入0汤圆

发表于 2012-4-18 22:32:18 | 显示全部楼层
好,有空看看

出0入0汤圆

发表于 2012-4-19 03:11:47 | 显示全部楼层
3.5控制核心——数字PID
        在控制系统中,将偏差的比例P、积分I、微分D通过线性组合构成控制量的PID控制器获得了广泛的应用,它结构简单,参数容易调整,不需要确切的数学模型。即通过采集实时转速值与设定值的偏差,利用软件编程实现转速调节的运算,单片机实现PID控制的类型分为位置式和增量式两种:

  位置式PID控制:其输入e (t)与输出u (t)的关系
               u(t)=kp(e(t)+1/TI∫e(t)dt+TD*de(t)/dt) (式3.5-1)
        从式3.5-1可以看出:
  位置式PID控制存在缺点:
        1)由于全量输出,所以每次输出均与过去状态有关,计算时要对e(k)(k=0,1,…n)进行累加,工作量大。
    2)因为计算机输出的u(n)对应的是执行机构的实际位置,如果计算机出现故障,输出u(n)将大幅度变化,会引起执行机构的大幅度变化,有可能因此造成严重的生产事故,这在实际生产中是不允许的。
故本系统采用增量式数字PID算法,表达式推导 式3.5-1 U(t2)与U(t1)相减:

式中:—比例常数;  —积分时间常数;  _微分时间常数;
   T—采样周期
对比位置PID控制方法增量式PID优点:
1)增量式PID的输出的是控制量增量,并无积分作用,因此,这种方法适用于执行机构带积分部件的对象。如步进电机;而位置式PID适用于执行机构不带积分环节的对象。
增量式PID输出的是控制量增量,若计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。

出0入0汤圆

发表于 2012-4-19 03:15:09 | 显示全部楼层
/************************************************
              增量控制PID函数体
51单片机最不擅长浮点数计算,转换成int型计算
*************************************************/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
  unsigned int dError,Error,pError;
  //增量法计算公式:
  //Pdt=Kp*[E(t)-E(t-1)]+Ki*E(t)+Kd*[E(t)-2*E(t-1)+E(t-2)]
  Error = set_temper - NextPoint;       // 偏差E(t)
  pError=Error-pp->LastError;         //E(t)-E(t-1)
  dError=Error-2*pp->LastError+pp->PrevError; //E(t)-2*E(t-1)+E(t-2)
  pp->PrevError = pp->LastError;
  pp->LastError = Error;
  return (
            pp->Proportion * pError        //比例
            + pp->Integral *Error  //积分项
            + pp->Derivative * dError          // 微分项
                        );  
}
单片机控制推荐这种函数。位置式纯机械运算控制非常有效,比如发动机燃油 “机械控制计算机”。纯凸轮-液压-顶杠机构。

出0入0汤圆

发表于 2012-4-25 21:23:47 | 显示全部楼层
收了。研究下。

出0入0汤圆

发表于 2012-4-25 21:46:43 | 显示全部楼层
单片机没试过用float 宣告 ,会不会导致速度变慢??

出0入0汤圆

发表于 2012-4-27 09:58:30 | 显示全部楼层
10楼的朋友我就是用的你的那个PID温度控制那个,还有很多地方不怎么明白,我QQ393283319加下,希望你帮我解释下,谢谢

出0入0汤圆

发表于 2012-5-1 22:36:21 | 显示全部楼层
学习洛!!

出0入0汤圆

发表于 2012-5-7 00:30:17 | 显示全部楼层
下下来读源码……

出0入0汤圆

发表于 2012-5-7 10:09:19 | 显示全部楼层
收下,有空研究一下!

出0入0汤圆

发表于 2012-5-7 23:41:12 | 显示全部楼层
xjj123456789 发表于 2012-4-17 09:52
PID->derivative = PID->derivative +
                         (PID->dt / ( PID->filter + PID->dt)) *  ...

这一句好像是有问题的
                PID->derivative = PID->derivative +
                        (PID->dt / ( PID->filter + PID->dt)) * (PID->derivative - PID->derivative);

                // update state更新状态
                PID->last_error  = error;
                PID->last_derivative  = PID->derivative;

后面有一个:PID->last_derivative  = PID->derivative;
查找后发现整个程序中只有这一句出现了PID->last_derivative 这个变量,没意义啊。
应该是:
PID->derivative = PID->derivative +
                        (PID->dt / ( PID->filter + PID->dt)) * (PID->last_derivative - PID->derivative);
或者:
PID->derivative = PID->derivative +
                        (PID->dt / ( PID->filter + PID->dt)) * (PID->derivative - PID->last_derivative);

但是我对这个算法还是不理解额……

出0入0汤圆

发表于 2012-5-7 23:41:45 | 显示全部楼层
xjj123456789 发表于 2012-4-17 09:52
PID->derivative = PID->derivative +
                         (PID->dt / ( PID->filter + PID->dt)) *  ...

这一句好像是有问题的

出0入0汤圆

 楼主| 发表于 2012-5-9 10:41:01 | 显示全部楼层
wwwymq 发表于 2012-5-7 23:41
这一句好像是有问题的
                PID->derivative = PID->derivative +
                        (PID->dt / ( PID->filter + PI ...

多谢大家指正,
应该是PID->derivative = PID->derivative +  (PID->dt / ( PID->filter + PID->dt)) * (PID->derivative - PID->last_derivative);

出0入0汤圆

 楼主| 发表于 2012-5-9 10:48:10 | 显示全部楼层
经过大家的指正,经过修改后的PID文件传上来

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-5-10 14:05:35 | 显示全部楼层
应该不错,收藏了。

出0入0汤圆

发表于 2012-5-15 17:48:37 | 显示全部楼层
过后在看 看不懂

出0入0汤圆

发表于 2012-5-17 22:53:28 | 显示全部楼层
顶一下,好东西。。。

出0入0汤圆

发表于 2012-7-28 17:35:48 | 显示全部楼层
看了,还不大懂

出0入0汤圆

发表于 2012-7-30 16:44:29 | 显示全部楼层
好贴,mark一个

出0入0汤圆

发表于 2012-8-3 16:02:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-11-25 20:01:20 | 显示全部楼层
EleHero2012 发表于 2012-5-9 10:41
多谢大家指正,
应该是PID->derivative = PID->derivative +  (PID->dt / ( PID->filter + PID->dt)) * ( ...


错了,应该是
PID->derivative = PID->last_derivative +  (PID->dt / ( PID->filter + PID->dt)) * ( ...
可以看这里:http://en.wikipedia.org/wiki/Low-pass_filter.

出0入0汤圆

发表于 2013-10-7 17:34:52 | 显示全部楼层
位置式

出0入0汤圆

发表于 2013-10-7 18:35:48 | 显示全部楼层
不同的算法,记下先。

出0入0汤圆

发表于 2013-11-9 12:59:34 | 显示全部楼层
开样子 是不错

出0入0汤圆

发表于 2013-11-11 18:34:40 | 显示全部楼层
很不错  学习了

出105入79汤圆

发表于 2013-12-16 03:10:12 | 显示全部楼层
本帖最后由 qwe2231695 于 2013-12-16 03:12 编辑

这个里面带有“不完全微分”优化技术。APM飞控里面就引用了这种方法 。为了避免微分引起的抖动。cuts out the high frequency noise that can drive the controller crazy。

出0入0汤圆

发表于 2013-12-16 05:05:04 来自手机 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2014-8-15 23:46:27 | 显示全部楼层
好不容易找到这样的贴  顶一下  顺便研究一下

出0入0汤圆

发表于 2014-8-16 10:38:22 | 显示全部楼层
也在学习PID控制技术,

出0入0汤圆

发表于 2014-8-16 10:43:06 | 显示全部楼层
mark.......

出0入0汤圆

发表于 2014-8-18 09:16:47 | 显示全部楼层
下载,学习

出0入0汤圆

发表于 2014-8-19 12:38:34 | 显示全部楼层
感谢大神共享

出0入0汤圆

发表于 2014-8-21 22:41:19 | 显示全部楼层
正在努力学习中!!

出0入0汤圆

发表于 2014-8-22 13:20:36 | 显示全部楼层
标记,一种位置式PID的程序实现
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 09:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表