haihongyuan.com
海量文库 文档专家
全站搜索:
您现在的位置:首页 > 初中教育 > 学科竞赛学科竞赛

第八届飞思卡尔智能车竞赛摄像头组浙大三队技术报告

发布时间:2013-11-19 13:53:10  

第八届“飞思卡尔”杯全国大学

生智能汽车竞赛

技 术 报 告

学 校: 浙江大学

队伍名称: 浙江大学三队

参赛队员: 徐 兵

孙志成

何 迪

带队老师: 姚 维 韩涛

关于技术报告和研究论文使用授权的说明

本人完全了解第七届“飞思卡尔”杯全国大学生智能汽车竞赛关保留、使用技术报告和研究论文的规定,即:参赛作品著作权归参赛者本人,比赛组委会和飞思卡尔半导体公司可以在相关主页上收录并公开参赛作品的设计方案、技术报告以及参赛模型车的视频、图像资料,并将相关内容编纂收录在组委会出版论文集中。

参赛队员签名:

带队教师签名:

日期:

I

摘要

关键词:智能车,机械调整,图像分割,PID

Abstract

In this paper we present a smart car system based on the micro-controller K60, including machinery, hardware and software three aspects. In the principle of stability, simplicity and efficient, different schemes are designed for the three aspects, lots of tests are carried on for these schemes, and finally the current system are determined. The result of tests show that the design scheme of system is available.

Keywords: Smart car, Mechanical adjustment, Image Segmentation,PID

III

目录

引言 ....................................................................................................................... 1

第一章 系统设计概要 ......................................................................................... 3

1.1 系统工作原理 ......................................................................................... 3

1.2系统设计结构图 ...................................................................................... 3

第二章 赛车机械系统设计与实现 ..................................................................... 5

2.1 车体模型 ................................................................................................. 5

2.2 后轮参数的调整 ..................................................................................... 6

2.2.1 主销后倾角调整 ........................................................................... 6

2.2.2主销内倾角调整 ............................................................................ 7

2.2.3后轮前束调整 ................................................................................ 7

2.3前轮参数的调整 ...................................................................................... 8

2.3.2前轮滑差和轮距调整 .................................................................... 9

2.4底盘的调整 .............................................................................................. 9

2.5 舵机的安装 ............................................................................................. 9

2.6 CCD摄像头支架安装 ........................................................................... 10

2.7 光电编码器 ........................................................................................... 11

第三章硬件电路系统设计与实现 ..................................................................... 13

3.1硬件电路设计方案 ................................................................................ 13

3.2硬件电路的实现 .................................................................................... 13

3.2.1以K60为核心的单片机最小系统 ............................................. 13

3.2.2 电源板 ......................................................................................... 14

3.2.3 视频同步分离电路 ..................................................................... 15

1

第八届飞思卡尔全国大学生智能汽车竞赛

3.2.4 片外A/D电路 ............................................................................ 16

3.2.5 电机驱动电路 ............................................................................. 16

3.2.6键盘拨码电路 .............................................................................. 18

3.2.7 PCB板 .......................................................................................... 18

3.3 摄像头 ................................................................................................... 18

第四章软件系统设计与实现 ............................................................................. 21

4.1图像处理 ................................................................................................ 21

4.1.1图像采集 ...................................................................................... 21

4.1.2黑线提取 ...................................................................................... 21

4.1.3起始道判断 .................................................................................. 25

4.1.4虚线提取 ...................................................................................... 26

4.1.5图像校正 ...................................................................................... 27

4.2 控制算法 ............................................................................................... 28

4.2.1基于窗口的方向与速度控制 ...................................................... 28

4.2.2 PID速度闭环控制 .................................................................... 28

第五章调试工具开发与使用 ............................................................................. 31

5.1 开发工具 ............................................................................................... 31

5.2 串口调试 ............................................................................................... 31

5.2.1 C#图像显示程序 .......................................................................... 31

5.2.2 C#辅助调试程序 .......................................................................... 32

5.2.3 SD卡模块 .................................................................................... 32

第六章总结 ......................................................................................................... 34

参考文献 ...................................................................................................... 35

2

附录A:源程序 ................................................................................................. 37

3

引言

智能汽车竞赛最早始于韩国,在国内,全国大学生“飞思卡尔”杯智能汽车竞赛从2006年举办以来,得到了各级领导及高校师生的高度评价。大赛为智能车领域培养了大量后备人才,为大学生提供一个充分展示创造力的舞台,吸引着越来越多来自不同专业的大学生参与其中。

全国大学生“飞思卡尔”杯智能汽车竞赛包括光电组、摄像头组和电磁组,其中数摄像头组的智能车速度最快,备受关注。

本技术报告主要包括机械系统、硬件系统、软件系统等,详尽地阐述了我们的设计方案。这份报告凝聚了我们智慧,是我们小组共同努力的成果。

1

第一章 系统设计概要

1.1 系统工作原理

智能车系统的工作原理是:CCD摄像头拍摄赛道图像,通过片外AD进行模数转换,将得到的数据输入K60控制枢纽,通过一定的软件程序对图像进行分割,提取黑色引导线;通过编码器检测车速,通过K60输入捕捉功能进行脉冲计数得到小车的实时速度。由得到的引导线,选择参考行,通过分段P系数算法来控制舵机;通过赛道的曲率,计算得到目标速度,利用PID相结合的闭环控制算法调整电机来控制小车速度。

1.2系统设计结构图

本着稳定、简单、高效的设计原则,在将近一年的时间里,我们将小车不断改进,有以下几个特点:

机械方面:竖直安装舵机,提高转向反应速度;采用单碳素杆支架,辅以两根细碳素杆固定,并降低摄像头位置,降低重心。

硬件方面:保证稳定性前提下,尽量减小电路板面积;采用广角摄像头,保证各种S弯都能提取到完整的黑线。

软件方面:采用动态阈值和跟踪算法提取黑线,保证黑线稳定性;只采用简单的PID控制策略,并且基本上不对路型作判断,提高赛车对赛道适应性。

赛车的整体结构框图如图1.1所示:

3

第八届飞思卡尔全国大学生智能汽车竞赛

图1.1 系统框图

得到小车最终版如图1.2所示。

图1.2最终作品

4

第二章 赛车机械系统设计与实现

经过这长时间的调车经历,我们发现当速度达到一定值时,机械性能成为制约赛车速度提高的瓶颈。特别是后轮的前束角和内倾角对转弯的稳定性起着决定性的作用,而后轮差速齿轮的松紧对弯道内部速度也起着关键性的作用。在这一章我们主要介绍车模的机械结构和特点,并对舵机安装、后轮参数和前轮参数的调整和优化作简单叙述。

2.1 车体模型

赛车机械结构使用的是竞赛组委会提供车模的底盘部分及转向和驱动部分。控制采用后轮转向,前轮驱动方案。具体车模数据如下:

车总长:340mm

车总宽:172mm

示意图如图2.1所示:

图2.1车模模型图

模型车技术参数统计

5

第八届飞思卡尔全国大学生智能汽车竞赛

我们对车模进行改装后得到的赛车参数列于下表:

2.2 后轮参数的调整

后轮的参数主要包括后轮主销后倾角,主销内倾角,前束角等等。这几个参数对赛车直线的稳定性和弯道灵巧性都有很重要的影响。

2.2.1 主销后倾角调整

图2.2 主销后倾角

主销后倾角指车体纵向平面和地面垂直线的夹角,如图2.2所示,主销后倾角可以产生一个与转向相反的力矩使得车轮具有自动回正的能力,一般主销后倾角越大,车速越高,后轮的自动回正能力就越强。但是主销后倾角太大,将

6

第二章赛车机械系统设计与实现

会引起后轮回正过猛,导致转向沉重。调试中发现,我们发现车速加快后,增加主销后倾角未必是好事,但是通过适当调整,能在一定程度上稳定车身。

2.2.2主销内倾角调整

图2.3 主销内倾角β和外倾角α

如图2.3所示,主销内倾角是主销在汽车横向平面内向倾斜了一个β角,即主销轴线与地面垂线在汽车断面的夹角,调大主销内倾角的好处是,当后轮受到外力作用发生偏转,由于主销内倾,汽车前部被抬高,外力结束后,由于重力作用下又恢复到原来中间位置。经过长时间调试发现,适当调节对赛车的影响是不大的,所以可以在不影响性能的前提下尽量将主销内倾角调大。

