转自: https://www.cnblogs.com/heyxiaotang/p/5701087.html
问题的提出
如何让步进电机平滑地加减速运动一段固定的行程
硬件平台
86步进电机
STM32F103ZET6微控制器
步进电机的转速由由输出给驱动器的PWM频率而定,使用MCU的一个定时器(TIM2_CH1)输出占空比 D=50% 的脉冲。
定时器的时钟频率为72MHz,分频后8Mhz,于是输出PWM的最低频率大约为120Hz。
假定需要在时间 t 内运行 θ 角度,根据驱动器的细分数,齿轮传动比等可以算出所需要的脉冲数 pls_cnt。
1.双曲线加速
刚开始的想法是,前半程加速,后半程减速,加减速时间间隔为 delta_t,由另一定时器的中断周期而定,在定时器ISR里面对频率进行调整,便能让电机平滑地起停。
但是我并不能直接改变输出PWM的频率 freq,能直接改变的只是定时器的自动重载值 period,freq 和 period 之间显然是双曲线的关系:
其中 tim_freq = 8MHz,
让 period 线性化,结果导致 freq 呈双曲线变化,加速过程很慢,减速很快,实验现象也是如此,而且这个过程的时间也不好控制。
2.线性加速曲线
要让 freq 线性化,首先确定 freq 的范围,freq_min 我设定为300Hz,freq_max 因该就是这段行程平均速度的2倍了:
在 [freq_min, freq_max] 内将 freq 线性化:
freq = linspace(freq_min, freq_max, t/delta_t);
然后算出 period:
period = tim_freq ./ freq;
减速过程的可以将数组其反过来:
period = [period, fliplr(period)];
可以得到如下的频率曲线:
实验中电机的加减速还算比较平滑,精度也还可以。
3.S形加速曲线
既然可以用线性加速曲线,那应该可以用更为平滑的加速曲线,在印象中S形曲线是非常平滑的,会得到速度连续,加速度也连续的调速过程。于是用S形曲线再试试。
Sigmoid函数的原型我想是这样子的:
绘出其在[-5, 5]上的图形:
这里选择[-5, 5]这段曲线比较合适,加速过程可能有点长,如有要求可以选择[-4, 4]。
然后将其变成我想要的样子:
起始点增益,也就是最低频率:freq_min;
最大增益,也就是最高频率:freq_max;
横轴范围:0~t;
对横坐标做平移变换,然后伸缩变换,再对纵坐标做伸缩变换便得到下式:
由于在0~t时间段内,指数项不可能为∞,所以起始频率要略高于 freq_min,指数项也不可能为0,所以最高频率要略低于 freq_max。
变换后得到的图像可能是这样:
其中 t:0~4s,freq_min = 300Hz, freq_max = 1kHz。
上式中 freq_min 可以自己先给定,这样还有一个参数 freq_max,需要确定。
在 0~t 时间段内运动 θ 角度,那么:
我想它应该等价于:
于是只需在 0~t 内做一个定积分,便可确定参数 freq_max:
如果我计算正确:
这样S形曲线便确定了,然后再算出 period 数组即可。减速过程同样的可以将数组反过来,例如:
实验中S形曲线自然是最为平滑的,精度不算太好,如有可能的话,可用编码器进行修正。