本算法结构适用情况:带有位置编码器的电机对象、想要实现更快速度响应的控制、实现0速度状态的完全锁定。
最近看到有智能车的车友调速度环感觉不好调,特来分享一下经验。
先讲一下我这个通过位置环实现的速度控制优点——没有速度观测误差,速度调整性能等同于位置环调整性能。
首先说一下为什么会感觉速度环难以调节。因为速度环在测量速度的时候,会引入一个观测误差。无论是使用M法测速(计算一段时间内的脉冲数量),还是T法测速(计算两个脉冲之间的时间差)。都会出现周期短速度数据波动大 ,周期长速度数据引入延迟变得难以使用PID控制。
尽管可以使用M/T法进行混合测量,但是对M/T的权重和切换又显得较为麻烦。
但是位置环就显得好实现的多,因为位置是绝对记忆的。只需要对所有的脉冲数量进行积分,也只用关心距离目标位置还有多少个脉冲。并不需要考虑时间差的问题。既然位置环性能这么好,那么当然也可以用位置环实现速度控制。
事实上,常见的伺服控制器(脉冲控制型)就是这种原理,每次发送一个脉冲就转动一点点距离,通过控制脉冲发送频率的变化实现速度的控制。
那么,如果要实现这样一个特殊的速度环,我们应该如何使用代码实现呢?
下面以我的STC-FOC Lite中代码举例,其他类型的电机和编码器实现的方式也是大同小异
- void SPI_DMA_Isr(void) interrupt DMA_SPI_VECTOR
- {
- CSN = 1; // 拉高使能,结束读取
- if ((DMA_SPI_STA & 0x04) == 0) // 正常进入
- {
- _angle_this_dat = (((Encoder_Data[0] << 8) | (Encoder_Data[1] & 0xfc)) >> 2);//获取单圈绝对位置数据
- //增量编码器可以统计两次中断之间的脉冲个数
- _angle_dangle = (_angle_this_dat - _angle_last_dat);//计算角度差值
- //绝对值编码器的过零点处理,增量编码器不需要
- if (_angle_dangle < -(Encode_bit_Max / 2))
- {
- _postion_add_dat++;//圈数自增
- _angle_dangle += Encode_bit_Max; // 过零处理
- }
- if (_angle_dangle > (Encode_bit_Max / 2))
- {
- _postion_add_dat--;//圈数自减
- _angle_dangle -= Encode_bit_Max;
- }
- //postion_add为目标位置累加变量,判断超过1(编码器最小分辨率)后,将整数部分添加进入电机的设定位置
- if (fabs(postion_add) > 1 && Mode == Speed_Mode && Run_Flag)
- {
- moto.set_postion += (long)postion_add;
- postion_add -= (long)postion_add; // 自减整数部分,因为这部分已经添加进入设置位置了
- }
- // 圈数累计,可以累计正负2^31圈
- _angle_last_dat = _angle_this_dat;
- }
- DMA_SPI_STA = 0; // 清除中断标志位
- }
复制代码
这部分是有关于中断的处理,其中过零处理是绝对值编码器才需要进行的操作,增量式编码器不需要。这部分主要的功能就是获取增加的角度,并且积分进入绝对位置。
并且将速度转换成的设定位置添加进入设定位置,这里因为编码器最小分辨率为1。但是累加的最小分辨率可能会很小,所以做了一个分辨率转换功能。只有超过1的部分才会添加进入设定位置。
否则就等待继续累加超过1。
- // 根据速度调整位置设定@30us
- float postion_add = 0; // 小于分辨率编码器时的累加器
- long last_postion_add = 0; // 上次增量记忆
- void Timer0_Isr(void) interrupt TMR0_VECTOR
- {
- if (Mode == Speed_Mode && Run_Flag && moto.set_speed != 0 && I_Error_Cnt < I_Error_Dat)
- {
- postion_add += (float)moto.set_speed * 30.0 * (1.6384 / 6000.0); // us
- }
- }
复制代码
这里就是一个普通的定时器,通过读取设定速度乘以指定的时间系数变换成位置信息。
剩下就是通过设定的位置信息moto.set_postion实现一个速度环,即可实现基于位置环的速度控制。
此时的速度控制将完全没有观测误差(因为位置采用积分,所以设定的位置信息一定会到达)
此时就算位置环调的参数不够理想,没能到达指定速度,也会在设定速度变成0后继续旋转到指定位置才停下(当然这种情况是不对的,说明位置环参数还需要调整的更加灵敏一些)
|