后轮外倾角是后轮的上端向外倾斜的角度,如果前面两个轮子呈现“V”字形则称正倾角,呈现“八”字则称负倾角。后轮外倾可以抵消由于车的重力使车轮向内倾斜的趋势,减少赛车机件的磨损与负重。如果后轮过于外倾,会使汽车的直道行驶变得不稳定,所以我们在不影响转角的情况下,将外倾角调至最小。

2.2.3后轮前束调整

图2.4后轮前束

7

第八届飞思卡尔全国大学生智能汽车竞赛

后轮前束是后轮前端向内倾斜的程度,当两轮的前端距离小后端距离大时为内八字,前端距离大后端距离小为外八字。由于后轮外倾使轮子滚动时类似与圆锥滚动,从而导致两侧车轮向外滚开。但由于拉杆的作用使车轮不可能向外滚开,车轮会出现边滚变向内划的现象,从而增加了轮胎的磨损。后轮外八字与后轮外倾搭配,一方面可以抵消后轮外倾的负作用,另一方面由于赛车前进时车轮由于惯性自然的向内倾斜,外八字可以抵消其向内倾斜的趋势。外八字还可以使转向时靠近弯道内侧的轮胎比靠近弯道外侧的轮胎的转向程度更大,则使内轮胎比外轮胎的转弯半径小,有利与转向。但是,如果后轮调成了内倾角,则选用内八字比较好,因为这样两者刚好抵消,因此在调车我们选用了内倾加前束,效果还是很好的。

后轮调整图如图2.5所示:

图2.5 后轮调整效果图

2.3前轮参数的调整

2.3.1齿轮啮合调整

车模前轮采用由竞赛主办方提供的电机驱动。电机齿轮和滑差齿轮之间的内核对车的性能影响还是不小的。齿轮传动部分安装位置的不恰当,会大大增加电机驱动前轮的负载,影响车的加速度,从而影响到最终成绩。调整的原则可以归纳如下:两传动齿轮轴保持平行, 齿轮间的配合间隙要合适,过松容易打坏齿轮,过紧又会增加传动阻力,白白浪费动力;经过多次试验,啮合度在70%是比较理想的状态。编码器的齿轮和电机齿轮的齿数和模数是一模一样的,所以安装要点是一样的。

8

第二章赛车机械系统设计与实现

2.3.2前轮滑差和轮距调整

在拐弯时由于弯道内侧轮比外侧轮的拐弯半径小,则内侧轮比外侧轮的速度小,这就使两轮胎有一定的速度差,称为差速。为了考虑这种情况,车模中设计了机械差速齿轮,是赛车的内外轮在拐弯是做到协调。差速齿轮有以下特性:如果差速过紧,即两轮胎的速度很接近时,转弯的时候内侧轮很容易打滑,从而产生侧滑,使赛车滑出赛道。当差速过松时,会使直道的时候两轮打滑(电机不是处于后轴中央),大大的减小了赛车的驱动能力。所以差速调整要适当,才会使直道驱动能力强且稳定,弯道转弯容易。调整滑差的标准时,电机全速时捏住一个轮子,另外一个轮子刚好处于转与不转的边缘就好。

2.4底盘的调整

由于全国决赛时赛道直线部分可以有坡度在15度之内的坡面道路,包括上坡与下坡道路。所以摄像头安装不能非常的低,因为假如摄像头太低将会导致在上坡时赛车丢失道路信息,但是随着摄像头安装位置的提高,在高速过弯时则所需向心力比较大,同时由于惯性则车很容易向一侧翻倒。为了避免这类事情的发生,我们把车的后轮底盘放低,采用的方法是在前轴加装垫片,后轴的放低也是采用组办方提供的轴承,从而降低整车的重心,防止车翻倒。但是后轮的底盘高度不能太低,我们只加了一个半垫片,这是为了使车能顺利的上坡而不至于由于底盘过擦到赛道。

同时,我们采用了pcb板加固了地板,使底板变成了刚性,这样的好处是减少了摄像头与车模的相对位移,使读图更加准确。

2.5 舵机的安装

全国比赛过程中车速很快,这要求舵机转向要非常灵敏,我们使用的是主办方提供的S-D5舵机,额定电压为5V。为了解决舵机滞后问题,将舵机竖直安装,并且使输出杆等长,转角更加精确。舵机具体安装结构如图2.6所示:

9

第八届飞思卡尔全国大学生智能汽车竞赛

图2.6 舵机安装

2.6 CCD摄像头支架安装

根据上届同学的经验,我们选用了质地坚硬但重量较小的碳素杆作为摄像头的支架。并且用两根细碳素杆固定,以减少车身震动而引起摄像头震动。

图2.7 摄像头支架

10

第二章赛车机械系统设计与实现

2.7 光电编码器

我们采用增量式光电编码器实现对驱动电机转速的检测,通过齿轮传动的方式将测速电机上小齿轮与差速齿轮啮合,可以实时地获得准确的运行速度。我们考虑采用的是500线的小型编码器,该编码器的外径只有18mm,安装方便,重量也很小

11

第三章硬件电路系统设计与实现

3.1硬件电路设计方案

在智能车比赛中,硬件电路的设计思路是:稳定、高效、简单。

稳定性对于智能车这种比赛的重要性不言而喻,因此,设计电路板时,要考虑到接地,屏蔽,滤波等问题,将数字电路与模拟电路分开。

高效性主要体现在A/D转换和电机驱动电路上:

1、我们采用了TLC5510片外AD对图像进行采集,提高了图像数据的水平分辨率,对于黑线提取的准确性和距离都有了提高。

2、我们采用技术成熟的mos管作为电机的驱动芯片,它具有内阻小、转换效率高等特点。

简单性是指在满足了稳定性、高效性的前提下,为了尽量减轻整车重量,降低车体重心位置,应使电路设计尽量简单,尽量减少元器件的使用数量,缩小电路板面积,使电路板安装于车底盘上面。

3.2硬件电路的实现

整车的电路系统分为四个部:K60为核心的最小系统板、功能板和驱动板。功能板包括信号采集和处理、片外AD转换、数码管显示、串口输出等功能。

3.2.1以K60为核心的单片机最小系统

单片机最小系统板使用K60单片机,为了减小最小系统板的空间,板上仅将智能车所需要的引脚引出,包括三路PWM接口,串行通讯接口,一路计数器接口,两路外部中断接口等等。

单片机引脚规划如下:

PTC1-8:片外AD的输出接口

13

第八届飞思卡尔全国大学生智能汽车竞赛

PTC9,10,11,12,14:按键

PTB1,2,3,10:拨码盘

PE2-3,PH0-2:双位数码管

PTB0:舵机角度控制脉冲输出

PTD4-5:电机速度控制脉冲输出

PTB18-19:测速编码器脉冲输入

PTE25,PTA17:视频中断信号输入

PTD6-7:串口通讯输出

3.2.2 电源板

本系统中电源稳压电路有五路,有三路为+5V稳压电路,一路为+12V升压电路,另一路为+3.3V稳压电路。其中,+12V升压电路为CCD摄像头供电,三路+5V稳压电路分别为功能板内芯片、测速编码器和无线传输供电。为了提高最小系统部分的稳定性,我们采用三个+5V稳压电路分别供电,一路+3.3V稳压电路对最小系统板供电。

电源板结构图如图3.1所示:

图3.1 电源板结构图

14

第三章硬件电路系统设计与实现

电路原理图如图3.2所示:

图3.2电源稳压电路

系统中+5V电路功耗较小,最大可提供500mA电流,所以采用较为普遍的LM2940。最小系统板由AMS1117提供3.3V稳压。采用MC34063升压到12V,最大可提供1.5A电流,对CCD摄像头进行供电。

3.2.3 视频同步分离电路

