PID算法实现及参数整定图解(附代码)

一、 PID含义

PID是英文单词比例(Proportion),积分(Integral),微分(Differential coefficient)的缩写。PID调节实际上是由比例、积分、微分三种调节方式组成,它们各自的作用如下:

比例调节作用:是按比例反应系统的偏差,系统一旦出现了偏差,比例调节立即产生调节作用用以减少偏差。比例作用大,可以加快调节,减少误差,但是过大的比例,使系统的稳定性下降,甚至造成系统的不稳定。

积分调节作用:是使系统消除稳态误差,提高无差度。因为有误差,积分调节就进行,直至无差,积分调节停止,积分调节输出一常值。积分作用的强弱取决与积分时间常数Ti,Ti越小,积分作用就越强。反之Ti大则积分作用弱,加入积分调节可使系统稳定性下降,动态响应变慢。积分作用常与另两种调节规律结合,组成PI调节器或PID调节器。

微分调节作用:微分作用反映系统偏差信号的变化率,具有预见性,能预见偏差变化的趋势,因此能产生超前的控制作用,在偏差还没有形成之前,已被微分调节作用消除。因此,可以改善系统的动态性能。在微分时间选择合适情况下,可以减少超调,减少调节时间。微分作用对噪声干扰有放大作用,因此过强的加微分调节,对系统抗干扰不利。此外,微分反应的是变化率,而当输入没有变化时,微分作用输出为零。微分作用不能单独使用,需要与另外两种调节规律相结合,组成PD或PID控制器。

离散式PID分为位置型和增量型。

二、 PID位置式计算公式:

 (式1-1)

式中 clip_image002clip_image003 u(n)——第k个采样时刻的控制,T   ——采样周期。

由于计算机的输出u(k)直接控制执行机构(如阀门),u(k)的值与执行机构的位置(如阀门开度)一一对应,所以通常称式(1-1)为位置式PID控制算法。

三、 PID增量式计算公式:

增量式计算公式可由(式1-1)推导得到:

由(1-1)可以得到控制器的第k-1个采样时刻的输出值为:

clip_image005(1-2)

将(1-1)与(1-2)相减并整理,就可以得到增量式PID控制算法公式为:

clip_image007(1-3

其中

clip_image009

由(1-3)可以看出,如果计算机控制系统采用恒定的采样周期T,一旦确定A、B、C,只要使用前后三次测量的偏差值,就可以由(1-3)求出控制量。

增量式PID控制算法与位置式PID算法(1-1)相比,计算量小得多,因此在实际中得到广泛的应用。

位置式PID控制算法也可以通过增量式控制算法推出递推计算公式:

clip_image011(1-4

(1-4)就是目前在计算机控制中广泛应用的数字递推PID控制算法。

式(1-3)也即:

Δu(k)=u(k)-u(k-1) = Kp*Δe(k)+ Ki*e(k)+ Kd*[Δe(k)-Δe(k-1)] ,式中Δe(k)=e(k)-e(k-1)

= Kp*[e(k)-e(k-1) + (T/Ti)*e(k) + Td*((e(k)-2*e(k-1)+e(k-2))/T)] (式1-2)

= Kp*(1+T/Ti+Td/T)*e(k) - Kp*(1+2*Td/T)*e(k-1) + Kp*Td/T*e(k-2)

= A*e(k) - B*e(k-1) + C*e(k-2) (式1-3)

式中:

Δu(k)——控制器(也称调节器)的输出增量;

e(k)——控制器的输入(常常是设定值与被控量之差,即e(k)=r(k)-c(k));

Ki=(Kp*T)/Ti 为积分系数

Kd=(Kp*Td)/T 为微分系数

式中:

T: 计算机控制系统的采样周期,其在选定后就不再改变。其选用原则是在被控系统反馈信号的反应时间要求内,尽量小。但过小会增加运算量。

Kp——控制器的比例放大系数;

Ti——控制器的积分时间;

Td——控制器的微分时间。

四、 优缺点

a) 增量式算法优点:①算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关,容易通过加权处理获得比较好的控制效果;②计算机每次只输出控制增量,即对应执行机构位置的变化量,故机器发生故障时影响范围小、不会严重影响生产过程;③手动—自动切换时冲击小。当控制从手动向自动切换时,可以作到无扰动切换。

b) 位置式PID控制算法的缺点:当前采样时刻的输出与过去的各个状态有关,计算时要对e(k)进行累加,运算量大;而且控制器的输出u(k)对应的是执行机构的实际位置,如果计算机出现故障,u(k)的大幅度变化会引起执行机构位置的大幅度变化。

