EleHero2012 发表于 2012-4-1 17:11:21

一种位置式PID的程序实现

我在网上搜到一个PID的程序,看起来不错,而且微分环节还带低通滤波的,
然后稍加修改留给自己用,应该可以用吧,请大家看看怎么样

fusion 发表于 2012-4-1 21:02:46

还没看 先顶一下

shanyan 发表于 2012-4-1 21:04:45

先顶一下{:lol:}

EleHero2012 发表于 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;
}

gxy508 发表于 2012-4-2 21:34:45

顶起来了

xjj123456789 发表于 2012-4-17 09:50:25

看了楼主的帖子后受益匪浅,绑定

xjj123456789 发表于 2012-4-17 09:52:00

PID->derivative = PID->derivative +
                         (PID->dt / ( PID->filter + PID->dt)) * (PID->derivative - PID->derivative);
这句话是不是后面有问题啊,这个滤波是怎么起作用的

EleHero2012 发表于 2012-4-17 10:11:24

这个式子有低通滤波的作用,具体原理我也不太清楚,不过应该是对的,我在很多地方都看到过。

xue_xi_zhong 发表于 2012-4-18 22:32:18

好,有空看看

bg8wj 发表于 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输出的是控制量增量,若计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。

bg8wj 发表于 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*+Ki*E(t)+Kd*
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          // 微分项
                        );
}
单片机控制推荐这种函数。位置式纯机械运算控制非常有效,比如发动机燃油 “机械控制计算机”。纯凸轮-液压-顶杠机构。

myh_hh 发表于 2012-4-25 21:23:47

收了。研究下。

ali1019 发表于 2012-4-25 21:46:43

单片机没试过用float 宣告 ,会不会导致速度变慢??

xielong4183 发表于 2012-4-27 09:58:30

10楼的朋友我就是用的你的那个PID温度控制那个,还有很多地方不怎么明白,我QQ393283319加下,希望你帮我解释下,谢谢

椿笙 发表于 2012-5-1 22:36:21

学习洛!!

wwwymq 发表于 2012-5-7 00:30:17

下下来读源码……

zhgyinfo 发表于 2012-5-7 10:09:19

收下,有空研究一下!

wwwymq 发表于 2012-5-7 23:41:12

xjj123456789 发表于 2012-4-17 09:52 static/image/common/back.gif
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);

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

wwwymq 发表于 2012-5-7 23:41:45

xjj123456789 发表于 2012-4-17 09:52 static/image/common/back.gif
PID->derivative = PID->derivative +
                         (PID->dt / ( PID->filter + PID->dt)) *...

这一句好像是有问题的

EleHero2012 发表于 2012-5-9 10:41:01

wwwymq 发表于 2012-5-7 23:41 static/image/common/back.gif
这一句好像是有问题的
                PID->derivative = PID->derivative +
                        (PID->dt / ( PID->filter + PI ...

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

EleHero2012 发表于 2012-5-9 10:48:10

经过大家的指正,经过修改后的PID文件传上来

bosw83 发表于 2012-5-10 14:05:35

应该不错,收藏了。

sz_works 发表于 2012-5-15 17:48:37

过后在看 看不懂

litaov2010 发表于 2012-5-17 22:53:28

顶一下,好东西。。。

Gloome 发表于 2012-7-28 17:35:48

看了,还不大懂

sysbreaker 发表于 2012-7-30 16:44:29

好贴,mark一个

lcmdw 发表于 2012-8-3 16:02:35

mark{:smile:}

pxpx601 发表于 2012-11-25 20:01:20

EleHero2012 发表于 2012-5-9 10:41 static/image/common/back.gif
多谢大家指正,
应该是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.

Pao_fu 发表于 2013-10-7 17:34:52

位置式

liang_work 发表于 2013-10-7 18:35:48

不同的算法,记下先。

yaonen 发表于 2013-11-9 12:59:34

开样子 是不错

477748703 发表于 2013-11-11 18:34:40

很不错学习了

qwe2231695 发表于 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。

wsm80828 发表于 2013-12-16 05:05:04

谢谢分享

电气工程化动自 发表于 2014-8-15 23:46:27

好不容易找到这样的贴顶一下顺便研究一下

TNTHUAHUA 发表于 2014-8-16 10:38:22

也在学习PID控制技术,

机器人天空 发表于 2014-8-16 10:43:06

mark.......

leicai05 发表于 2014-8-18 09:16:47

下载,学习

nhw1234 发表于 2014-8-19 12:38:34

感谢大神共享

votasee 发表于 2014-8-21 22:41:19

正在努力学习中!!

BrightWang 发表于 2014-8-22 13:20:36

标记,一种位置式PID的程序实现
页: [1]
查看完整版本: 一种位置式PID的程序实现