我们的智能车使用黑白CCD摄像头对赛道信息进行采集。摄像头视频信号中除了包含图像信号之外,还包含场同步信号、场消隐信号、行同步信号、行消隐信号等等。因为,要对频率信号进行处理,就必须通过视频同步分离电路准确地把握各种信号间的逻辑关系。我们使用LM1881芯片对视频信号进行同步分离,得到场同步信号与行同步信号。视频同步分离电路如图3.3所示:

15

第八届飞思卡尔全国大学生智能汽车竞赛

图3.3 视频同步分离电路

3.2.4 片外A/D电路

K60单片机自身具有A/D转换功能,但是受到时钟总线的限制,其转换速度很慢。因此,我们使用TLC5510芯片作为片外A/D,K60单片机通过IO口进行图像数据采集。TLC5510是美国德州仪器公司生产的8位高速A/D转换器,它提供最大20Msps的采样频率。使用片外A/D后,受到IO口读取数据的限制,每行图像可以采集到120个有效点,这样,使图像的行分辨率提高了一倍。

TLC5510电路图如图3.4所示:

图3.4TLC5510电路图

3.2.5 电机驱动电路

电机驱动板为一个由分立元件制作的直流电动机可逆双极型桥式驱动器,其功率元件由四支 N 沟道功率 MOSFET 管组成,额定工作电流可以轻易达到 100A

以上,大大提高了电动机的工作转矩和转速。该驱动器主要由以下部分组

16

第三章硬件电路系统设计与实现

成: PWM号输入接口、逻辑换向电路、死区控制电路、电源电路、上桥臂功率 MOSFET 管栅极驱动电压泵升电路、功率 MOSFET 管栅极驱动电路、桥式功率驱动电路、缓冲保护电路等。我们采用IR公司的IRF3205芯片作为电机的驱动芯片,以IR公司的IR2104来控制桥臂的导通、关断。

图3.5 驱动电路图

得到实际电路板如图3.6所示:

图3.6驱动电路板

17

第八届飞思卡尔全国大学生智能汽车竞赛

3.2.6键盘拨码电路

图3.7 键盘拨码电路

3.2.7 PCB板

为了提高硬件稳定性,我们将除了驱动以外的硬件电路印证了一块与车模底板相适应的PCB板,如图3.8所示。将驱动电路与其他电路分开的目的是为了防止驱动电路工作时较大的驱动电流容易影响其他电路的工作,从而引起非正常工作。

图3.8 PCB板主电路

3.3 摄像头

我们对CCD摄像头和CMOS摄像头进行了对比。CMOS摄像头动态图像差,智能车在高速行驶时,图像模糊,不利于黑线的提取。CCD摄像头虽然工作电压为12V,且相对功率大,但图像对比度高,动态特性好,因此,我们CCD摄像头。

在调试过程,我们发现一旦小车进入弯道内部,在大部分情况下都不能提取到黑线,在120度大S弯里采用了270度弯的控制策略,大大降低了的速度,针对这种情况进行分析后,发现这是由于摄像头角度过窄导致S弯的左边界和

18

第三章硬件电路系统设计与实现

右边界在摄像头视角之外,如图3.8所示。将摄像头镜头换成广角之后,这种情况基本得到解决,在大S弯能够采取比较切线的线路,大大减小了小车行使的路程。

图3.8

两种摄像头镜头的视角范围

19

第四章软件系统设计与实现

4.1图像处理

4.1.1图像采集

为了提高分辨率,采用片外AD采集数据,每行可采集230点,这样我们即使将摄像头前瞻提高到1.7m也能精确地提取到黑色引导线,在兼顾道路信息和处理时间的前提下,提取45行进行处理,将摄像头提取到的数据存于二维数组image_data[i][j],得到图像图4.1所示。

图4.1 摄像头采集到的赛道图像

4.1.2黑线提取

黑线提取实际上是一种图像分割技术。图像分割指图像分成各具特性的区域并提取出感兴趣目标的技术和过程,是一种基本的计算机视觉技术。只有在图像分割的基础上才能对目标进行特征提取和参数测量,使得更高层的图像分析和理解成为可能。

由摄像头得到的图像实际上是一幅灰度图像,可以将图像分为几个区域,区域内部的灰度具有灰度相似性,而在区域边界上一般具有灰度不连续性,因

21

第八届飞思卡尔全国大学生智能汽车竞赛

此灰度图像分割一般可分为利用区域内灰度相似性的基于区域的方法和利用区域间灰度不连续性的基于边界的方法,分别称为阈值法和边界法。

阈值法是一种最常用的方法,基本思想是利用阈值来区分不同目标的灰度值,从而提取目标。对于摄像头而言,黑线部分灰度值小,白板灰度值大,设阈值为limit,若满足iamge_data[i][j] < limit,则该点为黑线点,由此可以提取到黑色引导线。阈值法的优点是算法简单,提取黑线,识别三角形、起始道具有一定的优势,缺点是易于受场地光线干扰。

边界法基于边界的分割方法是利用不同区域间象素灰度不连续的特点检测出区域间的边缘,从而实现图像分割。对于摄像头提取到的黑线而言,利用白板与黑线灰度值的差异来提取黑线,这一方法的优点是抗干扰性强,光线强度在一定范围内变化,对黑线提取基本上没有任何影响,但是算法相对较复杂,特别是在提取起始道和三角形方面。

结合上述两种方法的优点,我们采用动态阈值的方法来提取黑线。

具体的步骤是:

利用差值法在图像的前几行提取黑线,并记录黑线的灰度值,得到黑线与白板的阈值limit = 黑线灰度值 + 15。

利用该阈值采用阈值法来处理图像中其他行的图像,从而提取黑线。

在步骤①中,从左至右搜索目标,设定一差值,若满足image_data[row][line]>image[row][line+2]+limit(取白点到黑点的间距为2是为了消除白黑边界的灰点的影响),再从j=line+2+width(width代表黑线的最小宽度)进行搜索,若能搜到image_data[row][j]+limit< image_data[row][j+2],则该点满足黑线条件,取黑线中心点作为黑线位置。

按上述方法若能连续两行搜到黑线的点,并且两个黑线的点位置小于3 ,则说明已经提到黑线的头,如此则进入步骤②。

在步骤②中,利用步骤①所得到黑线的头来进行跟踪搜索。因为黑色引导线是连续的,所以相邻行的黑线点一定比较接近,利用这一特性,我们只需在一个较小的窗口内搜索就可以了。具体的办法是,根据已提取到的黑线计算斜率,并通过该斜率来预测下一行黑点的位置,利用阈值法,在以预测黑点为中

22

第四章软件系统设计与实现

心半径为R的窗口内搜索黑点。采用跟踪搜索的方法,由于只在一个很小的范围内搜索,所以可以大大减低其他物事对提取黑线的干扰,而且利用斜率来预测下一点的中心位置,这样对十字交叉道的滤除也有很好的效果,此外,该方法大大提高了算法效率。

我们组开了一个半径为4的窗口就能非常精确的提取黑线,具有很强的抗场外干扰能力。

具体流程图如图4.2和4.3所示。

图4.2 步骤①流程图

23

第八届飞思卡尔全国大学生智能汽车竞赛

图4.3 步骤②流程图

提取到黑线效果如图4.4所示

24

第四章软件系统设计与实现

图4.4 黑线提取效果图

4.1.3起始道判断

由于我们在黑线提取时采用跟踪扫描的方式,这种方法无法将起跑线或十字交叉完整地提取出来。于是,我们在提取完黑线之后再对起始道进行提取。为了提高效率,我们只在直道上执行起跑线识别算法。

具体的方法判断步骤是:

判断该幅图像为直线时,以得到的左黑线右边13点的区域内采用阈值法搜索黑点,若某行有5个黑点,并且黑点与提取到的黑线间有2个或以上的白点,记录该行的行序号,进入步骤②。

考虑到斜视起始道的情况,如下图所示,在①中得到行的上下各2行范围内搜索黑点,每行在以提取到的黑线点位置为中心,半径为20的范围内搜索。若满足下列三个条件则判断为起始道:

每行在黑线的左和右都有至少两个白点(防止十字交叉道)。

左边和右边的黑点数目都必须大于一个常数。

起始道右侧的黑线段必须小于一定长度,该长度计算方法如下,在黑线右侧搜索的5行中,找出位置最右和最左的点,并用前者减去后者,得到黑线长度。这个条件是为了防止斜视十字交叉道的情况,如图4.6所示。

