TI中文支持网
TI专业的中文技术问题搜集分享网站

PID控制问题

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

feng shi:

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

/* ==================================================================================
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的差值。
不知我理解的对不对,仅供你参考!谢谢!

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

feng shi:

回复 ??????:

谢谢您的回答,不过_iq换成了float32, _IQ(1.3)换成1.3也可以吧。想换成浮点型的。

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

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

??????:

回复 feng shi:

您好!

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

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

user78960159:

KC

积分修正系数

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

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

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

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

user78960159:

关于PI和PID

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

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

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

JLDN:

回复 user78960159:

你好!

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

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

user78960159:

回复 JLDN:

sprc077

 下这个装下 在DOC里

/* ==================================================================================
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也可以吧。想换成浮点型的。

谢谢

feng shi:

回复 user78960159:

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

赞(0)
未经允许不得转载:TI中文支持网 » PID控制问题
分享到: 更多 (0)