五、 区别于联系:

1、其实是位置式和增量式是一样的,增量式最后那个输出化解完和位置式一样。增量式PID可以通过 u(k) = u(k-1) + Δu(k) 得到位置式输出

2、增量型算法与位置型算法比较:

(1)增量型算法不需做累加,计算误差后产生的计算精度问题,对控制量的计算影响较小。位置型算法用到过去的误差的累加,容易产生较大的累加误差。

(2)增量型算法得出的是控制的增量,误动作影响小,必要时通过逻辑判断限制或禁止本次输出,不会影响系统的工作。位置型算法的输出是控制量的全部输出,误动作影响大。
(3)是的,增量式算法的主要优势体现在对积分环节的处理上,积分作用的累加效果会影响到输出的准确性。
(4)楼上的说法让我获益不少,一直没理解“避免误动作”的原因。另外,增量式算法易于实现手、自动的无扰动切换。

六、 增量式PID调教总结
1.负反馈

自动控制理论也被称为负反馈控制理论。首先检查系统接线,确定系统的反馈为负反馈。例如电机调速系统,输入信号为正,要求电机正转时,反馈信号也为正(PID算法时,误差=输入-反馈),同时电机转速越高,反馈信号越大。其余系统同此方法。

2.PID调试一般原则

a.在输出不振荡时,增大比例增益P。
b.在输出不振荡时,减小积分时间常数Ti。
c.在输出不振荡时,增大微分时间常数Td。

3.一般步骤

a. 首先选取合适的采样周期T,这里先选取0.05S…待其余参数都调教好后,可再对比修改采样周期T.

clip_image013

T:0.05 Kp:0.85 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

clip_image015

T:0.1 Kp:0.85 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

T:0.2 Kp:0.85 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/mi

clip_image017

T:0.3 Kp:0.85 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

clip_image019

T:0.01 Kp:0.85 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min
b.确定比例增益P

确定比例增益P 时,首先去掉PID的积分项和微分项,一般是令Ti=0、Td=0(具体见PID的参数设定说明),使PID为纯比例调节。输入设定为系统允许的最大值的60%~70%,由0逐渐加大比例增益P,直至系统出现振荡;再反过来,从此时的比例增益P逐渐减小,直至系统振荡消失,记录此时的比例增益P,设定PID的比例增益P为当前值的60%~70%。比例增益P调试完成。

clip_image023

T:0.05 Kp:3 Ti:0 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min(实验证明此时速度加不到1档)

clip_image025

T:0.05 Kp:3 Ti:0.3 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min(此时速度可以达到1档,但超调过大)

clip_image027

T:0.05 Kp:2 Ti:0.3 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

clip_image029

% T:0.05 Kp:1 Ti:0.3 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

c.确定积分时间常数Ti

比例增益P确定后,设定一个较大的积分时间常数Ti的初值,然后逐渐减小Ti,直至系统出现振荡,之后在反过来,逐渐加大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。积分时间常数Ti调试完成。

clip_image031

% T:0.05 Kp:1 Ti:0.4 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

clip_image033

% T:0.05 Kp:1 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

clip_image034

% T:0.05 Kp:0.85 Ti:0.45 Td:0 占空比初始值(电机启动电压对应占空比):1620 速度加到一档400r/min

d.确定微分时间常数Td

积分时间常数Td一般不用设定,为0即可。若要设定,与确定 P和Ti的方法相同,取不振荡时的30%。

e.系统空载、带载联调,再对PID参数进行微调,直至满足要求。


七、 代码

1、C文件

/******************** (C) COPYRIGHT  Adrian *************************************
 * 文件名  :PID.c
 * 描述    :增量式PID算法和位置式PID算法
 * 作者    :Adrian
 * 版本更新: 2016-05-01
 * 硬件连接: 
 * 调试方式:J-Link-OB
**********************************************************************************/	