25

第八届飞思卡尔全国大学生智能汽车竞赛

通过上述三个条件的限制,加上该部分算法只在直线上执行,起始道的判断相当精确了。

图4.5起始线的图像

4.1.4虚线提取

普通的黑线提取是逐行进行的,但是这在虚线处会有很大的问题,因为黑线是断续的,逐行扫描在断续处就会采不到黑线,从而无法正常提线。从十字的处理受到启发,我们采用了跳行采线的方式,根据斜率预测黑线将会出现的位置,然后在附近寻找黑线,提出黑点后再与前一个黑点根据斜率补线,并根据相同的方法接连提取,直到提取出整条线来。以下是我们提出来的虚线图4.6。

26

第四章软件系统设计与实现

图4.6虚线的图像

4.1.5图像校正

图像校正的实现如下:

(1) 调整好摄像头位置、前瞻,固定好;

(2) 将摄像头对准黑白相间的赛道板,拍摄图像;

(3) 用matlab编写程序进行筒形变换、透视变换,生成变换的常量表;

(4) 在单片机程序中加入常量表,然后就可进行相应的校正和反校正变换了。

(5) 用上位机观察的校正效果如下图4.7

27

第八届飞思卡尔全国大学生智能汽车竞赛

图4.7 赛道校正图

4.2 控制算法

4.2.1基于窗口的方向与速度控制

在距车前一定的距离分别选取方向和速度矩形窗口,提取窗口中的黑线位置,主要是偏离车身中央的距离,将窗口中各行的偏离距离取平均数作为方向和速度控制的基础参考量。转角大小与平均偏移量成正比,速度大小与平均偏移量成反比。窗口的位置决定了车切内道和贴线的程度。距离车身较近的窗口参考行决定了车贴线的程度,越靠近越贴线,走线越老实;距离车身较远的窗口参考行决定了车切道或穿S弯的程度,越靠前路线越内切或直穿。

在实际操作时,依据现有的速度和本场图像的黑线长度来确定选用哪几行数据作为控制速度和转向的窗口。当速度较快、黑线较长时选取远处行的数据;反之,选择近处行。

4.2.2 PID速度闭环控制

PID控制器(比例-积分-微分控制器),由比例单元 P、积分单元 I 和微分单元 D 组成。通过Kp, Ki和Kd三个参数的设定。PID控制器主要适用于基本线性和动态特性不随时间变化的系统,如图4.7所示。

28

第四章软件系统设计与实现

图4.7 PID系统框图

控制器是一个在工业控制应用中常见的反馈回路部件。这个控制器把收集到的数据和一个参考值进行比较,然后把这个差别用于计算新的输入值,这个新的输入值的目的是可以让系统的数据达到或者保持在参考值。和其他简单的控制运算不同,PID控制器可以根据历史数据和差别的出现率来调整输入值,这样可以使系统更加准确,更加稳定。可以通过数学的方法证明,在其他控制方法导致系统有稳定误差或过程反覆的情况下,一个PID反馈回路却可以保持系统的稳定。

PID是以它的三种纠正算法而命名的。这三种算法都是用加法调整被控制的数值。而实际上这些加法运算大部分变成了减法运算因为被加数总是负值。这三种算法是:

比例- 来控制当前,误差值和一个负常数P(表示比例)相乘,然后和预定的值相加。P只是在控制器的输出和系统的误差成比例的时候成立。

积分I来控制过去,误差值是过去一段时间的误差和,然后乘以一个负常数I,然后和预定值相加。I从过去的平均误差值来找到系统的输出结果和预定值的平均误差。一个简单的比例系统会振荡,会在预定值的附近来回变化,因为系统无法消除多余的纠正。通过加上一个负的平均误差比例值,平均的系统误差值就会总是减少。所以,最终这个PID回路系统会在预定值定下来。

导数D来控制将来,计算误差的一阶导,并和一个负常数D相乘,最后和预定值相加。这个导数的控制会对系统的改变作出反应。导数的结果越大,那么控制系统就对输出结果作出更快速的反应。这个D参数也是PID被成为可预测的控制器的原因。D参数对减少控制器短期的改变很有帮助。一些实际中的速度缓慢的系统可以不需要D参数。

29

第五章调试工具开发与使用

5.1 开发工具

程序开放在IAR Embedded Workbench IDE下进行, Embedded Workbench for ARM 是IAR Systems 公司为ARM 微处理器开发的一个集成开发环境(下面简称IAR EWARM)。比较其他的ARM 开发环境,IAR EWARM 具有入门容易、使用方便和代码紧凑等特点。

EWARM 中包含一个全软件的模拟程序(simulator)。用户不需要任何硬件支持就可以模拟各种ARM 内核、外部设备甚至中断的软件运行环境。从中可以了解和评估IAR EWARM 的功能和使用方法。

5.2 串口调试

智能车的调试过程,实际上是一个分析实验数据、改进算法的过程,而这需要以大量的实验数据作为基础。图像方面,编写了基于PC机的C#程序,用于显示实际用于单片机处理的图像;控制参数方面,在C#环境下开发了可用于显示各控制参数,以及所提取黑线的实时变化的辅助调试软件。

5.2.1 C#图像显示程序

图5.1是程序界面,上位机通过串口与K60相连,得到摄像头采集到的实时图像数据,并将其以灰度值显示,如图5.2所示。该部分程序参照前人成果编写而成,实际效果非常不错。

图5.1 C#图像显示程序界面

31

第八届飞思卡尔全国大学智能汽车竞赛

图5.2C#生成K60提取到的图像

5.2.2 C#辅助调试程序

该程序是在C#软件编程环境下实现的一个基于完成显示黑线信息、绘制参数变化图、存储数据和保存图像功能。图5.3是控制参数变化图显示界面,完成将控制参数绘制成以时序为基础的曲线。把智能车在行驶中的黑线数据和参数通过无线传输工具传到上位机中,进行参数分析,这样我们就可以知道黑线、舵机转向和马达速度在具体赛道的变化趋势,调试起来非常具有针对性。

图5.3参数传输界面

5.2.3 SD卡模块

SD卡是一种基于半导体快闪存的新一代记忆设备。由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制,其大小犹如一张邮票,重量只有2克,却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全

32

第五章调试工具开发与使用

性。

实现SD卡的功能,可以通过软件的编写实现。首先需要将SPI模块设置为主机模式,并设置相关的寄存器使SPI模块有高速和低速之分。SD卡的软件设计主要包括两部分内容:SD卡的上电初始化过程和对SD卡的读写操作。SD卡上电后,主机必须先向SD卡发送74个时钟周期,以完成SD卡上电过程。SD卡上电后会自动进入SD总线模式,并在SD总线模式下向SD卡发送复位命令(CMD0),若此时片选信号CS处于低电平态,则SD卡进入SPI总线模式,否则SD卡工作在SD总线模式。SD卡进入SPI工作模式会发出应答信号,若主机读到的应答信号为01,即表明SD卡已进入SPI模式,此时主机即可不断地向SD卡发送命令字(CMD1) 并读取SD卡的应答信号,直到应答信号为00,以表明SD卡已完成初始化过程,准备好接受下一命令。

33

第六章总结

综上所述,

在机械方面,为了提高转向的灵敏性,竖直安装舵机;分析了后轮束角和主销倾角对转向的影响,并对其进行优化。

硬件电路方面,采用片外AD,提高分辨率;在保证稳定性前提下,尽量减小电路板面积;采用广角摄像头,保证各种S弯都能提取到完整的黑线。

软件算法方面,采用动态阈值和跟踪算法提取黑线,保证黑线稳定性;简化控制策略,基本对路型不作判断,提高小车对赛道的适应性。

然而,我们的车模仍然存在一些不足。我们三个人对小车的机械构造缺乏深入的认识,调试过程中摸着石头过河,走了不少弯路,与一些强队相比,仍然是相形见绌。虽然广角摄像头有利于弯道内部提取黑线,但是造成了很大的图形畸变,使图像变差,并且使小车走120度大S弯风险性很大。

