📡 信号的收集
在开始算法之前,首先要了解我们处理的是什么量级的数据。我们的主控 RT1064 开启了 12 位 ADC 采样,这意味着原始数值范围是 0~4096。
在正常赛道之上,电感感应到的有效值大约在 1000 ~ 3500 左右。这个量级下,环境中的噪声导致信号跳动,交给 PID 计算的时候小车会产生莫名的抖动。为了获得平滑的信号,我们采用了死区处理和 N 阶去极值平均滤波。
(1) 采样阶段:多通道同步获取
我们首先在一个控制周期内对 4 路关键传感器进行连续 5 次高速采样,存入缓冲区:
// 采样示例:在一个周期内连续获取多组数据
for(i = 0; i < 5; i++){
filter_buf_L[i] = adc_convert(Left_ADC_Pin); // 左侧横向
filter_buf_LS[i] = adc_convert(Left_Shu_Pin); // 左侧纵向
filter_buf_RS[i] = adc_convert(Right_Shu_Pin); // 右侧纵向
filter_buf_R[i] = adc_convert(Right_ADC_Pin); // 右侧横向
}
(2) 死区处理:提出微弱噪声
在实际中发现,采集到的几百个单位的数值几乎全是环境中的杂散磁场干扰或电路本身的零漂。
// 去除微弱信号
if(filter_buf_L[i] < 240) filter_buf_L[i] = 0;
if(filter_buf_LS[i] < 500) filter_buf_LS[i] = 0;
if(filter_buf_RS[i] < 500) filter_buf_RS[i] = 0;
if(filter_buf_R[i] < 240) filter_buf_R[i] = 0;
注:为何横向电感去除的是小于 240 的信号,而竖向电感去除的是小于 500 的信号?具体的参数设定逻辑及原因需结合硬件特性调整。
(3) 算法实现:剔除异常值
普通的均值滤波容易被一个极大或极小的异常脉冲拉低整体精度。我们的方案是:去掉一个最高值,去掉一个最低值,剩下的求平均。这样可以极大地增强系统的鲁棒性。
重要提示:必须先进行死区处理再进行滤波计算,否则微弱的干扰信号会被平均到滤波结果中。
/**
* @brief N 阶去极值平均滤波
* @param ADC: 指向采样缓冲区的指针
* @return 过滤后的平滑平均值
*/
float ADC_Del_MaxMin_Average_Filter(float* ADC){
uint16 max = 0;
uint16 min = ;
uint32 sum = ;
average = ;
i;
(i = ; i < ; i++){
(max < ADC[i]) max = ADC[i];
(min > ADC[i]) min = ADC[i];
sum += ADC[i];
}
average = ()(sum - max - min)/();
average;
}

