智能车竞赛
硬件方面
人机交互
环岛处理
方向控制
速度闭环
偏差计算
电磁数据处理
本文档使用 MrDoc 发布
-
+
首页
电磁数据处理
# 电磁数据处理 ## 信号处理(滤波) ### 中位值滑动平均滤波 其中: 中位值滤波:能有效克服因偶然因素引起的波动干扰 平均值滤波:适应于对一般具有随机干扰的信号进行滤波,这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动 滑动滤波:对周期性干扰有良好的抑制作用,平滑度高,适应于高频振荡的系统 先滑动滤波去除周期性干扰,再丢弃最大最小值去除偶然波动,最后平均滤波去除随机干扰。 ```C #define Data_SIZE 15//此为采样总数 #define Data_Random 2//此为预估的随机干扰数的一半 #define Date_ADC 5//此为所需要的电感数 uint16 value_buf[Date_ADC][Data_SIZE]; uint16 value_buff[Date_ADC][Data_SIZE]; uint16 adc_slip_filter(ADCN_enum adcn, ADCCH_enum ch,uint8 a) { uint8 i,j; uint16 filter_temp,filter_sum; for(i=0;i<Data_SIZE-1;i++) { value_buf[a-1][i]=value_buf[a-1][i+1];//所有数据左移,低位扔掉 } value_buf[a-1][Data_SIZE-1] = adc_convert(adcn,ch); //采集到的数据放入最高位 for(i=0;i<Data_SIZE;i++) { value_buff[a-1][i]=value_buf[a-1][i];//复制所有数据 } for(i=1;i<Data_SIZE;i++) //插入排序 循环遍历 { filter_temp=value_buff[a-1][i]; //将temp每一次赋值为value_buf[i] j=i-1; while(j>=0&&filter_temp<value_buff[a-1][j])//(temp后的)"<"为小到大,">"为大到小 { value_buff[a-1][j+1]=value_buff[a-1][j]; j--; } value_buff[a-1][j+1]=filter_temp; } for(i=Data_Random;i<Data_SIZE-Data_Random;i++) filter_sum+=value_buff[a-1][i]; return filter_sum/(Data_SIZE-Data_Random*2); } ``` 14行处adc_convert(adcn,ch)为ADC数据输入处(ADC接口) Date_ADC有几个电感就为几,例子中有5个,所以为5 ADCN_enum adcn, ADCCH_enum ch为ADC的定义,可根据实际修改 uint8 a存储了ADC数据组标号,不同的ADC数据组有不同的标号,例子中有5个,所以为1~5 ### 卡尔曼滤波 该滤波方案需要调节QR两个参数,调好后具有更为平滑,占用空间小,运行快的优点 ```C //卡尔曼滤波 //Q:预测值协方差,过程噪声 R:测量值协方差,测量噪声 //Q/(Q+R)的值就是卡尔曼增益的收敛值k,k大跟踪不好,k小收敛较慢 #define InitialPrediction 5 //预设初始可信度,绝不可为0 // x_last x_now p_last p_now kg double date[5][5]={{0,0,InitialPrediction,InitialPrediction,0}, {0,0,InitialPrediction,InitialPrediction,0}, {0,0,InitialPrediction,InitialPrediction,0}, {0,0,InitialPrediction,InitialPrediction,0}, {0,0,InitialPrediction,InitialPrediction,0}}; //Date:adc采集回来的值 Q R a:选择通道 double KalmanFilter(int16 ADCDate,float Q,float R,uint8 a) { date[a-1][0] = date[a-1][1]; //ADC数据左移 date[a-1][3] = date[a-1][2]+Q; //刷新P date[a-1][4] = date[a-1][3]/(date[a-1][3]+R);//计算卡尔曼增益 date[a-1][1] = date[a-1][0]+date[a-1][4]*(ADCDate-date[a-1][0]);//计算滤波后的ADC数据 date[a-1][2] = (1-date[a-1][4])*date[a-1][2];//计算下次的协方差P return date[a-1][1]; } ``` ### 电磁停车 ```C //无电磁信号停车 if((adc1<500)&&(adc2<500)&&(adc4<500)&&(adc5<500)) trig=1; //电磁信号丢失,停车 else if(trig==1)trig=0; ``` ## 后记补丁 ```c float length;//电磁偏差 float Across=1; //横电感权重 float Vertical=1; //竖电感权重 length=(Across*(sqrt(ad1)-sqrt(ad4))+Vertical*(sqrt(ad2)-sqrt(ad3)))*1000/((ad1+ad4)+(ad2+ad3)); int delay_dis; //延距离用,最大65535 uint8 flag_Round; //环岛标志位 uint8 flag_Round_dir; //环岛选择标志位 //环岛判断函数 void Roundaboutjudgment() { if(ad1+ad4>290&&flag_Round==0) { flag_Round=5; flag_Round_dir++; } }//环岛逻辑执行函数 void RoundaboutImplementation() { //延距离准备进环 if(flag_Round==5) { gpio_set(P11_2, 1); delay_dis+=encoder1; if(delay_dis>20000) { flag_Round=1; delay_dis=0; } } //改变电感权重进环 if(flag_Round==1) { gpio_set(P11_2, 0); delay_dis+=encoder1; Vertical=5,Across=0; if(delay_dis>25000) { flag_Round=2; delay_dis=0; Vertical=1,Across=1; } } //检测出环点 if(flag_Round==2) { if(ad2+ad3>200) flag_Round=3; } //改变电感权重出环 if(flag_Round==3) { gpio_set(P11_2, 1); delay_dis+=encoder1; Across=3,Vertical=0; if(delay_dis>15000) { flag_Round=4; delay_dis=0; gpio_set(P11_2, 0); Across=1,Vertical=1; } } //出环后延距离恢复环岛标志位 if(flag_Round==4) { delay_dis+=encoder1; if(delay_dis>60000) { delay_dis=0; flag_Round=0; flag_Round_dir=0; } } } ``` ```c length=((sqrt(ad1)-sqrt(ad4))+(sqrt(ad2)-sqrt(ad3)))*1000/((ad1+ad4)+(ad2+ad3)); //人为校正 length=length-10; if(length>=0) length=length*0.8; else length=length*1.3; ```
boiling
2023年12月25日 10:55
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码