在大半年的调车过程中,我们经历了学校的选拔赛、浙江赛区省赛直至即将到来的全国赛,一路走来,我们付出了很多,也收获了很多。在一张白纸上,我们从零开始。从学习K60单片机到组装车模,从舵机和马达徐徐转动到摄像头采集到数据,从黑线提取到控制策略,我们见证了小车从蜗牛般爬动到猎豹般飞驰的成长历程。付出的是汗水,收获的是硕果,在这大半年的时间里,我们不仅完成了小车的蜕变,也学到了很多,从电路板绘制到控制策略,从机械性能到单片机,从战胜失败的勇气到团队合作,我想这段经历将是一笔人生的财富。

在备战过程中,特别感谢学校和学院提供的经费和场地支持,感谢各位老师和学长的悉心指导。

34

参考文献

[1] 卓晴, 黄开胜,邵贝贝. 学做智能车[M]. 北京:北京航天航空大学出版社, 2007.3

[2] 臧杰,阎岩. 汽车构造[M]. 北京. 机械工业出版社[M].2005

[3] 邵贝贝. 单片机嵌入式应用的在线开发方法[M].清华大学出版社,2004

[4] 楚现知,吴吉祥,李锦忠. 基于LabVIEW的监控界面设计与单片机的串行通信[J].工业控制计算机,2005年18卷第7期

[5] 杨晖,曲秀杰. 图像分割方法综述.电脑开发与应用[J].2005.3

[6]俞斌,翁华,华文. 浙江大学EE-fly队技术报告.

[7]张鹏,徐怡,任亚楠.北京科技大学CCD一队技术报告.

[8]庆楠,蔡兴旺,潘锦州. 上海大学S.U.L挑战者技术报告.

[9] 胡晨晖, 陆佳南,陈立刚. 上海交通大学CyberSmart 队技术报告.

[10] 林辛凡, 李红志, 黄颖. 清华大学三角洲队技术报告.

[11]卓晴,王琎,王磊. 基于面阵CCD的赛道参数检测方法. 电子产品世界,2006

35

附录A:源程序

————————————————————————————————— #include "motorservo.h"

extern int s_kd_set;

extern int s_kp_set;

extern int steer_old;

extern int steer;

extern unsigned char path;

extern uint8 black_top[2];

extern int CtrlWindow_set;

extern uint8 road_state;

extern int time1s;

extern uint8 road_state_old1;//xubing

extern uint8 road_state_old2;//xubing

extern uint8 road_state_old3;//xubing

extern uint8 road_state_old4;//xubing

extern int skew_dv;//xubing

extern int skew_limit;//xubing

extern int skew_v;//xubing

extern int spd_s_dis;//xubing

extern int Ls_C;

extern int kp_Ls;

extern int Cross_p;

extern int zhidaoyanchi;

extern int djxs;

extern int Bshgxs;

extern int speedd_record_0;

extern int speedd_record_1;

extern int speedd_record_2;

extern int speedd_record_3;

extern int speedd_record_4;

extern int real_steer_0;

extern int real_steer_1;

extern int real_steer_2;

extern int real_steer_3;

extern int real_steer_4;

extern int pwm_stop;

extern int kpcross;

extern uint8 the_startline;

extern int stop_signal;

extern int stop_delay;

extern int stop_delay_count;

37

第八届飞思卡尔全国大学生智能车竞赛

extern int start_count;

extern int wandao;

extern int speed;

extern int choose;

extern int blacktop;

extern int blacktop_count;

extern int vary_long_add;

extern int bendplus;

int sum;

extern int speedd;

extern int kpzhi;

extern int high_speed;

extern int low_speed;

extern int spd_hanggao;

extern int wandaojizhi;

extern int lsxishu;

extern LOCATION left_blk_loc[ROW_MAX];

extern LOCATION right_blk_loc[ROW_MAX];

extern int speed_now;

extern int gyroscope;

extern int jizhi;

extern int rs;

extern int jizheng;

extern int jibian;

extern int speed_set_set;

extern int ckb1;

extern int ckblr1;

extern int speed_Str_count;

extern int sdbhxs;

extern uint8 SWitch[4];

/***********************************************************************************************

Function: // motorservo_ctl( uint8 line_state[], uint8

black_location[][ROW_MAX] )

Description:

Input:

Return:

////speed = 50 ; ckb = 2; ckblr = 6;

*************************************************************************************************/

int CtrlWindow = 0;

int CtrlWindow_old = 0;

int ckb = 0;

int ckblr = 0;

int tempt;

int head = 0;

38

附录A:源程序

int tail = 0;

int center_list[] ={64, 54, 46, 38, 30, 23, 20, 17, 15, 14};//{55, 71, 62, 53, 45, 37, 31, 29, 27, 24}; //{80, 71, 62, 54, 45, 38, 31, 29, 28, 27}

int center_list_fix[] = {4, 12, 19, 19, 20, 13, 12, 12, 11, 10};//{9, 8, 7, 6, 5, 5, 4, 4, 3, 3};//{5, 5, 5, 4, 3, 3, 2, 2, 2, 1};

//int fix = 0;

int center = 50;

int speed_chose;

int steers[45];

int fsteers[45] ;

int real_steer;

/*-------------------------------------------*/

int speed_lock_count = 0;

int speed_bend_count = 0;

int real_steer_old;

int d_real_steer=0;

int speed_limit_max = 100;

int nochange_steer_count=0;

int way_state=-1;

int way_state_old=-1;

int head1=0;

int head2=0;

int head3=0;

int biaozhiwei=0;

int biaozhiwei2=0;

int slopecount=0;

int slopecount2=0;

int speed_now3=0;

int speed_now2=0;

int speed_now1=0;

int speed_now_before=0;

int speed_now_now=0;

int speed_now_difference=0;

int speedplus=0;

#define MAXSTEEL 190

#define MINSTEEL -190

void motorservo_ctl(uint8 line_state[])

