1、目录1. 整体介绍12. 硬件部分32.1 硬件元器件42.2 调试过程93. 软件部分103.1 图像处理103.1.1 原始图像103.1.2 透视变换113.1.3 迷宫结构分析123.1.4 最短路径133.1.5 小车定位133.2 迷宫算法143.3 小车实时调试173.4.1有线方面174. 系统测试184.1 串口通信184.2 小车控制184.3 不足与改进185. 项目总结与心得196. 致谢207. 附录第19页 上海交通大学 电子信息与电气工程学院1. 整体介绍 由摄像头(USB接口)实时捕捉迷宫内小车的位置情况,通过USB线缆传送至电脑里编写的上位机软件,软件通过图像
2、识别找出当前小车的位置信息及迷宫的信息,经过计算,作出控制决策,生成控制信号,并经通讯模块发送至小车。 小车上的控制电路对控制信号作出相应反应,驱动电机。使用硬件材料:89S52单片机控制的小车、RS232有线收发模块、USB转RS232串口线、计算机、摄像头 项目组成1、图像处理 摄像头监小车位置,通过图像处理的手段发布指令。其中的具体项目包括图像实时采集,图像处理预处理,形状检测,小车跟踪,摄像机标定及最优线路生成。2、串行通信计算机与小车之间的通信为串行通信(有线),实现PC与单片机的通信。由摄像头(USB接口)实时捕捉迷宫内小车的位置情况,通过USB线缆传送至电脑里编写的上位机软件,软
3、件通过图像识别找出当前小车的位置信息及迷宫的信息,经过计算,作出控制决策,生成控制信号,并经通讯模块发送至小车。3、单片机部分具体包括闭环控制算法,小车电机控制。2. 硬件部分小车结构小车分为三个部分,主板部份、车体部份和控制芯片部份。主板部分负责接受8V直流电源,并向小车的电机提供8V电压,向电路板上的芯片提供工作电压。车体部份主要为上层芯片和整体提供支撑,它的电机为小车提供动力前进。控制芯片部份负责识别并处理收到的信号,并输出控制信号,控制小车电机的运转。信号收发模块信号收发模块分为收发两部分,即发送部分与串口连接,接受串行通讯标准的TTL高低电平,将其调制后发送出去。接受部份将发出的信号
4、转化成标准串行通讯信号发送给小车。接收模块的Vcc与89S52上层版的Vcc连接,GND接电路板的任一接地端。信号输出端与89S52上层版的RxD连接,由于主板三极管通常是坏的,可将上层板RxD与底板分开。 USB转RS232线此串口线将增加电脑一个COM口,根据电脑的不同,初始被赋予的COM口地址也不同,但一般为COM4,可以在设备管理器中对端口地址进行修改。对于电脑与小车进行串行通信来说该线是透明的。其USB端接电脑,TxD接无线发送模块的数据端,Vcc与发送模块Vcc相连,GND与发送模块GND连接。 电脑及摄像头电脑有两个以上USB口,摄像头使用普通USB摄像头。2.1 硬件元器件这次
5、科创三实验,用到两块主要的芯片,一块是CMOS8位微控制器,其主要功能是: 兼容MCS-51指令系统 8k可反复擦写(1000次)ISP FLASH ROM 1000次擦写周期 32个双向I/O口 4.5-5.5V工作电压 3个16位可编程定时/计数器 时钟频率0-33MHz 全双工UART串行中断口 128x8bit内部RAM 低功耗空闲和省电模式 中断唤醒省电模式 3级加密位 看门狗(WDT)电路 软件设置空闲和省电功能 灵活的ISP字节和分页编程 双数据寄存器指针AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K 在系统可编程Flash 存储器。AT89S52使用Atmel
6、公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,AT89S52拥有灵巧的8 位CPU和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。AT89S52具有以下标准功能: 8k字节Flash,256字节RAM,32 位I/O 口线,看门狗定时器,2 个数据指针,三个16位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。另外,AT89S52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU停止工作,允许R
7、AM、定时器/计数器、串口中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。 其PDIP图如下:另一块芯片是L298N,用它来控制两个电机。管脚图:每个管脚正常工作时的电参数如下:硬件原理图2.2 调试过程调试过程主要遇到了两点困难,一是拿来的小车本身硬件有问题,一开始根本无法正常运行。二是在转向时出现了打滑的现象。(一) 硬件部分是我们小组在基本完成软件部分后又碰到的一大问题,当时软件部分刚做完,以为整个项目已经完成了80%了。只要再调试一下,该进部分算法就可以了,但是实际上绝非如此简单。首先,拿到的小车本身就是坏的,缺少数据线和
8、电源线。然而,这才是问题的冰山一角,在我们将数据线和电源线旱好以后,接到了实验室的主机烧自检程序。却发现车子动都不动,而且奇怪的是电脑也可以检查到芯片,而且可以把程序烧进去,但是就是不动。起初我们以为是驱动部分的问题,但检查下来完全和图纸一样,而且电机也是好的。然后我们想到了L298N,这款芯片是控制电机的。但是我们换了另一组的单片机模块(就是上面的电路板),却发现可以正常运行selftest了。这也使我们把问题集中在了上面一块芯片。按理程序可以写入,应该芯片是不会有问题的,所以我们首先检查了电路和与下面电路板的接触问题,在确定所有电路都正确后,我们最后把问题的关键聚焦在了AT89S52芯片上
9、。果不其然,最后是我们的AT89S52芯片有问题。在换取了一块AT89S52芯片之后,我们的终于可以正常工作了。(二) 遇到的第二个和硬件部分有关的问题是轮胎的打滑问题,这个问题相对比较好解决,我们在轮胎上加了两圈橡皮筋就成功克服了如上问题。关于左右轮转向速度不同的问题,我们是通过软件的控制来改进的,具体就是更具左右转速的不同,来安排左右转弯的次数(既同一转向指令运行不同次数),以此来达到顺利专项的目的。3. 软件部分工具:OpenCV、 VC+。主要流程: 1摄像头获取原始图像,图像矩阵化2透视变换得到迷宫俯视图3分析迷宫结构4指定入口出口,计算最短路径5摄像头实时捕捉小车位置,与计算路径相
10、比较,并通过串口自动向小车发送调整指令6小车最终到达出口3.1 图像处理3.1.1 原始图像利用OpenCV的cvQueryFrame函数从摄像头获取原始图像。OPEN CV模块如下图所示 CVHighGuiCXCORE其中:CV:图像处理、视觉算法CXCORE:基本数据结构、运算HighGui:GUI,图像、视频接口所实现的图像处理过程如下: 包括以下注意点:光源亮度要足够、均匀成像的投影关系镜头聚焦使整个场景清晰3.1.2 透视变换迷宫路线计算和小车位置判断都基于透视变换后的俯视图,OpenCV提供了透视变换的函数WarpPerspective,该函数按照指定变换矩阵进行变换,而变换矩阵由
11、GetPerspectiveTransform从变换前后两个图像中的4个对应点计算出来。需要注意的是摄像头摄取的图像时反的,运用透视时要把图像纠正过来。3.1.3 迷宫结构分析迷宫的分析可以通过“测试线”进行:矩形可看作迷垂直方向的宫壁,而红色细线即为其“测试线”(类似的,水平方向迷宫壁的“测试线”为垂直方向)。将迷宫等分为8*8的小块,则“测试线”应设置在每小块周围的4个迷宫壁的中垂线位置。通过判断“测试线”上迷宫壁的像素个数,可以推断出该“测试线”是否跨越了一个迷宫壁,从而得到整个迷宫的结构。右上方窗口为透视变换后的实时图像,蓝色的网格线将迷宫等分为8*8的小格。左侧窗口为调解图像感光度的
12、窗口,用来应付不同的光照条件。右下方窗口为处理的结果,其中粉红色的区域即为迷宫的最短路径,是由右图中一个个的小格组成。而黄色网格线即为关键的“测试线”,绿色部分为标记出的迷宫壁,可以看出“测试线”正好与迷宫壁正交,准确地检测出迷宫的结构。3.1.4 最短路径最短路径的计算使用floodfill算法。基本思想顾名思义,假设水流匀速流动,自由分叉、汇合,并且会受到墙壁阻挡,则在迷宫中的起点处打开水龙头,最先到达出口的水流过的路径一定是最短的。具体的实现可以采用标号的广度优先搜索,第一次搜索到出口时,搜索树的层数是最小的。而且搜索时尽量保持方向不变,就可以再多条最短路径中选择出转向次数最少的那条,易
13、于控制。3.1.5 小车定位为了排除迷宫壁与迷宫地面的干扰,小车需要用蓝色包装。通过OpenCV的CalcBackProject函数得到照片在实时图像中的反向投影。反向投影是一幅图像在另一幅图像中出现的概率,小车的特写在迷宫中出现概率最大的地方自然就是小车当前在迷宫中的位置。而跟踪函数CamShift就是跟踪这块概率最大的区域,并返回这块区域的位置角度大小等信息。而小车定位最终确定小车在8*8的迷宫中哪一格,从而与路径信息比对。3.2 迷宫算法通过走格子的方式寻找迷宫出口,首先根据实际图像计算道路宽度,大致定下步长略大于迷宫道路宽度的三分之一但小于宽度的二分之一。行走路线为上下左右四个方向,每
14、一步后须判断其余三个方向的走法(去除标记为已试探或者不可走的方向),总体是回溯算法,直到找到出口或者出错返回。 寻找路径的基本原则(某一点可走): 1. 当前格未被走过 2. 当前格不能有墙 3. 与当前行进方向垂直的两边相邻的两格内不能有墙。 根据格子边长(步长)的先前指定,即略大于道路宽度的三分之一,可以证明:如果迷宫宽度均匀,则找可在道路中央附近唯一找到一条路径,以不至于太贴墙或者有重复路径。 约束条件:迷宫拍摄尽可能正,即道路水平和垂直方向;迷宫宽度均匀(拍摄效果);小车进入口方向默认向上。 注:某一点“可走“的条件为上述提到的三个原则。 若成功找到出口,则函栈内保存的即为路径的关键点
15、。 关键函数说明: void path(const IplImage * frame):计算路径void floodfill1(int map1717,int x,int y,int sx,int sy,int ex,int ey):floodfill1算法,用来求出最短路径void draw():把计算得到的路径画在屏幕上 3.3 小车实时调整小车基本行进方式为向前、微左弯、微右弯、90度左转、90度右转。各状态两个电机的速度事先设置好,实际过程中只需向小车发送相应的指令即可。走迷宫的路径已计算出并保存,小车的实时位置由摄像头捕捉并通过图像函数得到坐标位置,对小车位置的评估只基于当前理论应走
16、的方向(vector)和下一个拐角(corner)的位置。当小车当前位置与应在位置有较大差距时根据情况发送小步前进后退指令,确保小车停在应在位置附近当小车下一步方向不变时,大步前进。当小车下一步方向改变时,判断并发送左转右转指令,同时监视小车方向。由于迷宫壁的限制作用,小车一定能转向成功,并且方向的巨大改变能被明显的检测出来,则停止转向。直到到达出口为止。关键函数说明: void control():主要控制函数,用来控制小车的前行后退转弯。sendcommand(5),sendcommand(6),sendcommand(2),sendcommand(4),sendcommand(!)分别为
17、左转,右转,向前,向后,停止 3. 4串口通信 具体功能:由摄像头(USB接口)实时捕捉迷宫内小车的位置情况,通过USB线缆传送至电脑里编写的上位机软件,软件通过图像识别找出当前小车的位置信息及迷宫的信息,经过计算,作出控制决策,生成控制信号,并经通讯模块发送至小车。小车和电脑之间通过串口通信,使用USB转RS232串口线来传输指令。3.4.1 有线方面硬件:首先要在计算机上使用一个虚拟串口驱动程序将USB端口虚拟出一个串口,再用线联到小车对应端口就完成了。软件:串口程序有许多种写法,在C里也有对应的库函数,但由于我们要发送的消息结构比较简单,就不需要这些专用的库函数了,直接使用windows
18、.h中的函数了在有线的阶段,整个程序比较简单,因为计算机端每次发送,小车都能稳定正确地收到。4. 系统测试对小车的测试主要包括两个方面。一是图像处理结果与小车之间的串口通信;二是对于小车控制的调试。图像处理结果与小车的串口通信测试结果良好,在测试过程中基本没有遇到什么困难。在串口通讯完成以后,小车能够按照图像处理的结果进行左右拐弯、前进、停止等基本行动。小车控制所遇到的最大问题是小车拐弯的问题。经过多次测试得到如下结果:1、小车不是很稳定。不知道是因为马达的问题,还是控制芯片的问题,抑或是其他一些我们没有想到的问题,小车总不是很稳定,而每次小车的不稳定,直接导致我们小组的成员要花费相当多的时间
19、去检查小车硬件方面的问题,连线的焊接是否有误、是否出现连线断开的问题,控制芯片是否查紧等问题。2、拐弯比较困难我们小组在初始阶段预备采用一倍路宽(对于迷宫而言),但由于小车的体积比较大,要做到这一点比较困难。我们小组各成员经过讨论,决定改用二倍路宽,并取得了比较好的成就。3、小车参数的设置小车参数的设置是个复杂的问题,任何条件的改变都会对其造成影响:如小车的负重,电压的大小,甚至小车重心的改变,不仅如此,还要考虑小车颜色对识别的影响等因素。我们小组最终的测试环境如下:采用有线串口通讯,8V直流电压(未采用电池,因为会导致小车重心改变而影响最终的测试结果)。5. 项目总结与心得总结由于工具与方法
20、的选择与使用的正确,使得我们对摄像头与光照要求低,能用普通摄像头普通光照条件下确定整个8*8迷宫,且迷宫结构的确定很准确。同时小车控制很稳健,保证每一步的正确位置与方向后再走下一步,否则退回。因此可以在8*8迷宫且道路宽度为1格的情况下行驶。虽然有后退的情况,但由于确保了每步的正确性,整体前进的速度也很快,而且最终能无需干预的跑完全程。将狭窄的道路与迷宫壁充分的看作一种简化控制的道具,能将小车稳定的限制在道路上,从而达到更高的控制精度。心得入手:刚拿到实验题目的时候,感到这次实验真的是太难了,我们现有的知识还远不足以解决这样的问题,感觉无从下手,甚至不知所措。但随着实验的渐渐深入,在我们组的互
21、相协作和与其他组的交流中,在老师与助教的帮助下原本复杂的问题也渐渐的变得明朗了许多,很多东西也有了眉目。调试:在调试过程中间,我们同样遇到了许多的困难,如小车有时会接收不到信号,连接小车的导线被扯断等等。有一次小车出了问题,我们努力去寻找问题,一个零件一个零件去测,几乎把所有的零件全都拆下来了,还是没有发现问题;最后问其他组的同学借芯片插上去,问题解除了:原来是芯片坏了,我们大舒了一口气,虽然感觉白忙一场心里小小的不爽,不过解决问题之后还是很有成就感。我们发扬了团结协助的精神,不断地克服困难,特别是在指导老师细致耐心的指点下,我们取得了事半功倍的效果,在此非常感激给与我们小组帮助过的老师们。团
22、队协作:一个小团队,怎样分配每个人的工作,才能使整个队伍的效率最高?我们之前的分工很不明确,导致了整个项目的进展十分缓慢。直至期中考试过后,我们才意识到,必须有一个明确而详细的组织计划,才能指导我们正常进行下去。当每个人都有了自己负责的一方面时,这个团队之间即互相联系,又相对独立,整体的进度就可以大大提升了。也为我们以后的实践积累了经验。6. 致谢我们科创小组能够顺利实现完成这次科技创新三的课程实验,得益于多位老师和同学的帮助。首先要感谢开设这门课程并负责最终检验的的张士文老师,是他给我们宽松的氛围、齐备的材料,才使我们有信心和实力去做这个科创实验。其次要感谢的轮流在实验室给予我们悉心指导的各位助教,是他们耐心地听从我们的询问并且给予我们很多指点才使我们能够顺利地走在正确的设计路线上,这是我们能顺利做完课程实验不可缺少的因素之一。还要感谢的是在实验室和我们一起做科创,给我们帮助指导的其他组同学,与他们在一起做科创实验我们互相学习,互相帮助,一起努力,一起奋斗,使得我们有了不断开拓进取的精神和动力,也教给了我们很多东西。尤其是M07组,他们在小车硬件检查和串口方面给了我们很大的帮助。在此,我们对所有给予过指导和帮助的老师和同学致以衷心的感谢和敬意!