pid控制电机(待完善)

60 篇文章 12 订阅

 

PID含义

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

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

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

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

PID调试一般原则:

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

代码例子1

P参数越大,系统的响应速度就越快,目标值与实际值的差值来实时决定的,误差越大,计算出来的PWM就越大,误差越小计算出来的PWM就越小,而P参数就相当于一条直线的斜率,斜率越大,纵坐标对于横坐标的变化就越敏感,也就是系统对于外界的变化的响应速度越快。

int PwmPID_Kp  = 2;
void SetSpeed(u16 PwmSet,u16 PwmReal)//入口参数:目标值,实际值
{
      int PwmError=0,PwmIncPWM=0 ;

      PwmError=PwmSet-PwmReal;//本次偏差等于目标值减去实际值
      PwmError = PwmError>>5;
      PwmIncPWM=(int)(PwmPID_Kp*PwmError);
      PwmMotor_L+=PwmIncPWM;
      PwmMotor_R-=PwmIncPWM;
      if(PwmMotor_L>=100)
          PwmMotor_L=100;
      else if(PwmMotor_L<=10)
          PwmMotor_L=10;

      if(PwmMotor_R>=100)
          PwmMotor_R=100;
      else if(PwmMotor_R<=10)
          PwmMotor_R=10;
      
    TIM_SetCompare2(TIM5 , PwmMotor_L);  
    TIM_SetCompare1(TIM5 , PwmMotor_R); 
    
     xprintf("\r\n test PwmMotor_L=%d  PwmMotor_R=%d  PwmIncPWM=%d\r\n",PwmMotor_L,PwmMotor_R,PwmIncPWM);

}

例子2

///


//PID偏差控制计算
void PIDControl()        //pid偏差计算
{
	e=SpeedSet-num;//设置速度-实际速度,两者的差值 
	//对应于增量式PID的公式Δuk=uk-u(k-1)
//	duk=(Kp*(e-e1))/100;//只调节P
	duk=(Kp*(e-e1)+Ki*e)/100;//只调节PI
//	duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2))/100;//调节PID
	uk=uk1+duk;//uk=u(k-1)+Δuk
	out=(int)uk;//取整后输出
	if(out>250)	//设置最大限制
		out=250;
	else if(out<0)//设置最小限制
		out=0;
	uk1=uk;		  //为下一次增量做准备
	e2=e1;
	e1=e;
	PWMTime=out;  //out对应于PWM高电平的时间

例子3

/******************** (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**********************/

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值