{

int cb_left, cb_right; //ck_left, ck_right

int j;//, l, m;

int LineChoosed = 5;

int abs1=0;

int abs2=0;

//int n;

//int temp;

int sum = 0;

int ttt=0;

//int d;

int kd,kp;

39

第八届飞思卡尔全国大学生智能车竞赛

/* int d_steer;

int steerfix = 0;

int s_k = 0;

int temp1;

int ttt1;*/

ckb = ckb1;

ckblr =ckblr1;

steer_old = steer;

real_steer_old = real_steer;

kd = s_kd_set;

kp = s_kp_set;

if (line_state[LEFT] != 0 && line_state[RIGHT] != 0)

{

head = black_top[LEFT] > black_top[RIGHT] ? black_top[LEFT] : black_top[RIGHT]; tail = black_top[LEFT] <= black_top[RIGHT] ? black_top[LEFT] : black_top[RIGHT]; }

else if (line_state[LEFT] != 0)

{

head = black_top[LEFT];

tail = 0;

}

else if (line_state[RIGHT] != 0)

{

head = black_top[RIGHT];

tail = 0;

}

else

{

head = 0;

tail = 0;

}

CtrlWindow = CtrlWindow_set;//(int)numericUpDown2Cols.Value; if (head == 0)

{

CtrlWindow = 0;

}

else if (CtrlWindow > head - 2)

{

CtrlWindow = head - 2;

}

else if (CtrlWindow < 5)

{

CtrlWindow = 5;

}

if (CtrlWindow >= 1 )

{

for (LineChoosed = 5; LineChoosed <= 42; LineChoosed++)

40

附录A:源程序

{

if (LineChoosed <= head - 2)

{

if (left_blk_loc[LineChoosed - 2].x != LINE_MAX - 1 && left_blk_loc[LineChoosed +

1].x != LINE_MAX - 1 && line_state[LEFT] != MISSING)

{

sum = 0;

for (j = LineChoosed - 2; j <= LineChoosed + 1; j++)

{

sum += left_blk_loc[j].x;

}

cb_left = (sum / 4) - 115;

}

else

{

cb_left = NaN;

}

if (right_blk_loc[LineChoosed - 2].x != 0 && right_blk_loc[LineChoosed + 1].x != 0 &&

line_state[RIGHT] != MISSING)

{

sum = 0;

for (j = LineChoosed - 2; j <= LineChoosed + 1; j++)

{

sum += right_blk_loc[j].x;

}

cb_right = 115 - (sum / 4);

}

else

{

cb_right = NaN;

}

center = center_list[LineChoosed / 5];

center += center_list_fix[LineChoosed / 5]*10/10;

if (cb_left != NaN && cb_right != NaN)

{

steers[LineChoosed] = (cb_right - cb_left) * ckb / 10;//20; // ckb * 3 / 10 ***** // ckb * 3 / 8

}

else if (cb_left != NaN)

{

steers[LineChoosed] = (center - cb_left) * ckblr / 12;

}

else if (cb_right != NaN)

{

steers[LineChoosed] = -(center - cb_right) * ckblr / 12;

}

else if (LineChoosed >= 10)

{

steers[LineChoosed] = steers[LineChoosed - 1];

}

41

第八届飞思卡尔全国大学生智能车竞赛

else

{

steers[LineChoosed] = steer_old;

}

//steers[k] = (steers[k] > MAXSTEEL) ?MAXSTEEL : ((steers[k] < MINSTEEL) ? MINSTEEL : steers[k]);

}

else if (head >= 10)

{

steers[LineChoosed] = steers[LineChoosed - 1];

}

else

{

steers[LineChoosed] = steer_old;

}

}

for (j = 5; j <= 42; j++)

{

if (j < 6 || j >= 42)

{

fsteers1[j] = steers[j];

}

else

{

if ((steers[j - 1] <= steers[j] && steers[j] <= steers[j + 1]) || (steers[j - 1] >= steers[j] && steers[j] >= steers[j + 1]))

{

fsteers1[j] = steers[j];

}

else if ((steers[j] <= steers[j - 1] && steers[j - 1] <= steers[j + 1]) || (steers[j] >= steers[j - 1] && steers[j - 1] >= steers[j + 1]))

{

fsteers1[j] = steers[j - 1];

}

else

{

fsteers1[j] = steers[j + 1];

}

}

}

for (j = 5; j <= 42; j++)

{

if (j < (n + 1) / 2 || j >= 42 - n / 2)

{

fsteers2[j] = steers[j];

}

else

{

temp = 0;

42

附录A:源程序

for (l = 0; l < n; l++)

{

temp = temp + steers[j - (n + 1) / 2 + l];

}

fsteers2[j] = temp / 3;

}

}

if (CtrlWindow != 0)

{

steer = fsteers[CtrlWindow];

}

}

else if(road_state == Cross )

if(head != 0)

{

LineChoosed = head >30 ?30 : head - 3;

if (LineChoosed <= head - 2)

{

if (left_blk_loc[LineChoosed - 2].x != LINE_MAX - 1 && left_blk_loc[LineChoosed + 1].x != LINE_MAX - 1 && line_state[LEFT] != MISSING)

{

sum = 0;

for (j = LineChoosed - 2; j <= LineChoosed + 1; j++)

{

sum += left_blk_loc[j].x;

}

cb_left = (sum / 4) - 115;

}

else

{

cb_left = NaN;

}

if (right_blk_loc[LineChoosed - 2].x != 0 && right_blk_loc[LineChoosed + 1].x != 0 && line_state[RIGHT] != MISSING)

{

sum = 0;

for (j = LineChoosed - 2; j <= LineChoosed + 1; j++)

{

sum += right_blk_loc[j].x;

}

cb_right = 115 - (sum / 4);

}

else

{

cb_right = NaN;

}

center = center_list[LineChoosed / 5];

if (cb_left != NaN && cb_right != NaN)

{

43

第八届飞思卡尔全国大学生智能车竞赛

steer = (cb_right - cb_left) * ckb / 20; // ckb * 3 / 10 ***** // ckb * 3 / 8

}

else if (cb_left != NaN)

{

steer = (center - cb_left) * ckblr / 12;

}

else if (cb_right != NaN)

{

steer = -(center - cb_right) * ckblr / 12;

}

else

{

steer = steer_old;

}

//steers[k] = (steers[k] > MAXSTEEL) ?MAXSTEEL : ((steers[k] < MINSTEEL) ? MINSTEEL : steers[k]);

}

}

}

Path_Judge( fsteers, &road_state, black_top);

if((road_state_old1==Slopetop) && (road_state_old2==Slopetop) &&

(road_state_old3==Slopetop))

{

biaozhiwei=1;

slopecount=50;

biaozhiwei2=1;

slopecount2=150;

}

slopecount--;

slopecount2--;

if((road_state_old1==Slopedown1) && (road_state_old2==Slopedown1) &&

(road_state_old3==Slopedown1))

{

biaozhiwei=0;

slopecount=0;

}

if(slopecount==0)

biaozhiwei=0;

if(slopecount<=48 && slopecount!=0 && biaozhiwei==1) road_state = Slopedown2;

if(slopecount2==0)

biaozhiwei2=0;

if(biaozhiwei2==0 && road_state == Slopedown1) road_state = Str;

steer = fsteers[CtrlWindow];

if(road_state == Str )

44

附录A:源程序

{

CtrlWindow = 25;

steer = fsteers[CtrlWindow];

ttt=1;

}

if( road_state == Ls )

{

steer = fsteers[Ls_C];

}

if(road_state == Str || road_state == Stop || road_state == Cross || road_state == Ls && speed_Str_count>zhidaoyanchi) {

kp = kpzhi;

kd = 0;

}

if(road_state == Str || road_state == Stop || road_state == Cross || road_state == Ls) { kp = kpzhi+3;

kd = 0;

}

if(road_state == Cross)

{

CtrlWindow = 25;

steer = fsteers[CtrlWindow];

}

real_steer = kp * steer / 10 ;

if(road_state == Str || road_state == Ls || road_state == Stop || road_state == Slopetop) {

speedd = high_speed;

}

else if (road_state ==Slopedown2)

{

speedd = low_speed-40;

}

else if (road_state ==Slopedown1)

{

speedd = low_speed-20;

}

else

{

speedd = low_speed;

}

d_real_steer=real_steer-real_steer_old;

real_steer+=kd*d_real_steer/10;

if(road_state == Bs )

real_steer=real_steer*(100-blacktop*Bshgxs/10)/100;

if(real_steer>0)

abs1=real_steer;

if(real_steer<0)

abs1=-real_steer;

45

第八届飞思卡尔全国大学生智能车竞赛

if(real_steer_old>0)

abs2=real_steer_old;

if(real_steer_old<0)

abs2=-real_steer_old;

if(CtrlWindow < CtrlWindow_set && abs1<abs2)

real_steer=real_steer/2+real_steer_old/2;

if (CtrlWindow<CtrlWindow_set-3)

real_steer= real_steer*(jibian+3)/10;

else if (CtrlWindow<CtrlWindow_set-2 )

real_steer= real_steer*(jibian+2)/10;

else if (CtrlWindow<CtrlWindow_set-1 )

real_steer= real_steer*(jibian+1)/10;

else if (CtrlWindow<CtrlWindow_set )

real_steer= real_steer*jibian/10;

real_steer = real_steer >MAXSTEEL ?MAXSTEEL : (real_steer < MINSTEEL ? MINSTEEL : real_steer);

