This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PID控制问题

Other Parts Discussed in Thread: CONTROLSUITE
/* ==================================================================================
File name:       PID_REG3.H  (IQ version)                    
=====================================================================================*/

#ifndef __PIDREG3_H__
#define __PIDREG3_H__

typedef struct {  _iq  Ref;   			// Input: Reference input 
				  _iq  Fdb;   			// Input: Feedback input 
				  _iq  Err;				// Variable: Error
				  _iq  Kp;				// Parameter: Proportional gain
				  _iq  Up;				// Variable: Proportional output 
				  _iq  Ui;				// Variable: Integral output 
				  _iq  Ud;				// Variable: Derivative output 	
				  _iq  OutPreSat; 		// Variable: Pre-saturated output
				  _iq  OutMax;		    // Parameter: Maximum output 
				  _iq  OutMin;	    	// Parameter: Minimum output
				  _iq  Out;   			// Output: PID output 
				  _iq  SatErr;			// Variable: Saturated difference
				  _iq  Ki;			    // Parameter: Integral gain
				  _iq  Kc;		     	// Parameter: Integral correction gain
				  _iq  Kd; 		        // Parameter: Derivative gain
				  _iq  Up1;		   	    // History: Previous proportional output
		 	 	} PIDREG3;	            

typedef PIDREG3 *PIDREG3_handle;
/*-----------------------------------------------------------------------------
Default initalizer for the PIDREG3 object.
-----------------------------------------------------------------------------*/                     
#define PIDREG3_DEFAULTS { 0, 			\
                           0, 			\
                           0, 			\
                           _IQ(1.3), 	\
                           0, 			\
                           0, 			\
                           0, 			\
                           0, 			\
                           _IQ(1), 		\
                           _IQ(-1), 	\
                           0, 			\
                           0, 			\
                           _IQ(0.02), 	\
                           _IQ(0.5), 	\
                           _IQ(1.05), 	\
                           0, 			\
              			  }

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


#define PID_REG3_MACRO(v)																					\
	v.Err = v.Ref - v.Fdb; 									/* Compute the error */						\
	v.Up= _IQmpy(v.Kp,v.Err);								/* Compute the proportional output */		\
	v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr);	/* Compute the integral output */			\
	v.OutPreSat= v.Up + v.Ui;								/* Compute the pre-saturated output */		\
	v.Out = _IQsat(v.OutPreSat, v.OutMax, v.OutMin);		/* Saturate the output */					\
	v.SatErr = v.Out - v.OutPreSat;							/* Compute the saturate difference */		\
	v.Up1 = v.Up;											/* Update the previous proportional output */

#define PID_REG3_POS_MACRO(v)																			\
	v.Err = v.Ref - v.Fdb; 									/* Compute the error */						\
	if (v.Err >= _IQ(0.5))  																			\
		v.Err -= _IQ(1.0); 									/* roll in the error */	    				\
	else if (v.Err <= _IQ(-0.5))  																		\
		v.Err += _IQ(1.0); 	        						/* roll in the error */	    				\
	v.Up= _IQmpy(v.Kp,v.Err);								/* Compute the proportional output */		\
	v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr);	/* Compute the integral output */			\
	v.Ud = _IQmpy(v.Kd,(v.Up - v.Up1));																	\
	v.OutPreSat= v.Up + v.Ui + v.Ud;						/* Compute the pre-saturated output */		\
	v.Out = _IQsat(v.OutPreSat, v.OutMax, v.OutMin);		/* Saturate the output */					\
	v.SatErr = v.Out - v.OutPreSat;							/* Compute the saturate difference */		\
	v.Up1 = v.Up;
#endif // __PIDREG3_H__

// Add the lines below if derivative output is needed following the integral update

位置在ti\controlSUITE\libs\app_libs\motor_control\math_blocks\v4.3/

在给出的文档中似乎没有对这个的说明(看大家用的这个,也打算用这个。把Kd设为0就是PI了吧)

1、Kc,积分校正增益,没明白是什么作用

2、这个是增量式PID吗?

3、SatErr,饱和差,好像是v->SatErr = v->Out - v->OutPreSat;,但不知道什么用

4、v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr);也即是// Compute the integral output
v->Ui = v->Ui +v->Ki*v->Up + v->Kc*v->SatErr;其中的v->Kc*v->SatErr;怎么理解啊,为什么加上v->Ki*v->Up + v->Kc*v->SatErr,加上当前误差乘以Ki不就可以了吗?

5、// Compute the derivative output
v->Ud = v->Kd*(v->Up - v->Up1);计算微分的时候为什么用的是比例输出。

6、_iq换成了float32, _IQ(1.3)换成1.3也可以吧。想换成浮点型的。

