一、原理

  1. PID控制原理 一 (开闭环控制)

  2. PID控制原理 二(PID使用详解)

  3. PID控制原理 三 (控制系统硬件选择与仿真)

二、PID控制算法的公式:

 

 对其进行离散化:

 

 

 刚开始对小车的速度控制采用位置式PID控制算法,即常用的PID控制算法。但是位置式PID算法使用过去误差的累加值,容易产生较大的累计误差。而且由于小车的目标速度时刻在变化,err值需要不断的累加,可能出现err_sum溢出的情况。因此对位置式加以变换,得到增量式PID控制算法:

参见https://blog.csdn.net/lygeneral/article/details/105010950?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1.essearch_pc_relevant&spm=1001.2101.3001.4242

三、分段PID

分段PID不是指不同的速度对应不同的PID的值,不同于模糊PID的控制方法,我的分段是根据设定值与反馈值得偏差来进行分段控制。

https://blog.csdn.net/tingfenghanlei/article/details/81302833?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.essearch_pc_relevant

四、代码实现

https://blog.csdn.net/kilotwo/article/details/79952530?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-12.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-12.essearch_pc_relevant

/**************************************************************************
函数功能:增量PI控制器
入口参数:编码器测量值,目标速度
返回  值:电机PWM
根据增量式离散PID公式 
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
e(k)代表本次偏差 
e(k-1)代表上一次的偏差  以此类推 
pwm代表增量输出
在我们的速度控制闭环系统里面,只使用PI控制
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)
**************************************************************************/
int Incremental_PI (int Encoder,int Target)
{   
   float Kp=20,Ki=30;   
     static int Bias,Pwm,Last_bias;         //相关内部变量的定义。
     Bias=Encoder-Target;                //求出速度偏差,由测量值减去目标值。
     Pwm+=Kp*(Bias-Last_bias)+Ki*Bias;   //使用增量 PI 控制器求出电机 PWM。
     Last_bias=Bias;                       //保存上一次偏差 
     return Pwm;                         //增量输出
}
/**************************************************************************
函数功能:位置式PID控制器
入口参数:编码器测量位置信息,目标位置
返回  值:电机PWM
根据位置式离散PID公式 
pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差 
e(k-1)代表上一次的偏差  
∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;
pwm代表输出
**************************************************************************/
int Position_PID (int Encoder,int Target)
{   
     float Position_KP=80,Position_KI=0.1,Position_KD=500;
     static float Bias,Pwm,Integral_bias,Last_Bias;
     Bias=Encoder-Target;                                  //求出速度偏差,由测量值减去目标值。
     Integral_bias+=Bias;                                    //求出偏差的积分
     Pwm=Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias);       //位置式PID控制器
     Last_Bias=Bias;                                       //保存上一次偏差 
     return Pwm;                                           //增量输出
}

五、用Excel教会你PID算法

参见https://blog.csdn.net/Firefly_cjd/article/details/118977801

举例说明,当前小车速度为0.2,目标速度是1。输出y和输入x的关系是y=1*x。比例系数Kp=0.5。随着时间的增大,输出和输入关系如下。

 

 

其他

typedef struct MyPID
{
	int Target;   //设定目标
	int Uk;       //PID输出
	int Udk;      //PID增量
	int Uk_1;     //保存上一次PID输出
	int P;
	int I;
	u8  b;  //是否积分运算标志
	int D;
	int ek_0;//当前误差
	int ek_1;//上一次误差
	int ek_2;//上上次误差
}PID;

PID Speed_PID;     //定义一个变量,分布了具体的内存空间
PID *Speed_Point = &Speed_PID;

/*********初始化PID**********/
void PIDInit()
{
	Speed_Point->Target = ;
	Speed_Point->Uk = 0;
	Speed_Point->Udk = 0;
	Speed_Point->Uk_1 = ;
	Speed_Point->P = 3;
	Speed_Point->I = 1;
	Speed_Point->b = 1;
	Speed_Point->D = 1;
	Speed_Point->ek_0         = 0;         //ek=0
    Speed_Point->ek_1         = 0;         //ek-1=0
    Speed_Point->ek_2         = 0;          //ek-2=0
}