/* if(real_steer>40&& real_steer<101 &&real_steer > steer_old-1) {

speed_limit_count+=30;

} else if(real_steer>100&& real_steer<151 &&real_steer > steer_old-1)

{

speed_limit_count+=40;

} else if(real_steer>150 &&real_steer > steer_old-1)

{

speed_limit_count+=55;

}

if(real_steer<-40&& real_steer>-101 &&real_steer < steer_old+1)

{

speed_limit_count+=30;

} else if(real_steer<-100&& real_steer>-151 &&real_steer < steer_old+1)

{

speed_limit_count+=40;

} else if(real_steer<-150 && real_steer < steer_old+1) {

speed_limit_count+=55;

}

if(real_steer<200 && real_steer>150 &&real_steer < steer_old-10 &&

46

附录A:源程序

speed_limit_count>-5)

{

speed_limit_count -=5;

} else if(real_steer<150 && real_steer>50 &&real_steer < steer_old && speed_limit_count>-5)

{

speed_limit_count -=5;

}

if(real_steer>-200 && real_steer< -150 &&real_steer > steer_old+10 &&

speed_limit_count>-5)

{

speed_limit_count -=5;

} else if(real_steer>-150 && real_steer< -50 &&real_steer > steer_old && speed_limit_count>-5)

{

speed_limit_count -=5;

}

if((real_steer>0&&real_steer<steer_old && real_steer >

steer_old+50)||(real_steer<1&&real_steer>steer_old&&real_steer<steer_old+50))

{

if(real_steer>-20 && real_steer< 20 && steer_old >-25 && steer_old <25&& speed_limit_count<30)

{

speed_limit_count=5;

}

if(real_steer>-30 && real_steer< 30 && speed_limit_count>30 )

{

speed_limit_count -=5;

}else if(real_steer>-50 && real_steer< 50 && speed_limit_count>100 )

{

speed_limit_count -=5;

}

}

if(speed_limit_count>190) speed_limit_count=190;

if(speed_limit_count<-5) speed_limit_count=0;

if(real_steer>190|| real_steer<-190)

{

speed_limit_count=190;

}

if(real_steer>195&&steer_old>195)

{

speed_limit_count=speed_limit_count-10;

}

47

第八届飞思卡尔全国大学生智能车竞赛

speed = speed_set_set - speed_limit_count;

}

*/

blacktop=(black_top[LEFT]+black_top[RIGHT])/2;

speed_now3=speed_now2;

speed_now2=speed_now1;

speed_now1=speed_now;

speed_now_before=(speed_now3+speed_now2)/2;

speed_now_now=(speed_now2+speed_now1)/2;

speed_now_difference=speed_now_now-speed_now_before; if(speed_now_difference<0 && road_state ==Bend)

real_steer=(100+speed_now_difference*100*sdbhxs/speed_now)*real_steer/100;

if(real_steer - real_steer_old > 60)

{

real_steer =real_steer_old + 60;

} else if (real_steer-real_steer_old < -60 )

{

real_steer =real_steer_old - 60;

}

steer_control(real_steer);

start_count=start_count+1;

if(stop_delay<stop_delay_count)

{

if(road_state != Bs )

spd_s_dis=10;

speedd=low_speed+blacktop*blacktop*spd_hanggao*spd_s_dis/20250;

if (road_state ==Slopedown2 || road_state ==Slopedown1)

speedd=speedd-40;

if(road_state ==Str )

speedd=speedd+jizhi;

if(road_state ==Ls )

speedd=speedd+jizhi*lsxishu/10;

skew_v=skew_dv-skew_dv*(real_steer/10)*(real_steer/10)/(skew_limit*skew_limit); if(skew_v<0)

skew_v=0;

if(blacktop>=40)

blacktop_count=blacktop_count+1;

else

blacktop_count=0;

if((blacktop_count>=10)&&(road_state==Str))

speedd=speedd+vary_long_add;

if((blacktop_count>=10)&&(road_state==Ls))

speedd=speedd+vary_long_add*lsxishu/10;

if((GPIOB_PDIR & (1 << SWitch[1]))!=0){

48

附录A:源程序

speedd=speedd+skew_v;

}

if((road_state==Bs)||(road_state==Bend))

{

if(real_steer>0)

bendplus=real_steer;

else

bendplus=-real_steer;

if(bendplus<140){

speedplus=(140-bendplus)*djxs/100;

speedd=speedd+speedplus;

}

}

if((road_state==Bs)||(road_state==Bend))

{

if(real_steer>0)

bendplus=real_steer;

else

bendplus=-real_steer;

if(bendplus>130)

nochange_steer_count=0;

else if((real_steer - real_steer_old<=15)&&(real_steer - real_steer_old >=-15))

nochange_steer_count++;

else if((real_steer - real_steer_old<=25)&&(real_steer - real_steer_old > 15)||(real_steer - real_steer_old<-15)&&(real_steer - real_steer_old >-25))

nochange_steer_count=nochange_steer_count;

else

nochange_steer_count=0;

speedd=speedd+nochange_steer_count*wandao/10;

}

if(road_state==Bend)

speedd=speedd+wandaojizhi;

speedd_record_0=speedd_record_1;

speedd_record_1=speedd_record_2;

speedd_record_2=speedd_record_3;

speedd_record_3=speedd_record_4;

speedd_record_4=speedd;

speedd=(speedd_record_0+speedd_record_1+speedd_record_2+speedd_record_3+speedd_record_4)/5;

int speeddd;

if(speed_now>speedd+15)

motor_control(0,pwm_stop*10);

else

{

speeddd=setPID1(speedd,speed_now);

// speeddd=setPID1(speedd,speed_now);

motor_control(speeddd,0);

}

}

49

第八届飞思卡尔全国大学生智能车竞赛

else

{

if(speed_now>50)

motor_control(0,300);

else

motor_control(0,0);

}

}

#include "MSCtrl.h"

#include "includes.h"

extern int speed_Str_count;

extern int speed_set1,speed_set2,speed_set3,speed;

extern int speedPWM4;

extern int speed_switch_count,speed_PWM_record[10],speed_detect_record[10]; extern uint8 road_state;

extern int power;

extern int strchange;

extern int accelpara;

extern int kpkp;

extern int kiki;

extern int kdkd;

extern int kpkpkp;

extern int spendlimit;

extern int pwm_full;

extern int cur0;

extern int cur1;

extern int cur2;

extern int cur00;

extern int cur01;

extern int cur02;

extern int start_count;

int cur03=11;

int cur04=11;

int cur05=11;

int cur06=11;

int cur07=11;

int cur08=11;

int strchangege;

int KP;

int KI;

int KD;

int SPEED_FIX(int set,int road_state)

{

int i,temp1,temp2,speed_want;

int speed_set=set;

if(road_state!= Str && road_state!= Ls &&road_state!= Cross )speed_Str_count=0; switch(road_state)

{

50

附录A:源程序

case Str :

speed_Str_count++;

break;

case Ls :

speed_Str_count++;

break;

case Cross :

if(speed_Str_count>0)speed_Str_count--;

break;

case Stop :

break;

default:

break;

}

if(speed_set>350) speed_set=350+speed_Str_count-20;

if(speed_Str_count>=35) speed_Str_count=30;

speed_set1=speed_set2;

speed_set2=speed_set3;

speed_set3=speed_set;

temp1=speed_set2-speed_set3;

temp2=speed_set1-speed_set2;

temp1=temp1*temp2;

if(temp1>0||temp1==0){

speed_want=speed_set3;//

}

else

{

speed_set3=speed_set2; speed_want=speed_set3;

}

if(speed_want!=speed_set2)

{

speedPWM4=speedPWM4+speed_want-speed_set2;

}

if(speed_switch_count>10) //////增强减速

speedPWM4=speedPWM4-20;

temp1=speed_set3-speed_set2;

temp2=speed_set2-speed_set1;

if(road_state!=Str && road_state!=Unknow && road_state!= Ls &&road_state!= Cross) {

if(temp1>50||temp1<-50||temp2>50||temp2<-50) {

speed_switch_count=20;

}

else /////

{

if(speed_switch_count>0)speed_switch_count--; } }

if(speedPWM4>220)

speedPWM4=220;

if((speedPWM4<150&&road_state==Str)||(speedPWM4<150&&road_state== Ls)) speedPWM4=150;

if(speedPWM4<spendlimit)

speedPWM4=spendlimit;

51

第八届飞思卡尔全国大学生智能车竞赛

//if(strchangege!=0&&road_state!= Str && road_state!= Ls && road_state!= Cross) for(i=0;i<9;i++)

{

speed_PWM_record[i]=speed_PWM_record[i+1];

}

speed_PWM_record[9]=speedPWM4;

return speedPWM4;

}

#include "includes.h"

#include <string.h>//用了strcpy函数

uint8 image_get_state;

uint8 image_flash_flag;

uint8 image_data[ROW_MAX][LINE_MAX];

LOCATION2 img_reg[ROW_MAX][LINE_MAX];

LOCATION left_blk_loc[ROW_MAX],right_blk_loc[ROW_MAX]; uint8 black_top[2];

uint8 line_state[2];

uint8 road_state;

FIL faddata;

FATFS fs;

extern uint8 SWitch[4];

extern int periph_clk_khz;

