典型的驱动电路就是H桥式电路,可以控制电机的正反转,同时通过PWM脉宽调制可以方便的调节电机转速。
3.2H桥式电机驱动电路原理
电机驱动采用H桥驱动电路,原理如下:
当Q1管和Q4管导通时,电流就从电源正极经Q1从左至右穿过电机,然后再经Q4回到电源负极。
按图中电流箭头所示,该流向的电流将驱动电机顺时针转动。
当Q2管和Q3管导通时,电流就从电源正极经Q3从右至左穿过电机,然后再经Q2回到电源负极。
按图中电流箭头所示,该流向的电流将驱动电机逆时针转动。
3.3传感器布局
由3.2所述的性质,我们可以知道,垂直线圈可以比较容易地得出小车与导线的相对位置,水平线圈可以预测前方弯道以及传感器摆放的一些要求。
根据这些性质,分检测导线位置和前瞻两部分论述传感器的布局方案。
3.3.1确定导线位置布局
以垂直线圈作为检测小车与导线的相对位置,原则上采用双垂直线圈就可以判断导线的位置。
然而增加传感器可以增加检测的精度,有利于小车的精确控制。
我们选用三个垂直线圈平均间隔一字排开。
3.3.2前瞻设计
由于受到小车长度和垂直线圈检测方式限制,电磁小车的前瞻受到很大的局限。
尽管小车长度达到了极限,而小车的前瞻却只有10cm左右,不能满足智能车高速运行的要求。
因此需要用必要的手段增加小车的前瞻性能。
方案一:
双排传感器。
单排传感器检测信息单一,而双排传感器可以通过判断导线斜率来弥补前瞻不足。
由于双排传感器检测的信息较为丰富,可以合理利用其信息作转角以及速度的控制。
测试发现的确优于单排传感器。
方案二:
合理变更传感器方向。
由于水平线圈对远方道路比较敏感,可以感知道路的变化趋势,因此可以利用这个特点进行前瞻。
以φ6电感线圈为例,这种方法的前瞻可以在原来传感器位置的基础上前瞻约10cm的路况。
变更其摆放的方向和角度,可以在传感器原位置基础上前瞻约15cm~25cm的距离。
这样,
小车的前瞻最大可达到约35cm。
如果检测线圈直径较大,则可以做到约40cm的前瞻,下称“大前瞻”。
我们采用与小车前进方向一致的摆法。
这样的前瞻在5cm以内,下称“弱前瞻”。
由于线圈放置方向的关系,前瞻重要解决的问题是能否顺利通过十字交叉的赛道。
导线十字交叉出现场强叠加的情况,这样对大前瞻来说是一个严重的干扰。
尽管经过处理之后小车能够顺利通过十字交叉路口,但无可避免会有少许抖动。
这样既影响小车稳定性,也使行进速度有一定下降。
而弱前瞻具有一定的前瞻,尽管非常小,但总比没有前瞻要好。
在十字交叉处几乎不受干扰。
权衡利弊,从小车的稳定性考虑,选择了弱前瞻的方案。
第四章硬件电路模块
整个硬件系统使用模块化的设计思想,整体的硬件框图如图4所示:
图4系统硬件结构图
4.1控制器模块
小车控制器是大赛指定的XS128芯片。
使用BDM下载。
经过多次测试和在跑道上跑,信号采集只需要7路AD检测,同时需要的I/O资源也不多,因而选用80pin的芯片则满足要求。
而且80pin的CPU价格比多管脚的CPU便宜,功能上差不多,只是AD口少了一半,其他没有什么区别。
单片机控制器是各功能模块的CPU,在满足智能车功能的前提下,我们本着最简单电路的原则,使用了单片机的若干端口,单片机端口分配图如表4.1所示
表4.1端口资源分配
AD模块
PAD0-PAD6
传感器信号检测
PWM模块
PP1
舵机控制
PP3
电机控制
ECT模块
PT7
测速<编码器脉冲输入)
EXT模块
PE1
起跑线检测
I/0口
PE6、PB1、PB3、PB5、PB7
液晶显示
PA1、PA3、PA5、PA7
按键
PB0
舵机使能控制
4.2路径识别模块
测量磁场核心是检测线圈的感应电动势E的幅值。
信号检测放大电路包括感应线圈、信号选频放大、整流三部分组成。
4.2.1感应线圈
检测线圈可以自行绕制,也可以使用市场上能够比较方便购买的工字型10mH的电感。
这类电感体积小,Q值高,具有开放的磁芯,可以感应周围交变的磁场。
4.2.2信号选频放大
使用电感线圈可以对其周围的交变磁场感应出感应电动势。
这个感应电动势信号比较弱,干扰多。
因此信号放大需要进行选频放大,使得20kHz的信号能够有效的放大,并且去除其它干扰信号的影响。
可以使用LC串并联谐振电路<带通电路)来实现选频电路。
如图4.2.1所示:
图4.2.1选频电路图
电路谐振频率为:
<公式7)
已知感应电动势的频率f0=20KHz,感应线圈电感为L=10mH,由<公式7)可以得到电容容量的表达式如<公式8)。
<公式8)
由<公式8)可以计算出谐振电容的容量为:
通常在市场上可以购买到的标称电容与上述容值最为接近的电容为6.8nF,所以在实际电路中我们选用6.8nF的电容作为谐振电容。
为了能够更加准确测量感应电容式的电压,还需要将上述感应电压进一步放大,一般情况下将电压峰峰值放大到1~5V左右,就可以进行幅度检测,所以需要放大电路具有100倍左右的电压增益<40db)。
最简单的设计可以只是用一阶共射三极管放大电路就可以满足要求。
也可以选用运算放大器进行电压放大。
但是需要选择低噪音、动态范围大的高速运放,成本较高,所示不选用运算放大器进行信号放大。
一般晶体三极管带宽较大,因而大体只需考虑放大倍数。
可以选取常用的NPN三极管8050-D或1815-GR,我们选取的是1815-GR作为放大。
4.2.3检波整流
测量放大后的感应电动势的幅值E使用二极管检波电路将交变的电压信号检波形成直流信号,该信号正比于感应电压幅值的数值,可以知道单片机的AD进行测量。
为了能够获得更大的动态范围,检波电路中的二极管使用肖特基二极管1N5819。
由于肖特基二极管的开启电压一般在0.1~0.3V左右,小于普通的硅二极管<0.7V),可以增加输出信号的动态范围和增加整体电路的灵敏度。
最终,我们得到整个路径识别模块的电路图如图4.2.2所示:
图4.2.2信号放大处理电路图
4.3电源模块
智能小车采用组委会提供的7.2V2000mAhNi-cd电池直接供电,并采用稳压器件调整出各路模块所需电源。
电路结构如图4.3.1所示。
图4.3.1电源模块结构图
4.4舵机使能控制电路
可以说,舵机是一个非常脆弱的部件,稍有不慎就会烧掉,特别是被卡住的时候,为了防止在下载程序的时候舵机处于供电状态,所以加了一个舵机使能控制电路,舵机使能电路相当于一个软开关,可以通过软件去控制舵机电源。
设置PB0口可以使得舵机只有在程序被下进去并且运行之后才会被供电,否则处于断电状态,原理图如图4.5.1所示。
图4.5.1舵机使能控制电路
4.5电机驱动模块
为了加强小车后轮驱动能力,采用大功率MOS管IRF4905和IRF3205搭成H桥驱动电机。
为使小车能够快速的加减速,可以采用反转进行刹车。
但电机的正反转会产生很大的制动电流,对电机驱动本身造成很大的损害。
而在实际应用中只使用到半桥,其中一个控制端接地。
当需要制动时,只要使电机对地短接,依靠电机反电动势制动同样得到较好的制动效果。
驱动和单片机之间使用了MIC4424驱动H桥电路,既保证了开启MOS管栅极的逻辑控制,也对单片机有隔离保护的作用。
图4.6.1电机驱动电路图
第五章智能车软件设计
5.1控制总流程
本队所用的软件调试工具为CodeWarrior软件和BDM仿真器,这个软件支持C语言和汇编语言的混合编程,由于C语言操作简单,可修改和移植性强,所以大部分程序都使用C语言编写,只有在某些地方加入了汇编语句。
编程基本上采用模块化的思想,使得整个设计清晰明了。
下面是系统总体的软程图。
图5.1系统软件流程图
5.2导线位置提取
方案一:
数字检测法。
把检测回来的信号数字化,根据数字量判断导线的位置。
这种方法路径分辨率不高,而且当导线电流不稳定的时候,容易受到干扰,适应性不强。
为提高空间分辨率,只能增加传感器数量,但每个传感器之间相互会造成较大的干扰。
方案二:
模拟检测法。
根据采集回来的ad值进行合理的运算,判断导线的位置。
这种方法空间分辨率可以达到2mm,而且受电流变化的影响比较少,适合小车稳定的检测要求。
故选方案二作为导线提取方法。
首先,将AD值做归一化处理,即根据各个传感器接收赛道的最高电压和最低电压,计算出各个传感器的相对值,最后来计算黑线位置。
信号归一化的方法如下:
求取电压值最大的传感器位置,然后和它周围两个传感器采样值进行加权计算即可求得小车的偏差。
5.3系统控制算法
提取小车和导线之间的位置关系后,可以确定基本控制策略。
当小车偏离导线较少时,给定一个较小的回正角度,小车也可以加速行驶。
当小车偏离导线较大时,应该给定较大的回正角度和减慢车速。
5.3.1舵机转角控制算法
voidServo_control(>
{
floatSP=2。
AD_jzlb(>。
ad_chazhi=ad_lb[2]-ad_lb[0]+3。
//为调整直道时车在中间加3
error_ad_chazhi=ad_chazhi-pre_ad_chazhi。
if(!
left_flag&&!
right_flag>
{
if(ad_lb[0]<5>left_flag=1。
if(ad_lb[2]<5>right_flag=1。
if(ad_lb[1]>45>SP=2。
elseif(ad_lb[1]>35>SP=5。
elseif(ad_lb[1]>20>SP=8。
elseSP=35。
ServoPWM=mid_ServoPWM+SP*ad_chazhi-2*error_ad_chazhi。
//-2。
//调试ad_chazhi和error_ad_chazhi的系数?
//ad_chazhi_square=ad_chazhi^2。
//ServoPWM=1600+15*ad_chazhi_square-2*error_ad_chazhi。
//-2。
//调试ad_chazhi_square和error_ad_chazhi的系数?
}
if(left_flag==1>
{
right_flag=0。
if(ad_lb[1]>38>left_flag=0。
ServoPWM=mid_ServoPWM+7*(50-ad_lb[0]>+2*error_ad_chazhi。
}
if(right_flag==1>
{
left_flag=0。
if(ad_lb[1]>38>right_flag=0。
ServoPWM=mid_ServoPWM-7*(50-ad_lb[2]>-2*error_ad_chazhi。
}
5.3.2电机转速控制算法
voidMotor_control(>
{
AD_jzlb(>。
if(ad_lb[1]>=40>
{
//MortorPWM++。
MortorPWM=MortorPWM+5。
if(MortorPWM>max_MortorPWM>MortorPWM=max_MortorPWM。
}
elseif(ad_lb[1]>=10>
{
MortorPWM=MortorPWM-5。
if(MortorPWMMortorPWM=wan_MortorPWM。
}
if(ad_lb[0]<1&&ad_lb[1]<1&&ad_lb[2]<1>
{
//Motor_left_brake(>。
//Motor_right_brake(>。
MortorPWM=0。
}
Motor_left_forward(MortorPWM>。
Motor_right_forward(MortorPWM>。
}
第六章作品测试数据
1.舵机转动函数左边最大值1220,右边最大值1940,中间值1600。
2.FLAG<5,5,38),SP(2,5,8,35>,+3,(7,2,7,2>V:
60~90,wandao_V:
45/40,减速阈值40,可以15S<较稳定)
FLAG<5,5,38),SP(2,5,8,35>,+3,(7,2,7,2>V:
60~100,wandao_V:
50,减速阈值40,可以15S<较稳定)。
FLAG<5,5,38),SP(2,5,8,35>,+3,(7,2,7,2>V:
60~90,wandao_V:
45/40,减速阈值40,可以15S<较稳定)
FLAG<5,5,38),SP(2,5,8,35>,+3,(7,2,7,2>V:
60~100,wandao_V:
50,减速阈值40,可以15S<较稳定)
FLAG<5,5,38),SP(2,5,8,35>,+3,(7,2,7,2>V:
70~100,wandao_V:
60,减速阈值40,可以14S<较稳定)
3.为调整直道时车在中间,在程序段中ad_chazhi=ad_lb[2]-ad_lb[0]+3。
//为调整直道时车在中间加3。
第七章不足及今后改进方向
经过几个月时间的筹备,我队顺利完成了智能车的设计与制作,实现了智能车的寻迹自动行驶功能。
在此过程中,我们完成了小车的组装,程序的编写以及小车的调试。
由于知识水平和制作条件的限制,智能车在行驶过程中还存在一些问题。
1.车子安装的稳定性问题。
由于材料的限制,我们组小车的固定的强度不是太好,在小车调试的时候,舵机上的传动装置和测速用的编码盘,还有前瞻都掉下来过。
2.本智能车系统在控制算法上还是采用传统的控制算法,在智能算法研究上还有所欠缺。
因此,在之后的工作中,智能算法的研究将是控制算法改进的主要方向之一。
附录A部分程序代码
(带//或/*……*/符号的为注释>
#include/*commondefinesandmacros*/
#include"derivative.h"/*derivative-specificdefinitions*/
//PWM常量定义
//#defineCH_SA_DIV4
#defineBUS_FREQ8000000
#defineCH_A_PREQ8000000
#defineCH_SA_PREQ1000000
#defineCH_B_PREQ8000000
#defineCH_SB_PREQ1000000
#defineServo_PREQ50
#defineMotor_PREQ5000
#defineAbs(x>(((x>>0>?
(x>:
(-(x>>>//定义绝对值函数
//变量定义
volatileintadvalue[4][5]={0},ad_lb[5]={0}。
//AD数据采样,ad_lb[i]是加权递推均值滤波后的采样值,ad_standard是进一步归一化后的值
volatileintad_chazhi,ad_chazhi_square,error_ad_chazhi,pre_ad_chazhi=10。
//变量分别为:
AD差值,当前差值误差,前一次差值误差
volatileintServoPWM,mid_ServoPWM=1750。
volatileunsignedcharMortorPWM,wan_MortorPWM,max_MortorPWM。
volatileintleft_flag=0,right_flag=0。
/*******************************************************************************
Function:
AD采样模块
*********************************************************************************/
voidAD_init(void>
{ATD0DIEN=0x00。
//禁止数字输入
ATD0CTL0=0x04。
//转换AD0~AD3
ATD0CTL1=0x00。
//7:
非外部触发,65:
00-8位精度<10-12位精度),4:
不放电,3210:
ch
ATD0CTL2=0x40。
//禁止外部触发,中断禁止
ATD0CTL3=0xc0。
//右对齐无符号,每次转换8个序列,NoFIFO,Freeze模式下继续转
ATD0CTL4=0x01。
//765:
采样时间为4个AD时钟周期,ATDClock=[BusClock*0.5]/[PRS+1]
ATD0CTL5=0x30。