#include"PID.h"
//采用增量式计算,采样周期为T时间
//Δu(k)=u(k)-u(k-1) = Kp*Δe(k)+ Ki*e(k)+ Kd*[Δe(k)-Δe(k-1)] ,式中Δe(k)=e(k)-e(k-1) 
//											= Kp*[e(k)-e(k-1) + (T/Ti)*e(k) + Td*((e(k)-2*e(k-1)+e(k-2))/T)]			(式1-1)
//											= Kp*(1+T/Ti+Td/T)*e(k) - Kp*(1+2*Td/T)*e(k-1) + Kp*Td/T*e(k-2)
//											= A*e(k) - B*e(k-1) + C*e(k-2)																				(式1-2)




//式中:			
//					Δu(k)——控制器(也称调节器)的输出增量;
//					e(k)——控制器的输入(常常是设定值与被控量之差,即e(k)=r(k)-c(k));
//					Ki=(Kp*T)/Ti 为积分系数
//					Kd=(Kp*Td)/T 为微分系数

//式中:			T:采样周期
//					Kp——控制器的比例放大系数;
//					Ti——控制器的积分时间;
//					Td——控制器的微分时间。



 /**
  * @file   IncrementalPIDInit
  * @brief  增量式PID参数初始化
  * @param  *S:PID结构体   Piont:目标值  T:采样周期   Kp:控制器的比例放大系数   Ti:控制器的积分时间;  Td:控制器的微分时间;
  * @retval 无
  */
void IncrementalPIDInit(IncrementalPID *S, int32_t Piont, double T, double Kp, double Ti, double Td)
{
	S->SetPoint = Piont; 			//目标值
	S->SumError = 0;
	S->A = Kp*(1+T/Ti+Td/T);	//
	S->B = Kp*(1+2*Td/T);	 		//
	S->C = Kp*Td/T;	 					//
	S->NowError = 0;  				//当前误差
	S->LastError = 0; 				//上次误差
	S->PrevError = 0;					//上上次误差	
}


//Position type PID


 /**
  * @file   IncrementalPIDCalc(式1-2)
  * @brief  增量式PID迭代
  * @param  *S:   x:根据反馈量得到的值(属性和Sptr->SetPoint一样)
  * @retval PID调节后控制信号增量
  */
int32_t IncrementalPIDCalc(IncrementalPID *Sptr, int32_t x)
{
	int32_t Out = 0;
	
	
	Sptr->NowError = Sptr->SetPoint - x;


	Out = Sptr->A * Sptr->NowError - Sptr->B * Sptr->LastError + Sptr->C * Sptr->PrevError; //(式1-2)
	
	Sptr->PrevError = Sptr->LastError;
	Sptr->LastError = Sptr->NowError;
	
	return (Out);
}

void PointSetIncrementalPID(IncrementalPID *Sptr, int32_t Piont)//增量式PID设置目标值
{
	Sptr->SetPoint = Piont; //目标值
}
void PointSubIncrementalPID(IncrementalPID *Sptr, int32_t Piont)//增量式PID目标值递减
{
	Sptr->SetPoint = Sptr->SetPoint - Piont; //目标值
}
void PointAddIncrementalPID(IncrementalPID *Sptr, int32_t Piont)//增量式PID目标值递增
{
	Sptr->SetPoint = Sptr->SetPoint + Piont; //目标值
}







 /**
  * @file   IncrementalPIDInit1
  * @brief  增量式PID参数初始化
  * @param  *S:PID结构体   Piont:目标值  T:采样周期   Kp:控制器的比例放大系数   Ti:控制器的积分时间;  Td:控制器的微分时间;
  * @retval 无
  */
void IncrementalPIDInit1(IncrementalPID1 *S, int32_t Piont, double T, double Kp, double Ti, double Td)
{
	S->SetPoint = Piont; 			//目标值
	
	S->Kp = Kp;								//
	S->Ki = Kp*T/Ti;	 				//
	S->Kd = Kp*Td/T;	 				//
	S->NowError = 0;  				//当前误差
	S->LastError = 0; 				//上次误差
	S->PrevError = 0;					//上上次误差	
	S->SumError = 0;
}

 /**
  * @file   IncrementalPIDCalc1(式1-1)
  * @brief  增量式PID迭代
  * @param  *S:   x:根据反馈量得到的值(属性和Sptr->SetPoint一样)
  * @retval PID调节后控制信号增量
  */
