本文将系统阐述如何做好电磁车前期的硬件与软件准备工作
硬件部分
认识电感
工字电感 感应赛道交变磁场,产生感应电动势,后续电路通过对感应电动势进行一些列的选频、放大、检波,得到稳定信号并输入到单片机对赛道信息进行识别,对电机发出加减速、舵机直行拐弯的指令。
电感是电磁车的眼睛,赛道中漆包线流过的微弱的电流与电感产生电磁感应,产生的感应电流经过运放放大,最后传给单片机的AD采集口,即可获取赛道信息。
电感分布探究
基本的分布认知
电感水平左右放置,漆包线与电感垂直的时候产生的感应电流最大,在赛道上 从左至右移动电感,电感上面感应电流应该是先逐渐变大,再逐渐变小。
电感安装时要注意相邻两个电感切忌安装过近,至少要有两厘米的距离,否则会产生互感现象,具体现象就是过十字的时候车身会产生振动,严重的会导致十字直接冲出赛道。
深入的探究分布
电感排布方案是制约电磁智能车竞赛成绩的关键因素之一,下面我们就深入地探究下,如何确定一个好的电感排布方案。 一.双水平电感排布方案
如上图,这种双电感平行排布的方案是电磁车结合赛道采用的电感排布的最基本的方案,此方案也可以使得电磁车简单地循迹,但效果并不太理想。
当小车如上图,将水平两端电感对称放置时,此时小车也应该处于赛道电磁线中心位置,左右两边电感正常情况下应相差不大,即差不多相等。即在直道行驶时可以保持良好的采集数据获取,通过计算分析两端电感数值,就可以判断出小车与赛道中心线的偏离方向及偏差量,从而做出相应的方向控制。 但双电感排布也有弊端,如在弯道情况下,不能很好地采集到数据,没有办法精确地计算出偏差量,只能大致从数值中推测出小车的偏移方向。
如上图,水平电感并没有跟赛道上的电磁线有很好的角度(粗色指赛道电磁线) 二.八字形电感排布方案
八字形电感排布同样也可以跟双水平电感一样,在直道行驶时保持良好的采集数据获取,通过计算分析两端电感数值,判断出小车与赛道中心线的偏离方向及偏差量,从而做出相应的方向控制
并且在弯道情况下,与赛道电磁线呈很好的角度,获取赛道信息更精确。 但是前面说到,双水平电感在直道行驶有很好的优势,在这里八字形电感恰好在弯道行驶有很好的优势,不如把两者结合起来排布,使得电磁车在赛道上获取的信息更准确更充分,这就衍生出了第三种方案。 三.双T形电感排布方案
这种方案结合了两者优点,能够充分捕捉赛道上信息,通过采集每个电感的数值,加以合理处理,便可以解算出电磁车所在的赛道位置,能够很好的控制电磁车在赛道上行驶。 除了上图所示排布方案,也可以使用下图的排布,道理皆一样。
验证理想结果
认知了电感的作用,知道了电感如何排布,下面我们就要做最后的硬件方面的测试,看是否呈现理想结果。 首先前提: 1.有设计好的运放板 2.电感排布按上述策略对称排布好 3.调用库函数,学会ADC采集 这里主要简略讲下,如何判断理想结果: 粗糙地操作方法就是,用显示屏显示出每个电感的采集数值,将小车放置赛道电磁线中间,左右匀速摆动小车,观察数值是否呈规律变化,有无大的跳变,如果呈均匀变化趋势,则粗略判断可以稳定地采集数据。 更加直观地方法就是,采用上位机(下图所用上位机为山外上位机),将每个电感的采集数值通过蓝牙传输到上位机上,采用波形显示观察,观察波形是否平滑,是否上下对称。(具体操作如上所讲)
这里上位机显示的电感为何如此之小?这里是我将采集到的电感数值做了归一化处理,下文会接着讲到。
软件部分
采集滤波
简单地一个adc采集获取电感的数值是远远不够,采集到的信息可能是不准确的,需要采集多次,通过各种滤波算法处理才能得到一个较好的数值,这样用起来才可靠。网上的滤波算法有很多这里我就不再啰嗦描述,大家感兴趣的可以去我的博客下载中心去下载。 在这里我只贴出一种算法,给大家简单地描述下:
for(num = 0; num < 10; num++)
{
i = adc_once(ADC1_SE9,ADC_12bit); j = adc_once(ADC1_SE9,ADC_12bit); k = adc_once(ADC1_SE9,ADC_12bit); // B1-4
//2.取中值
if (i > j)
{
tmp = i; i = j; j = tmp;
}
if (k > j)
tmp = j;
else if(k > i)
tmp = k;
else
tmp = i;
sum+=tmp;
}
AD_VAL4=sum/10;
sum=0;
如上图这里所用的滤波算法就是中值平均滤波法 方法就是:相当于“中值滤波法”+“算术平均滤波法”,连续采样10次,去掉一个最大值和一个最小值,最后再算术平均。 优点:融合了两种滤波法的优点, 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。 缺点:测量速度较慢, 比较浪费 RAM(不过对于智能车所使用的MCU,问题不是太大)
归一化处理
很多一开始的小白,在做电磁这一部分时,可能并不太知道归一化,只是通过上面的滤波算法处理后,就用解算出来的电感数值,开始写控制算法,这样导致的结果就是,调出来的车可能容错率不高,适应性不强,换个场地,因受赛道各种因素的影响可能需要不停地调原有设定好的电感值,对整个程序框架影响还是挺大的。 这里我给大家通俗地讲述下到底归一化该怎么处理。 这里我们以一个电感采集为例,就把他命名为AD1,接下来的代码都是表示对AD1电感采集到的数值进行处理。 首先第一步,我们还是先通过滤波算法对AD1电感采集到的数值进行滤波处理:
//AD1-------------------------------------------------------------------------------------
for(num = 0; num < 10; num++)
{
i = adc_once(ADC1_SE8,ADC_12bit); j = adc_once(ADC1_SE8,ADC_12bit); k = adc_once(ADC1_SE8,ADC_12bit); //B0-3
//2.取中值
if (i > j)
{
tmp = i; i = j; j = tmp;
}
if (k > j)
tmp = j;
else if(k > i)
tmp = k;
else
tmp = i;
sum+=tmp;
}
AD_VAL1=sum/10;
sum=0;
然后,我们需要把AD1电感放置在能够使其数值呈现最大的位置处,读出采集到的最大值是多少,如下图我采集到的就是4095,这里我们引入一个最大值,也引入一个最小值(最小值默认设置为0)。
int AD_val_1_min=0;
int AD_val_1_max=4095;
接着,对刚才滤波后的电感数值进行限幅处理
//限幅
if(AD_VAL1>AD_val_1_max) AD_VAL1=AD_val_1_max
再然后,进行归一化处理,引入归一化后的电感数值ad_VAL1
//归一化
ad_VAL1=100*(AD_VAL1 - AD_val_1_min)/(AD_val_1_max-AD_val_1_min);
如有错误,请批评指正
码字不易,你的支持是我创作的最大动力,给个点赞关注下吧