速度PID参数整定困难?来尝试位置PID实现的速度控制!
本算法结构适用情况:带有位置编码器的电机对象、想要实现更快速度响应的控制、实现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 << 8) | (Encoder_Data & 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后继续旋转到指定位置才停下(当然这种情况是不对的,说明位置环参数还需要调整的更加灵敏一些)
页:
[1]