PID参数整定
背景介绍
线控底盘作为移动机器人的重要组成部分,显得尤为重要。对于线控底盘而言,其重要技术有二。其一是底盘控制技术,其二是底盘通信技术。对于底盘控制技术而言,主要是通过对底盘的运动学建模,运用一定的算法实现对底盘的基本运动控制。常见的移动底盘的运动学模型大多为差速运动模型,即底盘通过左右轮的差速实现基本的线速度(以一定的线速度进行前后运动)、角速度(以一定的角速度进行顺时针、逆时针旋转)运动。通过对不同模型的运动学求解,可以分别得出每个驱动电机的转速值,在运动中,只要保证每个电机按照给定的转速旋转,就能实现底盘的精准运动控制。故而,电机转速精准控制就显得尤为重要。在此,主要分享一下近来我在电机转速控制方面的一点心得,愿与大家共同学习,同时也是记录自己的技术成长之路。刚开始写博客,望诸位大神多多关照!!!
硬件平台
直流减速电机
在某宝上买了一款直流减速电机,该电机自带霍尔编码器编码器,其分辨率为260线,通过4倍频处理后可将分辨率提升至1040线,该值是对于减速电机的输出轴而言,即减速电机的输出轴旋转一周,编码器产生1040个脉冲,该电机的工作电压7~13V。电机及编码器实物如下图所示:
电机及编码器实物:
STM32F103控制器及其外围电路
电机的控制器使用stm32f103的最小系统搭建,其控制电路图及控制电路实物图如下所示:
控制电路图:
控制电路实物图:
软件平台
虚拟示波器(平衡小车之家开发)
为了方便调试,使用串口通信将电机的目标转速与实际转速对应的编码器值发送至PC端(发送周期设为
10
m
s
@
100
H
z
10ms@100Hz
10ms@100Hz),并使用一个虚拟示波器(平衡小车之家开发)实时显示,使得调试变得简单、直观。虚拟示波器如下图所示:
虚拟示波器:
算法简介
增量式PID
为了实现对电机速度的控制,采用M法测速,控制周期设为10ms@100Hz,使用增量式PID算法。关于PID算法的理论,网上有很多,大家可以自行搜索。这里直接上增量式PID算法的数学离散表达式:
o
u
t
=
o
u
t
+
k
p
∗
[
e
(
k
)
−
e
(
k
−
1
)
]
+
k
i
∗
e
(
k
)
+
k
d
∗
[
e
(
k
)
−
2
∗
e
(
k
−
1
)
+
e
(
k
−
2
)
]
\ out = out + kp*[e(k)-e(k-1)]+ki*e(k)+kd*[e(k)-2*e(k-1)+e(k-2)]
out=out+kp∗[e(k)−e(k−1)]+ki∗e(k)+kd∗[e(k)−2∗e(k−1)+e(k−2)]
C代码实现
//out += kp*[e(k)-e(k-1)]+ki*e(k)+kd*[e(k)-2*e(k-1)+e(k-2)]
int increacementPID(const int val_tar, const int val_rel)
{
const float kp = 62.5; //set kp as 62.5
const float ki = 5.5; //set ki as 5.5
const float kd = 48; //set kd as 48
static float err, err_last, err_last2 , val_cal; //define varables:err->当前偏差(e(k)), err_last->上一次偏差e(k-1), err_last2->上上次偏差(e(k-2)), val_cal->计算结果(out)
err = val_rel - val_tar; //renew err
val_cal += kp*(err- err_last) + ki*err+ kd*(err-2*err_last+err_last2); //calculate val_cal
err_last2 = err_last; //renew err_last2
err_last = err; //renew err_last
//encoder varable magnitude limited
if(val_cal > enc_dc_max) val_cal = enc_dc_max;
else if(val_cal < -enc_dc_max) val_cal = -enc_dc_max;
else ;
return val_cal; //return result->val_cal
}
参数整定
整定思路,按照参数的整定顺序,主要分成3步: k p kp kp-> k i ki ki-> k d kd kd。即先整定 k p kp kp,使系统的响应在目标值50%附近振荡;然后加入积分作用,调整 k i ki ki,使系统的响应静差为0,此时,系统的响应仍然存在较大的超调量;最后加入微分作用,调整 k d kd kd,降低系统的超调量,使系统的响应振荡消失,增强系统的抗干扰性能,平滑整个响应。
整定步骤
通过设定定时器定时 10 m s @ 100 H z 10ms@100Hz 10ms@100Hz,定时调用我们的增量式PID控制函数increacementPID(const int val_tar, const int val_rel),实现100Hz的控制频率。这里,我们将所有的目标转速编码值val_tar统一设为35,之后的控制都是根据这个目标值进行控制、调节。同时为了滤掉编码器测得值的噪声,我们设计了一个10阶的FIR低通滤波器对编码器的值进行数字滤波处理。
int CNT_TAR[2] = {30, 30}; //define target encoder cnt and init as 30
int CNT_REAL[2]; //define real encoder cnt
void TIM1_IRQHandler(void) //T = 10ms@100Hz
{
static int dc; //define the
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
//ctrl moudle
CNT_REAL[0] = filter_FIR(Read_Encoder(2)); //use FIR filter to filter and renew the encoder value
//pid controller->velocity loop(cnt/10ms)
dc = increacementPID(CNT_TAR[0], CNT_REAL[0]); //calculate the control value
pwmSetting(dc); //set the control value to the PWM generating moudle
}
}
STEP0:整定 k p kp kp
在一个控制系统中,对于 k p kp kp,其通常起关键作用,调好了 k p kp kp,整个系统就成功了一大半。我们的目标是调整 k p kp kp使得系统的响应曲线在目标值的50%处振荡。
S0.0 测试判断 k p kp kp的极性
首先,我们需要测试判断
k
p
kp
kp的极性,可以先取
k
p
=
−
100
kp = -100
kp=−100,
k
i
=
0
ki = 0
ki=0,
k
d
=
0
kd = 0
kd=0,通过虚拟示波器查看系统的响应曲线如下(注:图中黄线为目标曲线,紫线为系统响应曲线,以下响应曲线相同):
系统响应曲线图[
k
p
=
−
100
kp = -100
kp=−100
k
i
=
0
ki = 0
ki=0
k
d
=
0
kd = 0
kd=0]:
通过响应曲线我们可以看出,编码器的反馈值远远偏离目标值,初始响应方向与目标值相反,且整个响应在目标值附近大幅度振荡,故而kp的极性反了,因此,我们再取
k
p
=
100
kp = 100
kp=100,
k
i
=
0
ki = 0
ki=0,
k
d
=
0
kd = 0
kd=0,通过虚拟示波器查看系统的响应曲线如下:
系统响应曲线图[
k
p
=
100
kp = 100
kp=100
k
i
=
0
ki = 0
ki=0
k
d
=
0
kd = 0
kd=0]:
通过响应曲线我们可以看出,编码器的反馈值与目标值方向一致,因此,
k
p
kp
kp的极性为正。
S0.1 确定 k p kp kp取值
以上的
k
p
kp
kp虽然保证了其值的极性,但系统的响应存在较大的振荡。我们可以继续增大、减小
k
p
kp
kp,查看系统的响应,体会
k
p
kp
kp的作用,这里我们直接取最后的
k
p
=
62.5
kp = 62.5
kp=62.5,
k
i
=
0
ki = 0
ki=0,
k
d
=
0
kd = 0
kd=0,该值使得系统的响应在目标值50% 以下振荡,其响应曲线如下:
系统响应曲线图[
k
p
=
62.5
kp = 62.5
kp=62.5
k
i
=
0
ki = 0
ki=0
k
d
=
0
kd = 0
kd=0]:
至此,我们的
k
p
kp
kp算调整得差不多了,一般不需要再修改。
STEP1:整定 k i ki ki
积分环节主要作用是消除系统的静差,通过前面的调节,我们的系统仍然存在较大的静差,因此,我们的目标就是调整 k i ki ki,消除系统存在的静差,使系统的响应曲线与理想的目标曲线重合。
S1.0 确定 k i ki ki取值
调整方法仍然是试凑,通过先找到
k
i
ki
ki的范围,然后再微调,使得系统出现最佳效果。这里,我们直接给出最终的
k
i
=
5.5
ki = 5.5
ki=5.5,即最终参数为
k
p
=
62.5
kp = 62.5
kp=62.5,
k
i
=
5.5
ki = 5.5
ki=5.5,
k
d
=
0
kd = 0
kd=0,此时的系统响应曲线如下图所示:
系统响应曲线图[
k
p
=
62.5
kp = 62.5
kp=62.5
k
i
=
5.5
ki = 5.5
ki=5.5
k
d
=
0
kd = 0
kd=0]:
通过响应曲线可以看出,加入积分作用的系统基本消除了静差,但系统仍然存在较大的超调量和轻微振荡。
STEP2:整定 k d kd kd
为了降低系统的超调和振荡同时增强系统的抗干扰能力,我们加入微分环节。
S2.0 确定 k d kd kd取值
在
k
p
=
62.5
kp = 62.5
kp=62.5,
k
i
=
5.5
ki = 5.5
ki=5.5的基础上,我们加入
k
d
kd
kd,使得系统的响应曲线逐渐趋向平滑,还是使用试凑的方法,先确定
k
d
kd
kd的范围,然后再逐渐微调,使得系统的响应曲线出现一个最佳的平滑效果。这里我们直接取最后的
k
d
=
48
,
kd = 48,
kd=48,,即最终参数为
k
p
=
62.5
kp = 62.5
kp=62.5,
k
i
=
5.5
ki = 5.5
ki=5.5,
k
d
=
48
kd = 48
kd=48,此时的系统响应曲线如下图所示:
系统响应曲线图[
k
p
=
62.5
kp = 62.5
kp=62.5
k
i
=
5.5
ki = 5.5
ki=5.5
k
d
=
48
kd = 48
kd=48]:
通过响应曲线可以看出,整个系统的响应效果还是挺不错的。为了验证系统的抗干扰性能,我们可以给电机的输出轴(车轮)施加一定的阻力,给系统造成干扰,然后再观察系统的响应曲线如下:
加入干扰的系统响应曲线图[
k
p
=
62.5
kp = 62.5
kp=62.5
k
i
=
5.5
ki = 5.5
ki=5.5
k
d
=
48
kd = 48
kd=48]:
从该响应曲线可以看出,系统受到外界干扰后,很快又恢复到理想状态,说明系统的抗扰性能也还不错。大家可以自己计算系统的相关指标(上升时间、峰值时间、调整时间、超调量),对系统的性能(快速性、准确性、稳定性)进行评估。
总结
通过本次对直流电机转速的PID参数整定,最大的体会就是借助理论知识对实际操作进行指导,要想对理论知识有更加深刻的体会,就必须通过亲手实验。在调参过程中,我们要善于改变参数,观察系统的响应,通过系统的不同表现来体会每个参数的作用。当然,拥有一定的理论知识,更加有利于我们对参数作用的理解。通过本次调参,对于PID算法我的理解如下:比例环节决定系统响应的快速性,积分环节能够消除系统的静差,微分环节能够降低系统的超调,增强系统的抗干扰性能。
致谢
特别感谢平衡小车之家开发的虚拟示波器上位机,有了它,以后调参都会变得得心应手!
也特别感谢网上诸多关于PID调参大神的博客分享!