Learner高级组.docx
《Learner高级组.docx》由会员分享,可在线阅读,更多相关《Learner高级组.docx(95页珍藏版)》请在冰豆网上搜索。
Learner高级组
“三星视界杯”
第七届智能控制设计大赛
技术报告
所报组别:
高级组
队名:
Learner
队长:
李靖文
队员:
庄森彬
王齐
华南理工大学自动化科学与工程学院
二〇一二年五月
目录
第1章引言3
第2章机械4
2.1车模方案比较与选择4
2.2车模概况4
2.3电机方案比较与选择4
2.4车轮5
2.5速度检测模块的比较与选择6
第3章电路7
3.1概述7
3.2主控模块7
3.3电源转换模块7
3.4电机驱动模块8
3.5红外检测模块9
3.6调试板9
3.7无线模块10
第4章程序11
4.1主函数流程图11
4.2最优路径算法12
4.3红外检测流程13
4.4光电编码器的软件消抖14
附录:
主要器件清单15
主函数清单16
第1章引言
网格迷宫小车采用RPR220红外一体管传感赛道信息,双光电编码器传感电机速度,分析车子行驶过程中姿态变化并控制电机,完成巡线任务。
小车主要由机械、电路、程序三大部分组成。
以下主要从这三部分的设计、制作和实验等方面入手,描述了小车寻迹的全过程。
机械部分,基于简单易于DIY的有机板作为小车主要支撑,主要描述了编码器、电池、电机和各电路模块的安装。
电路部分,最小系统板是购买的成品,该部分主要讲了电源转换电路、电机驱动电路和红外检测模块的设计。
程序部分,基于传感器的传感信息,主控stm32完成小车的巡线任务,迷宫信息的获取和处理。
附录为相关电路清单和部分源码。
第2章机械
作为一个能独立完成巡线功能的小车,本身的机械结构是制作的基础。
具体的车长宽、车身高度和车模材质等直接影响了电机和各电路模块的安装,我们尽可能的全面考虑并完成设计方案,下面将以方案比较、设计与论证,理论分析与计算等几个方面论述:
2.1车模方案比较与选择
方案一:
采用直接购买的车模作为比赛小车的车模,购买车模一般由CAD设计后工厂机器加工,具有对称性好的优点。
但是一般购买的车模较大,车身较长,不易满足迷宫中90度转弯的要求。
方案二:
采用有机板作为网格小车的主体部分,有机板由一种名叫Polystyrene(聚苯乙烯)的物质为主要原料构成的,简称GPPS。
具有体质轻、透明、易裁减的特点,同时又不失一定强度,广泛的运用在商业广告牌和装饰品中,非常好作为自行DIY设计。
鉴于车模与其他模块配合的重要性,综上我们采用方案二。
2.2车模概况
小车上元器件安放的的整体布局对于小车的速度瓶颈至关重要,可能一开始的时候不会显现出来,但在最起始的时候就要有这个意识,所以我们在总结以前的经验再加自己的实验的基础上,设计了现在的小车布局。
小车整体图片:
2.3电机方案比较与选择
电机是巡线小车的驱动力,是控制系统的执行机构。
电机参数选定直接影响了控制器的参数输出要求,同时在功耗上也需要详细周到的考虑。
方案一:
采用步进电机作为本设计的执行元件,步进电机能够将数字脉冲信号转化为角位移,步进电机每转一步,角度为1.8度。
步进电机具有控制较精确的特点,可以十分容易的实现小车的90度和180度转弯,但是其转速低时力矩大,转速高时力矩小,还具有发热严重的特点。
方案二:
采用直流电机作为本设计的执行元件,直流电机具有成本低、体积小的特点,能够方便快速的实现转向变换,这在180度转弯过程中十分有效。
但是直流电机的精确控制较难,需要配合编码器,控制较为繁琐。
综上两种电机的特点,我们对步进电机和直流电机分别进行了测试。
测试结果:
①步进电机控制简单,实测能非常精确的实现转弯和回转的控制,但是在低速运转时发热严重,有一次甚至将周围固定用的溶胶熔化了。
且当提高步进电机转速是,小车经常会由于转矩下降而停止;
②直流电机使用PWM可以实现简单控制,但是实际有两个电机特性不完全相同,造成相同PWM两个电机转速存在一定差别,使得小车起始速度存在一定的转向偏差。
且直流电机的功耗较大,当电池电量下降时,转速会发生明显变化,对小车巡线造成一定影响。
结合分析与测试,我们在小车设计上使用了直流电机,参照如下图的直流电机选型表:
减速直流电机是在直流电机上加上减速箱改造而成的,可以实现电机空载转速较低输出和扭力的增大输出,考虑到时间上的限制,我们对1:
48和1:
120减速比分别测试。
结果发现1:
48减速比较小,电机空载转速快且扭力较小,在制动后需要一个瞬时PWM脉冲才可以启动,且转速受PWM变化而变化明显,不方便调速。
综合速度和控制的考量,我们最终采用了双轴HC02-120减速直流电机。
2.4车轮
在小车行驶的过程中,车轮和跑道之间的摩擦力至关重要。
在前期调试中,我们发现KT板较滑,车子在转弯中易出现打滑现象,同时这也直接影响了启动和刹车。
解决方案是对轮胎进行处理,经过反复尝试,我们开始是将车轮胎磨平,这样车轮就可以和地面进行充分的接触,试验发现效果不佳。
后来发现轮胎中间有凹槽,导致轮胎中间悬空,于是我们试着先拆掉轮胎,然后在里面贴上一到两层胶带,试验发现确实可以增大摩擦力,打滑现象大大减少。
2.5速度检测模块的比较与选择
为了实现对电机的精确控制,仅仅对它有一个PWM输出控制是远远不够的,因为主控芯片不会知道输出的PWM对于对于电机来说是否合适,或者电机的响应如何。
在前期的调试过程中,我们采用的是根据直观的感觉修改程序。
但是实际工作量非常大,一个非常大的干扰因素是电量的下降将导致上一次设定好的PWM这一次调试可能过大会过小。
于是我们考虑使用调加一个反馈通道来更精确的控制电机。
方案一:
霍尔传感器,霍尔传感器是一种当交变磁场经过时产生输出电压脉冲的传感器。
脉冲的幅度是由激励磁场的场强决定的。
使用时将其安装在电机同轴部,靠检测电机的磁场变换输出速度变化,具有安装较方便的特点,但是由于我们的电机较近,容易产生干扰。
方案二:
光电编码器。
光电编码器由码盘和对射型红外管构成,是一种通过广电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器,是目前应用最多的传感器,具有成本低,受干扰小的特点,但是安装对误差的影响极大。
实际发现小车系统不需要太高精度的速度反馈,且结合干扰方面的考虑,选用100线光电编码器。
最终实际安装图如下:
第3章电路
3.1概述
我们将电路主要分成五个部分:
主控板、电源转换模块、电机驱动模块,红外检测模块和调试模块,主控板上包括了主控芯片STM32,引出各种需要的引脚连接其他外围电路;电源转换模块是+5V输出的电路,由电池输入后为主控板和红外检测模块供电;电机驱动模块实现主控芯片对电机的控制;红外检测模块实现对网格迷宫黑线的检测;最后的调试板配合红外检测模块使用,用于显示相应红外一体管的状态。
3.2主控模块
使用STM32F103RBT6芯片作为主控芯片。
作为一款优秀的处理器芯片,stm32具有运行速度快,内部集成多种外设等强大功能,而且IO口多,完全有能力作为一个稳定、高效控制芯片。
主控芯片STM32,是小车的控制核心。
STM32是基于ARMCortex-M3内核的32位处理器,具有杰出的功耗控制以及众多的外设,最重要的是其性价比。
STM32内部资源丰富,128KFLASH、20KSRAM、USB、CAN、12位ADC、SPI、IIC、TIMER、USART、RTC、DMA等一应俱全,开发十分方便。
3.3电源转换模块
在控制电路中,电源部分非常重要,电源的好坏直接影响到电路是否能工作,单片机电压不稳定会常自动复位,导致系统不能正常运行,我们在以往的比赛中就出现过单片机供电电压太低导致工作不正常的经历,也出现过电源突然过流导致单片机烧坏的例子。
本次比赛我们特地采用了优质芯片LM2576,相比传统的7805有效率更高、发热较低的特点。
3.4电机驱动模块
小车采用专用芯片L298N作为电机驱动芯片。
L298N是一个具有高电压大电流的全桥驱动芯片,它相应频率高,一片L298N可以分别控制两个直流电机,而且还带有控制使能端。
用该芯片作为电机驱动,操作方便,稳定性好,性能优良。
并加入续流二极管可防止电流逆流进芯片,以保护芯片。
并加入续流二极管可防止电流逆流进芯片,以保护芯片。
电路图如下:
3.5红外检测模块
红外对管检测电路采用了典型的电位比较器LM393,当检测到楼层时,由于反射作用,红外接收管接收到一定强度的红外线,阻值急剧下降,经分压抬高了负端输入电压,引起电平翻转,输出低电平供单片机处理。
实际电路图如下:
3.6调试板
巡线小车本身是一个控制系统,了解输入输出对分析控制程序是否存在问题十分关键。
又因为车载电池容量有限,我们在前期调试中使用LCD调试很容易使电池电量下降很快,于是我们使用了直观的LED来显示红外检测模块的输入情况。
将LM339的电位比较信号输出给共阳的LED,如果输出低则LED亮,表示相应红外一体管下检测到黑线。
3.7无线模块
为了给小车带来更强大的交互体验,我们给小车系统加入了2.4Ghz无线模块NRF24L01,其具有最高工作速率2Mbps,高效GFSK调制,抗干扰能力强,内置硬件CRC检错和点对多点通信地址控制的特点,非常适合小型控制系统。
模块图片如下:
第4章程序
系统采用C语言编程实现各项功能。
C语言本身带有各种函数库,算术运算能力较强,而本系统的软件设计中运算有较多且比较复杂,利用C语言编程的优势完全可以体现出来。
程序是在Windows7环境下采用keil软件编写。
4.1主函数流程图
程序进行了分层设计:
第一层是输入层,主要用于对红外一体管和码盘的传感信息进行读取;第二层是处理层,主要是根据红外一体管的传感器信息生成迷宫图和最优路径算法实现;第三层是输出层,主要用于对电机的控制。
如下图所示为主函数流程图,包括了探路过程小车控制、迷宫生成和最优路径获取。
4.2最优路径算法
按照题目要求,小车在遍历完所有的网格黑线后,重新从起点启动,以最短的路线直接驶向终点。
在通过对小车的行驶控制中,没过一个节点就会会记下这个节点的信息。
具体流程图如下:
当所有节点历遍后,开始搜寻最优路径
因为最优路径肯定是一个个节点接起来的,不可能路过死胡同,所以从起点0开始,一个一个节点接。
第一条路线,起点是0,只有0方向接的是节点,所以路线1;0->1,距离是3。
一节点0方向接2,1方向接3,2方向接0,3方向接2.所以路线1:
0->1->2,距离是4.路线2:
0->1>3,距离是5。
如果接到重复的节点则舍弃这条路线。
依次类推,最后得出条路线,分别是:
路线1:
0->1->2->3->4距离是6
路线2:
0->1->3->4距离是6
路线3:
0->1->2->3->4距离是8
所以选路线1
4.3红外检测流程
红外检测模块是小车的眼睛,虽然我们通过方案论证决定采用RPR220红外一体管,不过具体使用多少个红外一体管,采用什么样的安装方式需要实际测试了才知道。
通过多次比较分析,在满足小车输入信息需求和红外一体管用量最少的情况下,我们最终决定使用8个红外一体管。
安装方式如下图所示:
第一排的五个红外一体管主要用于小车的姿态信号输入,第二排的三个红外一体管主要用于迷宫节点的信息输出,两排相互配合,实现小车的智能巡线任务。
如下面各图所示,不同的迷宫位置对应红外一体管不同的状态
4.4光电编码器的软件消抖
光电编码器构成简单,通过I/O的下降沿检测脉冲,但是由于车身抖动的原因,可能造成误判,一般采用硬件加触发器的方法消抖,我们采用双线加标志位的方法进行软件消抖,具有误判率低、成本低的特点。
对管中包含两根信号线,一根黄色、一根蓝色,两线相位相差90°,高速信号下,输出类似正弦波样脉冲波;低速模式下是方波,它们的信号如下图所示
图3-4-1(a)顺时针图3-4-1(b)逆时针
图3-4-2有抖动的波形
通过两线增加标志位的方法可以很好的消除抖动现象,算法流程图如下:
图3-4-3消抖算法流程
附录:
主要器件清单
1.红外检测模块
Comment
Description
Designator
Footprint
LibRef
Quantity
发光二极管
D1,D2,D3,D4,D5,D6,D7,D8
1206
发光二极管
8
50K
Potentiometer
DIANWEI1,DIANWEI2
VR3296-1
RESVR
2
HEADER3X2
JP1
HDR2X3
HEADER3X2
1
HEADER4X2
JP2
HDR2X4
HEADER4X2
1
HEADER2
JP3,JP4
HDR1X2
HEADER2
2
HEADER9
JP5
HDR1X9
HEADER9
1
CON3
Jw1,Jw2,Jw3,Jw4,Jw5,Jw6
TO-126
CON3
6
P521
P1,P2,P3,P4,P5,P6
HDR2X2
P521
6
10K
R1,R2,R3,R4,R24,R25,R26,R27
0805
RES
8
1M
R5,R6,R7,R8,R28,R29,R30,R31
0805
RES
8
150
R9,R10,R11,R12,R22,R32
0805
RES
6
47K
R13,R14,R15,R16,R23,R33
0805
RES
6
1K
R17,R18,R19,R20,R21,R34,R35,R36
0805
RES
8
LM339N
U1,U2
SOJ-14
LM339N
2
2.电源转换模块
Comment
Description
Designator
Footprint
LibRef
Quantity
100u
ElectrolyticCapacitor
C1
RB.1/.2
ELECTRO1
1
1000u
ElectrolyticCapacitor
C2
RB.2/.4
ELECTRO1
1
0.1uF
Capacitor
C3
RAD0.1
CAP
1
IN5819
SchottkyDiode
D1
DIODE0.3
DIODESCHOTTKY
1
LED
D2
LED
LED
1
100uh
L1,L2
RB.2/.4
INDUCTOR2
2
4HEADER
4PinHeader
P1,P3
SIP4
4HEADER
2
8HEADER
8PinHeader
P2
SIP8
8HEADER
1
1K
R1
AXIAL0.3
RES2
1
LM2576-5
U1
TO-220_D
LM2576
1
3.电机驱动模块
Comment
Description
Designator
Footprint
LibRef
Quantity
100F
Capacitor
C1
100UF
电解电容
1
0.1UF
Capacitor
C2
RAD0.1
普通电容
1
100UP
Capacitor
C3
100UF
电解电容
1
0.1UP
Capacitor
C4
RAD0.1
普通电容
1
DIODE
D1,D2,D3,D4,D5,D6,D7,D8
DIODE0.4A
DIODE
8
HEADER9
P1
SIP9
HEADER9
1
4HEADER
4PinHeader
P2
SIP4
4HEADER
1
L298N
DualFullBridgeDriver
U1
Multiwatt15V
L298N
1
主函数清单(保留了调试函数段的注释)
/*Includes------------------------------------------------------------------*/
#include"stm32f10x.h"
#include"hardware.h"
//#include"usart.h"
#include"ili932x.h"
#include"rtc.h"
#include"24l01.h"
#include"adc.h"
#include"hongwai.h"
static__IOuint32_tTimingDelay;
uint8_tcarstate=0;//0探路1返回上个未历遍节点2返回出口3回入口4最优路径行驶5waitforcommand
uint8_tnowpix=0;//目前的标准坐标方向
uint8_tmapfinish=0;//地图是否完成
uint8_tnowdir=0;//目前要转的方向
uint8_tncross=0;//节点的个数
uint8_tchange=0;//后面的步骤车子的位置是否改变
uint8_ttest=0,test1=0;
uint8_tcarspeed=0;//车速
uint8_ttime=0;
uint16_tlspeed=165;
uint16_trspeed=162;
uint16_trturnsp;
uint16_tlturnsp;
uint16_tlstep=0;
uint16_trstep=0;
uint8_tenter=0;
uint8_tiftc=0;//T字路口辅助判断
uint16_tdlstep=0;
uint16_tdrstep=0;
uint8_txiuzheng=0;
uint8_textichange=0;
uint8_tgrid=0;//所走的格数
uint8_tlastcrostate;//0起点1节点2终点3死胡同
uint8_t*bestpix;//最优路径信息
uint8_t*bestxy;
uint8_tbestdir[20];
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
structcross{
uint8_tpx;//坐标以起点为0,0
uint8_tpy;
uint8_tcondiction[4];//四个方向的状态0无路1有路还没走2正要走3节点4死胡同5起点6终点
uint8_tnext[4];//四个方向接的下一个节点
uint8_tdistant[4];//与下一个节点间的距离
uint8_tcon;//这个节点的状态1没走遍2走遍
};
structmap{
uint8_tpx;
uint8_tpy;
uint8_tstate;//0无3节点2转弯4死胡同5起点6终点
uint8_tnext[4];
};
structmappoint[40];
structchoose{
uint8_tpx;
uint8_tpy;
uint8_tpix;
};
uint16_tlsmax=205;
uint16_tlsmin=175;
uint16_trsmax=200;
uint16_trsmin=160;
uint8_tnpoint=0;//点的个数包括转弯死胡同节点终点
uint8_tlastpoint=0;//上一个点的编号
uint8_treroute[40];//记录返回的路线
uint8_tbackstep=0;//
uint8_tbackgoal=0;
uint8_tcountrl;//r1l0
structcrosscrossroad[40];
uint8_trunning=0;
uint8_tturning=0;
uint8_tturndir=0;
uint8_tspeedup=0;
uint8_tpixton(uint8_tpx,uint8_tpy,uint8_tporc);
uint8_tsearch(void);
voidreturnroute(uint8_tstart,uint8_tend);
voidchoosebest(void);
voiddrawmap(void);
voidEXTIX_Init(void);
voiddrawline(uint8_tx1,uint8_ty1,uint8_tx2,uint8_ty2);
voidExti_Set(uint8_tlin,uint8_ten);
voidcontrol(uint8_trunorstop,uint16_tspeed,uint8_tdir);
voidcheckpos(void);
voidGPIO_Configuration(void);
voidNVIC_Configuration(void);
voidTimerx_Init(u16arr,u16psc);
voiddelay(uint16_tx);
voidLED_Init(void);
uint8_tgetpix(uint8_ta,uint8_tb);
uint8_troute[200];
uint8_tnroute=0;
uint8_ttemp_distant=0;
voidshowdetect(void);
voiddeal_arrive(uint8_td);
voidpid_init(void);
int16_tgetpwm(int8_tcurrent,uint16_tnowpwm,uint8_trorl);
voidsentmap(void)
{
/*uint8_ttmp_buf[32];
while(NRF24L01_TxPacket(tmp_buf)!
=TX_OK)
{
tmp_buf[0]=1;
tmp_buf[1]=lastpoint;
tmp_buf[2]=point[lastpoint].px;
tmp_buf[3]=point[lastpoint].py;
tmp_buf[4]=point[lastpoint].state;
tmp_buf[5]=point[lastpoint].next[0];
tmp_buf[6]=point[lastpoint].next[1];
tmp_buf[7]=point[lastpoint].next[2];
tmp_buf[8]=point[la