//输入位置环偏差输出(设定值),输入当前速度值(测定值)
int SpeedPID(int placeout,int g_Speed_Count)
{
	Speed_Point->ek_0 = placeout-g_Speed_Count;  //偏差计算
	Speed_Point->Udk = Speed_Point->P*(Speed_Point->ek_0-Speed_Point->ek_1)+Speed_Point_b*Speed_Point->I*Speed_Point->ek_0;   //增量计算
	Speed_Point->Uk = Speed_Point->Uk1+Speed_Point->Udk;//PID输出
//保存误差,用于下一次计算
	Speed_Point->ek_2 = Speed_Point->ek_1;
	Speed_Point->ek_1 = Speed_Point->ek_0;
	Speed_Point->Uk_1 = Speed_Point->Uk;
	if(Speed_Point->Uk >= PWM_Max)
	{
		return PWM_Max;
	}
	else if(Speed_Point->Uk <= PWM_Min)
	{
		return PWM_Min;
	}
	return(Speed_Point->Uk);
}

1、在整定PID控制器参数时,可以根据控制器的参数与系统动态性能和稳态性能之间的定性关系,用实验的方法来调节控制器的参数。有经验的调试人员一般可以较快地得到较为满意的调试结果。在调试中最重要的问题是在系统性能不能令人满意时,知道应该调节哪一个参数,该参数应该增大还是减小。
2、为了减少需要整定的参数,首先可以采用PI控制器。
为了保证系统的安全,在调试开始时应设置比较保守的参数,例如比例系数不要太大,积分时间不要太小,以避免出现系统不稳定或超调量过大的异常情况。
3、给出一个阶跃给定信号,根据被控量的输出波形可以获得系统性能的信息,例如超调量和调节时间。应根据PID参数与系统性能的关系,反复调节PID的参数。
如果阶跃响应的超调量太大,经过多次振荡才能稳定或者根本不稳定,应减小比例系数、增大积分时间。如果阶跃响应没有超调量,但是被控量上升过于缓慢,过渡过程时间太长,应按相反的方向调整参数。
4、如果消除误差的速度较慢,可以适当减小积分时间,增强积分作用。
反复调节比例系数和积分时间,如果超调量仍然较大,可以加入微分控制,微分时间从0逐渐增大,反复调节控制器的比例、积分和微分部分的参数。
5、总之,PID参数的调试是一个综合的、各参数互相影响的过程,实际调试过程中的多次尝试是非常重要的,也是必须的。

有关pid自动调节时间的范围是多少,自动调谐过程初期,输出步长值会按比例调整一次,pid自动调节时间,注意PID常用口诀,并使用一看二调多分析的方法,掌握自动调谐序列的用法。

pid自动调节时间的范围

1、PID常用口诀

参数整定找最佳,从小到大顺序查,先是比例后积分,最后再把微分加,曲线振荡很频繁,比例度盘要放大,曲线漂浮绕大湾,比例度盘往小扳,曲线偏离回复慢,积分时间往下降,曲线波动周期长,积分时间再加长,曲线振荡频率快,先把微分降下来,动差大来波动慢,微分时间应加长,理想曲线两个波,前高后低4比1,

2、一看二调多分析,调节质量不会低

PID控制器参数的工程整定

自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。

这就是说,在控制器中仅引入“比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。

自动调谐序列

在确定了滞后值和偏差值后,自动调谐序列就会开始。此调谐过程开始于在回路输出上施加初始输出步长。

此输出值的改变应会导致进程变量值的相应改变。当输出变化将PV推离设定值足够远以至于超出滞后边界时,自动调谐器就会检测到一个过零事件。在每次发生过零事件时,自动调谐器将向相反方向推动输出。

调谐器会继续对PV进行抽样和等待下一个过零事件。此序列总共需要十二个过零才能完成。所观察到的峰到峰PV值幅度(峰值误差)和过零发生的速率与此进程的动态特性直接相关。

在自动调谐过程初期,输出步长值会按比例调整一次,从而令随后的PV峰到峰摆动更接近欲用的偏差值。一旦做出此调整后,新的输出步长值将写入回路表的"实际步长"
域(ASTEP)。

如果两次过零之间的时间超出过零看门狗间隔时间,自动调谐序列将以错误告终。过零看门狗间隔时间的默认值为两小时。

有些PID回路变化慢12个过零动作需要很长很长时间。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