简 介:对电机的速度控制,探究开环闭环两种方式的区别与实现。
关键词:电机,pid,闭环
先来演示一下PID控制电机速度的效果:
然后对比一下不加PID控制的电机速度控制效果:
可以看到,开环控制的电机在我发出速度等于0的指令之后,由于惯性存在,电机会继续转动一段时间。
由于该电机存在减速箱,阻力较大,惯性效果不是很明显,接下来我们看一下智能车比赛用的电机控制效果如何。
开环控制:
闭环控制:
好吧,光看gif图我也看懵了,结合音效可以看出清楚的区别。
基于PID控制的电机速度闭环控制系统演示和讲解
一次闭环控制,一次开环控制,可以非常明显的对比两者的效果。16届智能车比赛中智能视觉组要求小车需要识别二维码并停在前方1m区域内,所以如果使用开环速度控制,小车是无法实现及时刹车的。
能实现快准稳的速度控制意义不止于此,由于比赛时的赛道弯道较多,如果我们能在弯道中降低速度,在直道上提高速度,那小车行进将会稳定很多,也更适用于多样化的赛道。
首先,每一个控制系统都需要明确需要控制的变量和反馈的变量,还需要知道如何控制这个变量改变和如何获取反馈的变量才修正我们的控制量。
对于速度控制系统,我们要控制的是电机的速度,电机速度靠PWM脉冲宽度调制技术来调节。
在stm32中使用TIM定时器可以硬件输出pwm,并可通过一个函数直接调节pwm的频率:
TIM_SetCompare2(TIM3,PWM_OUT); //2表示TIME3的2通道输出PWM信号
我们这里设置pwm频率为1k赫兹:
TIM3_PWM_Init(1000 - 1,72 - 1); //pwm
电机的控制频率太低会产生震荡,这是由于pwm低电平时间太长,高电平还没到达的时候电机速度已经降了下来。
但频率也不宜过高,否则会产生高频噪声,常用的直流电机控制频率为几khz到几十khz。
然后,为了让我们控制的变量稳定在期望值,我们需要引入反馈,测量电机速度的方案有很多,这里采用编码器方式。
编码器分为光电式编码器和电磁式编码器,编码器固定在电机轴上随电机转动,编码器的A相和 B相随转子转动一圈会输出一定数量的相位相差90度的方波脉冲,通过判断是A相超前还是B相超前可以判断电机的转动方向,然后根据一定时间内脉冲个数对时间求导可以得到速度。
定时器自带正交解码功能,这里采用TIM4定时器获取速度:
TIM4_Encoder_Init();
我们根据获取到的速度与期望值相减得到误差值,传递到PID控制器来输出合适的PWM信号驱动电机稳定在期望值。
int Motor_PID_Cal(int input_speed,int setspeed)
{
static int pwmout=0,last_error=0,last_last_error=0;
int error =setspeed - input_speed; // 误差
int d_error=error-last_error;
int dd_error = -2*last_error+error+last_last_error;
pwmout+=KP*d_error/10 +KI*error/10+KD*dd_error/10; // 输出pwm信号
last_last_error=last_error;
last_error = error;
if(pwmout > 1000) pwmout = 1000;
if(pwmout < -1000) pwmout = -1000;
return pwmout;
}
PID控制器分为增量式和位置式,这里用的是增量式,增量式PID存在一定的积分迟滞,但他的稳态误差小,适用于电机速度控制这种期望值变化很小的系统,而位置式适用于期望值变化较快和变化较大的场合,比如说小车的方向控制。
此外,程序还加入对匿名上位机的支持,大家可以通过匿名上位机实时查看电机期望速度和实时速度的变化,方便调节参数,并学习每个参数的调节对速度控制的影响。
可以看到,蓝线为期望速度,紫色线为实时速度,跟随效果还是比较理想的。现在调节期望速度为0:
来对比一下开环调节:
可以看到右边下降阶段,紫色速度曲线需要一定时间才能靠阻力把速度降低到0。
获取代码和上位机
链接:https://pan.baidu.com/s/1jpsEmjIyUfGRiQupcJjuTQ
提取码:2021