uint8 road_state_old1;

uint8 road_state_old2;

uint8 road_state_old3;

uint8 road_state_old4;

int high_speed=230;

int low_speed=195;

int spd_hanggao=70;

int skew_dv=20;

int skew_limit=18;

int skew_v=0;

int spd_s_dis=7;

int Ls_C=25;

int sdbhxs=3;

int djxs=20;

int Bshgxs=5;

int bend_speed=220;

int speedd_record_0=200;

int speedd_record_1=200;

int speedd_record_2=200;

int speedd_record_3=200;

int speedd_record_4=200;

int real_steer_0=0;

int real_steer_1=0;

int real_steer_2=0;

int real_steer_3=0;

int real_steer_4=0;

52

附录A:源程序

int bendplus=0;

int cur0=0;

int cur1=0;

int cur2=0;

int cur00=0;

int cur01=0;

int cur02=0;

int Cross_p=0;

int kpcross=12;

int zhidaoyanchi=5;

uint8 the_startline = 0;

int stop_signal=0;

int stop_delay=0;

int stop_delay_count=15;

int start_count=0;

int kpkp=4;

int kiki=0;

int kdkd=0;

int kpkpkp=12;

int kpzhi=5;

int kp_Ls=5;

int hhdd=200;

int pwm_full=100;

int pwm_stop=30;

int jizhi=80;

int wandao=10;

int wandaojizhi=3;

int lsxishu=5;

int ckb1 = 10;

int ckblr1 =20;

const uint8 road_width[10] = {170,170,150,145,141,130,125,120,115,110}; int param_k = 0;

int speed_set1=0, speed_set2=0, speed_set3=0;

int speedPWM4 = 0, speedPWM7 = 0; int error1 = 0,error2= 0,error3= 0,error4= 0,error5= 0,error_differential= 0;

int speed_param1=0,speed_param2=0;

long int error_sum= 0;

int speed_switch_count=0,speed_PWM_record[10],speed_detect_record[10];

int speed_Str_count;

int speed_limit_count;

uint16 time2ms=0;

uint8 strategy=0;

int strchange=18;

uint8 pos=6;

int CtrlWindow_set = 18;

int dbg_counter = 0;

int PWM_set = 80;

int speed_set_set = 200;

int param_new_car_Kp_set = 10;

int param_new_car_Ki_set = 300;

int param_new_car_Kd_set = 50;

53

第八届飞思卡尔全国大学生智能车竞赛

int s_kd_set = 0;

int s_kp_set = 11;

int ckb_set = 14;

int ckblr_set = 28;

int g_voltage;

uint8 pwm4;

int nothing = 0;

int speedd=0;

int speeddd=0;

int blktop=0;

int jibian=12;

int spendlimit=160;

int blacktop;

int blacktop_count=0;

int vary_long_add=30;

int power;

uint8 debug_output=1;

int S_line_delay = 8;

int jizheng=14;

int rs=0;

int speed_now=0;

int speed = 130;

int steer=0;

int steer_old = 0;

int slope_count = 0;

unsigned char Pathtype;

int choose=0;

int accelpara=5;

struct solution

{

int CtrlWindow_set;

int speed_set_set;

int s_kd_set;

int s_kp_set;

};

int s_num = 0;

struct solution Solu[3] = {

{17, 200, 6, 12},

{18, 105, 0, 11},

{19, 110, 0, 11}

};

int gyroscope=0;

int screen[8];

void main_init(void);

void main(void)

{

int time20ms=0,time1s=0,timelimit=0; DisableInterrupts;

main_init(); //enable_pit_interrupt(PIT0); uart_send1(UART0,'a');

54

附录A:源程序

uart_send1(UART0,'e');

EnableInterrupts;

s_num = 0;

speed_set_set = Solu[s_num].speed_set_set;

s_kd_set = Solu[s_num].s_kd_set;

s_kp_set = Solu[s_num].s_kp_set;

CtrlWindow_set = Solu[s_num].CtrlWindow_set;

debug( "CtrlWindow", "s_kp_set", "djxs", "jizhi", "low_speed", "Bshgxs", "timelimit",

&CtrlWindow_set, &s_kp_set, &djxs, &jizhi, &low_speed, &Bshgxs, &timelimit );

delay_ms(1000);

while(1)

{

if(image_flash_flag) {

image_flash_flag=0;

switch(image_get_state)

{

case IMAGE_GET_WAIT:

field_delay();

break;

case IMAGE_GET_ING:

get_imageline();

break;

case IMAGE_GET_DONE:

{

gpio_ctrl(PORTC,13,1);

gyroscope=adc_mid(1,14,16)/250;

speed_now=FTM2_CNT*45/100;

FTM2_CNT=0;

init_get_blackline(left_blk_loc, right_blk_loc); get_blackline(image_data, left_blk_loc, right_blk_loc); if(road_state == Str || road_state == Ls )

get_startline(image_data,left_blk_loc,

right_blk_loc,&road_state,black_top);

bendplus=0;

if(start_count<150)

the_startline=0;

if((the_startline>8)&&(start_count>150)) //xubing--10 to 17 stop_signal=1;

if(stop_signal==1)

stop_delay=stop_delay+1;

motorservo_ctl(line_state);

time20ms++;

if(timelimit!=0)

{

if(time20ms>50)

{

time20ms=0;

time1s++;

}

if(time1s>=timelimit)

55

第八届飞思卡尔全国大学生智能车竞赛

{

motor_control(0,0);

f_close(&faddata); while(1){}

}

}

upload_info(left_blk_loc,right_blk_loc);

gpio_ctrl(PORTC,13,0);

image_get_state=IMAGE_GET_WAIT;

PORTE_ISFR=1<<25;

PORTA_ISFR=1<<17;

enable_irq(FIELD_ISR);

} //end case

}//end switch

}

}

}

void main_init(void)

{

light_init(Light_Run_PORT,Light_Run1,Light_OFF);

KBInit();

LCD_Init();

adc_init(0);

adc_init(1);

uart_init (UART0,periph_clk_khz,115200);

initial_image_isr();

ftm0_init();

ftm1_init();

quad_init(); }

void sd_init(void)

{

FRESULT res;

UINT br,bw;

disk_initialize(0);

uint8 sd_file_cnt=1;

uint8 tmp1,tmp0,i,j;

char namebuf[7];

f_mount(0,&fs);

res = f_open(&faddata,"img_reg.txt",FA_OPEN_EXISTING|FA_READ); {

for(i=ROW_MAX-1;i>0;i--)

{

for(j=0;j<LINE_MAX;j++)

{

f_read(&faddata,&img_reg[i][j].x,sizeof(uint16),&br);

56 if(!res)

附录A:源程序

f_read(&faddata,&img_reg[i][j].y,sizeof(uint16),&br);

}

}

}

res = f_close(&faddata);

res = f_open(&faddata,"000.txt",FA_OPEN_EXISTING|FA_READ|FA_WRITE); if(res)

{

res = f_open(&faddata,"000.txt",FA_CREATE_ALWAYS|FA_WRITE);//000文件不存在

res = f_write(&faddata,&sd_file_cnt,sizeof(uint8), &bw);

res = f_close(&faddata);

res = f_open(&faddata,"001.txt",FA_CREATE_ALWAYS|FA_WRITE); }

else

{

res = f_read(&faddata,&sd_file_cnt,sizeof(uint8),&br);

sd_file_cnt++;

res = f_lseek(&faddata,0);

res = f_write(&faddata,&sd_file_cnt,sizeof(uint8), &bw);

res = f_close(&faddata);

strcpy(namebuf,"000.txt");

tmp1=sd_file_cnt/100;

tmp0=sd_file_cnt%100;

namebuf[0]=(char)(tmp1+0x30);

tmp1=tmp0/10;

tmp0=tmp0%10;

namebuf[1]=(char)(tmp1+0x30);

namebuf[2]=(char)(tmp0+0x30);

res = f_open(&faddata,namebuf,FA_CREATE_ALWAYS|FA_WRITE); }

}

57

网站首页网站地图 站长统计
All rights reserved Powered by 海文库
copyright ©right 2010-2011。
文档资料库内容来自网络,如有侵犯请联系客服。zhit326@126.com