谢谢

  • 这个大家谁知道吗,不需要回答全部,回答下您知道的就可以,非常感谢。

  • 你好!

          我是一个DSP的菜鸟不知理解的对不对,2你的这个算法好像不是增量式的PID,好像是位置式的PID,

    Up= _IQmpy(v.Kp,v.Err),比例环节,
    Ui= v.Ui + _IQmpy(v.Ki,v.Up)积分环节,
    Ud = _IQmpy(v.Kd,(v.Up - v.Up1))微分环节,饱和差我也不是很清楚,但是位置式的PID由于积分一直在累加求和因此需要退饱和,具体怎么退饱和我没有接触过所以我说不清楚。
    Ud = v->Kd*(v->Up - v->Up1)这是微分环节离散化之后的公式,以上的三个PID都是经过离散化的,
    Kd(du/dt),离散化就是前后两个时间的差值,也就是
    Kd*(v->Up - v->Up1)。
    而增量式PID比位置式的多一步,增量式是前后两个时间位置PID的差值。
    不知我理解的对不对,仅供你参考!谢谢!
  • 谢谢您的回答,不过_iq换成了float32, _IQ(1.3)换成1.3也可以吧。想换成浮点型的。

    Ui= v.Ui + _IQmpy(v.Ki,v.Up)积分环节,这个是得出积分的输出,但是不应该是
    v.Ui +KI*Err吗,为什么是_IQmpy(v.Ki,v.Up),谢谢
  • 您好!

    关于这个问题,我也有疑问,我比较同意你的看法v.Ui +KI*Err,不知是不是这个PID中间还有其他的传递环节,因为我上面写的那个参考是最简单的数学模型,你的这个应该比较复杂点,所以我也没什么把握!我再查查资料,如果你弄明白了也请给我留言谢谢!

  • KC

    积分修正系数

    以直流有刷电动机转速电流双闭环控制算法为例,控制环路有两个:转速环和电流环。

    转速环的PI控制器可以饱和,然而电流是瞬态量,因此内环的PI控制器是不允许饱和的,因此电流环的PI控制器有3个参数,比例、积分和抗积分饱和修正系数(Kc)

    因为控制器饱和以后是失效的状态,从饱和到推饱和是需要时间的,这个延时对电流环控制来讲是不允许的,所以电流环要用抗积分饱和PI控制器

  • 关于PI和PID

    之前查到个说法 说电机控制系统是单极点系统,不存在多极点系统引起的滞后问题

    所以一般用PI,没必要用PID

  • 我新下载了control suit ,但是找到的pid_reg3.h和你的不一样

    我的文件位置是:

    内容:

    /* ==================================================================================
    File name: PID_REG3.H (IQ version)
    =====================================================================================*/

    #ifndef __PIDREG3_H__
    #define __PIDREG3_H__

    typedef struct { _iq Ref; // Input: Reference input
    _iq Fdb; // Input: Feedback input
    _iq Err; // Variable: Error
    _iq Kp; // Parameter: Proportional gain
    _iq Up; // Variable: Proportional output
    _iq Ui; // Variable: Integral output
    _iq Ud; // Variable: Derivative output
    _iq OutPreSat; // Variable: Pre-saturated output
    _iq OutMax; // Parameter: Maximum output
    _iq OutMin; // Parameter: Minimum output
    _iq Out; // Output: PID output
    _iq SatErr; // Variable: Saturated difference
    _iq Ki; // Parameter: Integral gain
    _iq Kc; // Parameter: Integral correction gain
    _iq Kd; // Parameter: Derivative gain
    _iq Up1; // History: Previous proportional output
    } PIDREG3;

    typedef PIDREG3 *PIDREG3_handle;
    /*-----------------------------------------------------------------------------
    Default initalizer for the PIDREG3 object.
    -----------------------------------------------------------------------------*/
    #define PIDREG3_DEFAULTS { 0, \
    0, \
    0, \
    _IQ(1.3), \
    0, \
    0, \
    0, \
    0, \
    _IQ(1), \
    _IQ(-1), \
    0, \
    0, \
    _IQ(0.02), \
    _IQ(0.5), \
    _IQ(1.05), \
    0, \
    }

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


    #define PID_MACRO(v) \
    v.Err = v.Ref - v.Fdb; /* Compute the error */ \
    v.Up= _IQmpy(v.Kp,v.Err); /* Compute the proportional output */ \
    v.Ui= v.Ui + _IQmpy(v.Ki,v.Up) + _IQmpy(v.Kc,v.SatErr); /* Compute the integral output */ \
    v.OutPreSat= v.Up + v.Ui; /* Compute the pre-saturated output */ \
    v.Out = _IQsat(v.OutPreSat, v.OutMax, v.OutMin); /* Saturate the output */ \
    v.SatErr = v.Out - v.OutPreSat; /* Compute the saturate difference */ \
    v.Up1 = v.Up; /* Update the previous proportional output */

    #endif // __PIDREG3_H__

    // Add the lines below if derivative output is needed following the integral update
    // v.Ud = _IQmpy(v.Kd,(v.Up - v.Up1));
    // v.OutPreSat = v.Up + v.Ui + v.Ud;

    其中没有你的

    PID_REG3_MACRO(v)和PID_REG3_POS_MACRO(v)

    这两个

    PID_REG3_MACRO(v)是PI

    PID_REG3_POS_MACRO(v)是PID

    你的问题2到5,pid_reg3.pdf的这两页可以接到,你看下推导下就明白了

    应该是位置式的PID

  • 你好!

    请问pid_reg3.pdf的位置在哪里?谢谢!

  • sprc077

     下这个装下 在DOC里

  • 好的好的,我看下,非常感谢您,谢谢

  • 我第一次看这个代码的时候也有和你一样的疑问,

    主观上理解PID控制器的输出,不就是比例 加 积分 加微分嘛

    但是你看这个代码里:

    你也提到了微分怎么和比例有关系呢?

    再有你看,其实还有积分部分还涉及到了比例系数和积分系数相乘呢,更不可理解。

    但是看看文档,推到下,这些也就不是疑问了

  • 你好!

    我想请教一下,就是如果我想用DSP去控制BUCK式的降压电路的PWM驱动。实现输出电压或者电流的控制。使用的PID控制是用增量式的PID控制还是位置式的。哪种好?谢谢!

  • 位置式PID有一定的抗干扰性,增量式的反应比较快,看你怎么应用了

  • 看个文档,这样说的位置式PI 调节器这种算法的优点是计算精度比较高,缺点是每次都要对e(k) 进行累加, 很容易出现积分饱和的情况。但现在有抗积分饱和的了。

    增量式 PI 算法与位置式 PI 算法并没有本质的区别,只是增量式 PI 算法控制的是执行机构的增量 Δu(k),这种算法的优点在于:由于输出的是增量,因此 计算错误时的产生的影响较小,这种算法的缺点在于:每次计算 Δu(k)再与前次 的计算结果u(k 1) 相加得到本次的控制输出,这就使得 Δu(k)的截断误差被逐次的累加起来,输出的误差加大。

    只是照书上说的。你考虑下

  • http://www.deyisupport.com/cfs-file.ashx/__key/communityserver-discussions-components-files/56/2068._9E58CF910F5F_pid_8C544D4F6E7F0F5F_pid_F876D46B04540967C04E484E184F3A7FB9701FFF_-_2D00_-_E5774E4E_.pdf

    这是知乎上面的一个帖子 写的很好 

    你仔细看下这个帖子 再去理解下TI的位置式PID_REG3和北京航空航天大学出版社出版的《电动机的DSP控制——TI公司》这本书里提到的增量式PID

    知乎的这个帖子即从理论上又从编程实现上对比了两种算法的区别

    feng shi的解释书本化 百度上搜的很多博客也是这么写的;bad提到的位置式具有一定的炕扰性,增量式反应比较快,我不清楚从原理上怎么体现出这些区别

    知乎的这个解释还是挺好的 建议jin chao yang看下

  • 谢谢haichao zhang ! 受教了。

  • 我总结了下 写到我的个人微信公众号了 你可以看看

    https://mp.weixin.qq.com/s?__biz=MzI2NDE4NTQ5NA==&mid=2657808641&idx=1&sn=101fa7ce554e4d51d9a02a26571470c5&chksm=f12e22f8c659abee54a93b934c5f8992adc5752513137c12a133c7a762e7331b091c199fe921&scene=0&key=c81d77271180a0e62461a725234a604d1a20a51c8d71a59a86241577191211e1d6133de18ee3732ec69b7f671b62652d5093c46b27b1b4fb85c6aff4a42ba7ff6ad9e68de7df4f81389a1250d8fbc31b&ascene=7&uin=MjgwNzA5NDkzMg%3D%3D&devicetype=android-22&version=26031f30&nettype=cmnet&abtest_cookie=AQABAAgAAQAkhh4AAAA%3D&pass_ticket=mRYEiupMywwCUHbOBhzmYskXjc85k9xx643ughbLKY%2Fddboo0AZ3MHujeXyRQiPj&wx_header=1

  • 谢谢张工! 学习学习!

  • 你好,我想问下,在公式中T和Ti的关系是什么意思,或者说T比Ti大多少,或者小多少,有个参考值概念吗?
x 出现错误。请重试或与管理员联系。