🎀 文章作者:二土电子
🐸 期待大家一起学习交流!
由于在调PID时意外把板子烧了,目前只完成了比例调节的调试,整个程序也不太完善,本文当前仅作记录,后续会完善更改。
——2023.07.26
一、什么是PID
PID是常用的一种控制算法,其中P(proportional)是比例,I(integral)是积分,D(derivative)是微分。PID算法的原理图如下
- 比例环节
比例环节系数Kp用来控制速度快速趋近目标值,Kp越大,趋近速度越快,但是容易产生震荡,就是反复在目标值上下横跳。Kp越小,调节速度越慢。 - 积分环节
积分环节使用来消除静态误差的。比如我们设定的目标值为200,只靠比例调节会发现,速度有可能固定在185不动了。这时候就需要积分环节出手。只要我们的实际值与目标值存在偏差,就会不断地对偏差进行积分(累加)。积分系数Ki越大,调节效果越明显。使用积分调节时需要注意,需要设置一个积分限制,防止在一开始就累加偏差。 - 微分环节
微分环节是让车速快速稳定下来,实际就是产生一个阻尼效果。
另外,PID分为增量式PID和位置式PID,这里暂不做介绍,后续补充。
二、PID有什么用
知道了什么是PID,那么我们用PID来做什么?在智能车中PID可以用来控制电机转速,实现速度的闭环控制。举一个例子,做过智能车的小伙伴可能遇到过,智能车四个轮子,给相同的占空比,发现智能车无法走直线,这是因为四个轮子转速不相同。如果加上PID,可以根据目标转速给四个车轮不同的占空比来实现四个轮子转速相同。
测量转速需要用到编码器,这里暂不做介绍,后续会详细介绍电机和编码器。
三、PID程序实现
这里简单给出一个PID的实现程序,仅供参考。
u16 Speed_Pid_Ctrl (int targetSpeed,int actualSpeed)
{
float bias = 0; // 目标值与实际值的差值
static float lastBias = 0; // 上次偏差
static float lastLastBias = 0; // 上上次偏差
static float pwmDuty = 0; // PWM占空比
// 比例调节系数范围1.6
float kp = 1.6; // 比例调节
float ki = 0; // 积分调节
float kd = 0; // 微分调节
printf ("target = %d actual = %d\r\n",targetSpeed,actualSpeed);
lastLastBias = lastBias;
lastBias = bias;
bias = (float)targetSpeed - (float)actualSpeed;
pwmDuty += kp * (bias - lastBias) + ki * bias + kd * (bias - 2 * lastBias + lastLastBias);
// 限幅
if (pwmDuty >= 999)
{
pwmDuty = 999;
}
return (u16)pwmDuty;
}