int32_t IncrementalPIDCalc1(IncrementalPID1 *Sptr, int32_t NowPoint)
{
	int32_t Out = 0;
	
	
	Sptr->NowError = Sptr->SetPoint - NowPoint;

	Out = Sptr->Kp * (Sptr->NowError - Sptr->LastError) + Sptr->Ki * Sptr->NowError + Sptr->Kd * (Sptr->NowError - 2 * (Sptr->LastError) + Sptr->PrevError); //(式1-1)

	Sptr->PrevError = Sptr->LastError;
	Sptr->LastError = Sptr->NowError;
	
	return (Out);
}

/*********************************************END OF FILE**********************/

2、头文件

#ifndef PID_H__
#define PID_H__

#include "stm32f10x.h"

typedef struct IncrementalPID

{
	int32_t SetPoint; //设定目标 Desired Value
//	double Proportion; //比例常数 Proportional Const
//	double Integral; 	//积分常数 Integral Const
//	double Derivative; //微分常数 Derivative Const
	double A; 	//
	double B; 	//
	double C; 	//
	int32_t NowError;  //Error[0]
	int32_t LastError; //Error[-1]
	int32_t PrevError; //Error[-2]
	int64_t SumError; //误差累计

} IncrementalPID;


void IncrementalPIDInit(IncrementalPID *S, int32_t Piont, double T, double Kp, double Ti, double Td);
int32_t IncrementalPIDCalc(IncrementalPID *Sptr, int32_t x);
void PointSetIncrementalPID(IncrementalPID *Sptr, int32_t Piont);//增量式PID设置目标值	
	
void PointSubIncrementalPID(IncrementalPID *Sptr, int32_t Piont);//增量式PID目标值递减
void PointAddIncrementalPID(IncrementalPID *Sptr, int32_t Piont);//增量式PID目标值递增


// PID结构声明
typedef struct IncrementalPID1
{
	int32_t SetPoint; //设定目标 Desired Value 
	double Kp; //比例常数 Proportional Const 
	double Ki; //积分常数 Integral Const 
	double Kd; //微分常数 Derivative Const 
	int32_t NowError;		//Error[0] 
	int32_t LastError; //Error[-1] 
	int32_t PrevError; //Error[-2] 
	int64_t SumError; //Sums of Errors 
}IncrementalPID1; 


#endif //PID_H__



  • 58
    点赞
  • 527
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
遗传算法是一种通过模拟生物进化过程来优化问题解决方案的算法。在整定PID参数的情况下,遗传算法可以用来找到最优的PID参数组合,以达到最佳的性能表现。 首先,我们需要定义一个适应度函数,以评估给定PID参数组合的性能。适应度函数可以根据实际控制系统的需求来选择,比如可以使用误差均方根(RMSE)来度量控制器的稳定性和精度。 然后,我们需要定义遗传算法的基本操作,包括选择、交叉、变异和替换。选择操作通过根据适应度函数的评估结果选择最优的个体来构建下一代种群。交叉操作将选定的个体进行基因重组,生成新的个体。变异操作随机改变个体的某些基因值,以增加种群的多样性。替换操作用于替换当前种群中较差的个体。 接下来,我们需要编写代码实现上述的基本操作。可以使用C语言来编写遗传算法实现。具体的细节和代码逻辑会依赖于具体的问题和算法设计。 在遗传算法中,最重要的一部分是种群的初始化和演化过程的迭代。种群的初始化可以根据问题的参数范围和算法要求来进行随机生成。演化过程的迭代包括选择、交叉、变异和替换操作的循环执行,直到达到停止准则(如达到最大迭代次数或误差收敛)。 最后,根据遗传算法的结果,选择具有最佳适应度的个体的PID参数组合,并将其应用于实际控制系统,进行性能测试和调整。 总之,通过使用遗传算法整定PID参数,我们可以通过模拟生物进化过程来找到最佳的参数组合,以提高控制系统的性能。编写相应的C代码实现遗传算法的基本操作,并根据算法结果选择最佳的参数组合进行实际应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值