第八届“飞思卡尔”杯全国大学生
智能汽车竞赛
技 术 报 告
学 校: 中南大学
队伍名称: 比亚迪金牛座2013
参赛队员:
郭 慧
杨惠宇
魏 垚
带队教师:
王 击
安建奇
关于技术报告和研究论文使用授权的说明
本人完全了解第八届“飞思卡尔”杯全国大学生智能汽车竞赛有关保留、使用技术报告和研究论文的规定,即:参赛作品著作权归参赛者本人,比赛组委会和飞思卡尔半导体公司可以在相关主页上收录并公开参赛作品的设计方案、技术报告以及参赛模型车的视频、图像资料,并将相关内容编纂收录在组委会出版论文集中。
参赛队员签名:
带队教师签名:
日 期:
目录
第一章 引言................................................................................................................... 1
1.1 背景介绍........................................................................................................... 1
1.2 赛车整体设计思路............................................................................................ 1
1.3 文章结构........................................................................................................... 2
第二章 机械结构调整.................................................................................................... 3
2.1 整体思路........................................................................................................... 3
2.2 底盘调整........................................................................................................... 3
2.3 后轮定位调整................................................................................................... 3
2.3.1 主销后倾角............................................................................................. 4
2.3.2 主销内倾角............................................................................................. 4
2.3.3 车轮外倾角............................................................................................. 4
2.4 舵机安装........................................................................................................... 5
2.4.1 舵机延时分析......................................................................................... 5
2.4.2舵机的安装与控制延时解决办法............................................................ 7
2.5摄像头支架的设计安装..................................................................................... 9
2.6 电路板安装....................................................................................................... 9
第三章 硬件设计.......................................................................................................... 11
3.1 总体方案......................................................................................................... 11
3.2 电源模块......................................................................................................... 11
3.3 传感器模块..................................................................................................... 13
3.3.1 摄像头的选择....................................................................................... 13
3.2.2编码器测速模块..................................................................................... 13
3.4 主控模块......................................................................................................... 14
3.5 电机驱动模块................................................................................................. 14
第四章 软件设计.......................................................................................................... 16
4.1 黑线的提取和图像中心的计算....................................................................... 16
4.1.1原始图像的特点及校正......................................................................... 16
4.1.2黑线的提取和中心的计算...................................................................... 17
4.2方向控制方案.................................................................................................. 19
4.3 分类进行方向控制算法.................................................................................. 20
4.3.1 直道的方向控制算法............................................................................ 20
4.3.2 大弯的方向控制算法............................................................................ 20
4.3.3 急弯的方向控制算法............................................................................ 21
4.3.4 “大S型”道的方向控制算法.................................................................. 21
4.3.5 “小S型”道的方向控制算法.................................................................. 21
4.3.8 起跑线的方向控制算法........................................................................ 22
4.4速度控制方案.................................................................................................. 22
4.4.1 速度控制的重要性................................................................................ 22
4.4.2 速度控制的算法设计............................................................................ 23
4.5 棒-棒控制算法.............................................................................................. 25
4.5.1 棒-棒控制算法简介............................................................................ 25
4.5.2 棒-棒控制算法用于该赛车系统......................................................... 25
4.5.3 棒-棒控制与PID控制两种方法结合的必要性................................... 25
4.6 PID控制算法................................................................................................... 26
4.6.1 PID控制算法简介................................................................................. 26
4.6.2 数字PID控制算法................................................................................ 27
4.7 经典PID算法实现速度的控制....................................................................... 29
4.7.1 经典PID算法实现速度控制的计算机仿真.......................................... 29
4.7.2 经典PID算法实现速度控制的具体实现.............................................. 30
4.7.3 PID参数调节......................................................................................... 30
4.8 控制系统实时性能分析.................................................................................. 31
第五章 仿真与调试...................................................................................................... 32
5.1 调试阶段......................................................................................................... 32
5.1.1 摄像头调试........................................................................................... 32
5.1.2 软件系统调试....................................................................................... 32
第六章 赛车具体参数.................................................................................................. 34
第七章 总结与展望...................................................................................................... 35
7.1 总结................................................................................................................ 35
7.2 展望................................................................................................................ 36
致 谢............................................................................................................................ 37
参考文献....................................................................................................................... 38
程序附录....................................................................................................................... 39
第一章 引言
1.1 背景介绍
全国大学生智能汽车竞赛是在统一汽车模型平台上,使用飞思卡尔半导体公司的8位、16位、32位微控制器作为核心控制模块,通过增加传感器、电机驱动、编写相应软件以及装配模型车,制作一个能够自主识别道路的模型汽车,按照规定路线行进,以完成时间最短者为优胜。该竞赛是涵盖了控制、模式识别、传感技术、电子、电气、计算机、机械及车辆工程等多个学科的科技创意性比赛。
全国大学生智能汽车竞赛已经成功举办了七届,比赛规模不断扩大、比赛成绩不断提高。通过比赛促进了高等学校素质教育,培养大学生的综合知识运用能力、基本工程实践能力和创新意识,激发大学生从事科学研究与探索的兴趣和潜能,倡导理论联系实际、求真务实的学风和团队协作的人文精神,为优秀人才的脱颖而出创造条件。[1]
从20012年9月开始,我们就开始着手准备这项赛事。历时11个月时间,经历了机械构造、硬件方案、算法思路的不断创新,这些创新体现在设计理念上,也贯穿赛车制作过程的始终。由于这些创新,赛车各方面综合性能得到提升,并且获得了良好的赛场表现。本技术报告将详细介绍我们为第八届“飞思卡尔”杯全国大学生智能汽车竞赛而准备的智能车系统方案。
1.2 赛车整体设计思路
1.2.1 控制系统设计
智能车系统是一个相对复杂的反馈系统。CMOS摄像头采集的赛道图像信息、光电编码器采集到的车体运行速度是反馈控制系统的输入量。执行器(直流电机和伺服舵机)以及模型赛车构成反馈系统的装置。飞思卡尔K60系列的32位单片机是系统的控制器。在智能车系统的搭建到赛车快速、稳定地按照赛道行驶的整个过程中,反馈原理是我们分析问题和解决问题的基本原理。
1.2.2 赛车结构设计
关于赛车的整体结构布局(如图1.1所示),我们主要思路是:减轻车体重量,电路板模块化处理,尽量降低并合理调整车体重心。为此,我们将电路板体积做到了最小,在双面板情况下集成度做到了最高;选用轻质单板CMOS摄像头;选用轻质碳素合金支杆安装摄像头;尽可能的降低了摄像头高度;微控制板与大功率驱动板分开安装。
图1.1 智能车整体结构布局
1.3 文章结构
技术报告分七个章节:第一章节主要是对模型车设计制作的主要思路以及实现的技术方案概要说明,提出技术报告的行文框架。第二章介绍了赛车机械改造的总体思路,并详细说明了机械结构调整情况。第三章说明赛车系统的硬件设计实现。第四章说明方向控制和速度控制算法设计。第五章介绍仿真和调试的方法。第六章是赛车的具体参数。第七章总结了整个制作过程中的创新点和不足之处,提出了下届备赛过程的努力方向。
第二章 机械结构调整
2.1 整体思路
关于赛车机械结构的调整,我们主要从以下两个个方面考虑:
① 车体重量:比赛规则规定,智能车的驱动电机和传动机构不允许更改,意味着赛车的最大驱动力是一定的。要想提高赛车的平均速度,必须提高其加速和制动性能,在驱动力一定的情况下,尽量减轻车体的重量是必要的,我们将电路板体积做到了最小,在双面板情况下集成度做到了最高;
②重心安排:导引线弯道的最小半径为0.5米,要使得智能车能在弯道上高速通过,必须防止侧滑和侧翻,尤其是侧翻。重心位置是影响侧翻的最关键的因素,所以设计中应尽量降低智能车的重心。为此,传感器选用轻质CMOS摄像头;选用轻质碳素合金支杆安装摄像头;尽可能的降低了摄像头高度;微控制板与大功率驱动板放在了一起,以减小电路板体积,达到减轻重量的效果。
2.2 底盘调整
在独立悬架下摆臂与底板之间可以通过增减垫片来调整底盘离地间隙。垫片有1mm和2mm两种规格。一片垫片不加,车前部离地间隙为9mm,故离地间隙的调整范围为9~12mm。由于采用CMOS摄像头式布置结构,为保证车模高速行驶时的稳定性并降低重心,将底盘离地间隙设为最低9mm。
2.3 后轮定位调整
调试中发现,在赛车过弯时,转向舵机的负载会因为车轮转向角度的增大而增大。后轮定位可保证转向的稳定性,定位是由主销内倾、主销后倾、前轮外倾和前轮前束四个因素决定的。
2.3.1 主销后倾角
主销后倾角是指在纵向平面内主销轴线与地面垂直线之间的夹角。它在车辆转弯时会产生与车轮偏转方向相反的回正力矩,使车轮自动恢复到原来的中间位置上。所以,主销后倾角越大,车速越高,前轮自动回正的能力就越强,但是过大的回正力矩会使车辆转向沉重。通常主销后倾角值设定在1°到3°。
模型车通过增减黄色垫片的数量来改变主销后倾角的,由于竞赛所用的转向舵机力矩不大,过大的主销后倾角会使转向变得沉重,转弯反应迟滞,所以设置为0°,以便增加其转向的灵活性。
2.3.2 主销内倾角
主销内倾角是指在横向平面内主销轴线与地面垂直线之间的夹角,它的作用也是使前轮自动回正。角度越大前轮自动回正的作用就越强,但转向时也就越费力,轮胎磨损增大;反之,角度越小前轮自动回正的作用就越弱。通常汽车的主销内倾角不大于8°,主销内倾的调整应该保持在一个合适的范围,“一般来说0~8 度范围内皆可”。在实际的调整中,只要将角度调整为5 度左右就会对于过弯性能有明显的改善。如果赛道比较滑,可以将这个角度再调节的大一些。在实际制作中,这个角度调节为8 度左右。对于模型车,通过调整前桥的螺杆的长度可以改变主销内倾角的大小,由于过大的内倾角也会增大转向阻力,增加轮胎磨损,所以在调整时可以近似调整为0°~3°左右,不宜太大。
2.3.3 车轮外倾角
车轮外倾角是指通过车轮中心的汽车横向平面与车轮平面的交线与地面垂线之间的夹角,对汽车的转向性能有直接影响,它的作用是提高前轮的转向安全性和转向操纵的轻便性。在汽车的横向平面内,轮胎呈“八”字型时称为“负外倾”,而呈现“V”字形张开时称为正外倾。如果车轮垂直地面一旦满载就易产生变形,可能引
起车轮上部向内倾侧,导致车轮联接件损坏。所以事先将车轮校偏一个正外倾角度,一般这个角度约在1°左右,以减少承载轴承负荷,增加零件使用寿命,提高汽车的安全性能。
模型车提供了专门的外倾角调整配件,近似调节其外倾角。由于竞赛中模型主要用于竞速,所以要求尽量减轻重量,其底盘和前桥上承受的载荷不大,所以外倾角调整为0°即可。
2.4 舵机安装
2.4.1 舵机延时分析
舵机的响应时间对于控制非常重要,舵机能够及时响应微控制器发出的指令并产生相应的动作可以保障智能车在高速行驶过程中能够及时转弯,不脱离轨道。否则,即使控制算法再好,输出控制信号后,执行器(舵机)没有动作,则也达不到预期的控制效果。例如,微控制器已经根据赛道信息发出了转弯指令,但舵机响应控制信号延迟,则会出现已经到了弯道跟前,但是舵机却还没有转动的情况,智能车在惯性的作用下依旧向前冲,等舵机转动时小车车身已经偏离出轨道了。情况好的,在减速刹车后经过一段时间还能转回来,驶上正常的轨道;情况坏的则会冲出赛道,导致摄像头检测不到正确的赛道信息,不能够继续行驶。
在之前的比赛中,有很多队伍都提到了舵机的响应会滞后,但是没有分析原因,导致有些队伍无法对症下药,不得不以牺牲速度为代价,来换取智能车平安完成比赛。在此,我们对舵机延时的原因做一个比较详细的分析,以便做出相应的改进。
① 微控制器输出周期延时
前面已经提及,我们利用K60微控制器内部集成的PWM模块产生周期一定,占空比(及脉宽)可调的PWM波形。而控制PWM波周期和占空比是通过K60微控制器的一个16位的内部寄存器来实现的,它们是PWMPERx(PWM Period)和 PWMDTYx(PWM Duty),其中x代表0~7通道的序号。设定好这
两个寄存器的值后(具体的设置还与系统总线频率和其它寄存器的值相关),对应的通道就会一直输出一个固定频率的PWM波,直到改变这两个寄存器的值为止[5]。
当智能车检测到前方有弯道时,经过运算得出需要的占空比和所对应的寄存器的值,将这个值赋给PWMDTYx寄存器,随后输出PWM波的占空比就会发生相应的改变。但是,当在软件中改变了PWMDTYx寄存器中的值后,输出PWM波的占空比并不会立刻改变。PWMDTYx寄存器为双缓冲结构,由于K60微控制器内部硬件结构的原因,当在PWM信号输出过程中进行写操作时,写入的值将进入缓冲器,而不是直接进入该寄存器,直到通道被禁止或当前周期结束,计数器重新被写入(计数器回0)时才能进入该寄存器。这样设计的目的,虽然是为了避免输出变化着的不稳定的PWM波形,但是却产生了延时,如图2.1所示。
假设我们产生的PWM波的频率是300Hz,即周期为3.3ms。我们在软件中运算得出需要的占空比对应的PWMDTYx寄存器的值,并将其赋值给PWMDTYx寄存器,如果这一时刻在A点,即一个周期刚开始的时刻,那么我们运算得出的结果将要在缓冲器中保存3.3ms,在下一周期开始时才进入PWMDTYx寄存器,使占空比变成我们计算出的结果;如果那一时刻刚好在C点,即一个周期即将结束的时刻,那么我们运算的结果能够立刻进入PWMDTYx寄存器,使下一周期的占空比发生变化;而通常这一时刻则在B点,即3.3ms中的任意一点。因此,这就是第一次延时产生的原因所在。根据上面的叙述,当PWM波周期为3.3ms,产生的延迟时间为0~3.3ms。我们将这个延时叫做微控制器输出周期延时。
图2.1 PWM波占空比改变示意图
② 舵机机械延时
由于舵机内部具有小型直流电机、级联减速齿轮组、位置反馈电位器等机械装置,因此不可能瞬间达到我们所期望的输出角度,这就是影响舵机控制特性的一个主要参数即响应速度,也叫做舵机输出轴转动角速度,这个参数一般以舵机空载时输出转盘旋转60°所需要的时间表示。大赛指定使用的舵机工作电压范围为5V左右,在4.8V时,响应速度时0.20sec/60 degrees,在5.5V时,响应速度为0.16sec/60 degrees。而带了负载之后,响应速度还会略微下降。由此可知,舵机转动一定角度有时间延迟,时间延迟正比于旋转过的角度,反比于舵机的响应速度。例如,当舵机收到从0°转动到60°的信号时,要经过160ms才会达到我们预期的角度值。我们将这部分延时叫做舵机机械延时。
2.4.2舵机的安装与控制延时解决办法
因此,舵机的控制输出延时由微控制器输出周期延时和舵机机械延时两部分组成,由上分析可知,延时最大时会达到将近3.3ms+160ms=163.3ms。可以说,舵机的响应速度直接影响智能车通过弯道时的最高速度。因此提高舵机的响应速度是提高智能车平均速度的一个关键。根据以上的分析,提出以下几个解决办法:
1. 提高PWM波频率。指定舵机可接收的PWM信号频率范围为50 – 300Hz,对应的周期为20ms – 3.3ms,通过上述分析可知,频率越高,微控制器输出周期延时就越短,因此我们在设置K60微控制器PWM模块输出信号时选用300Hz的频率,可以有效减少延迟时间。
图2.2 舵机安装方式
2. 提高舵机工作电压。在上述分析中可以看出,工作电压越高,响应速度则越快,我们使用电池电压为7.2V,略高于舵机标定的工作电压范围,但是可以直接舵机供电。如此一来,舵机的响应速度还可以进一步提高,大约为0.1sec/60 degrees。
3. 安装更长的舵机输出臂。采用杠杆原理,在舵机的输出舵盘上安装一个较长的输出臂,将转向传动杆连接在输出臂末端。这样就可以在舵机输出较小的转角下,取得较大的前轮转角,从而提高了整个车模转向控制的速度。如图2.3所示,这种方法是通过机械方式,利用舵机的输出转距余量,将角度进行放大,加快了舵机响应速度[4]。
2.5摄像头支架的设计安装
赛车CMOS图像传感器的架设主要考虑以下几个因素:
1、确保CMOS图像传感器位置的居中且正对前方。因为当CMOS图像传感器不居中,其采集进来的图像也不是居中的,而处理程序对舵机输出量是居中的,这样就会导致智能车在直道上也偏离赛道中央,即使可以通过程序校正,也会导致扫描到的图像面积左右不对称,会浪费一部分图像信息。
2、CMOS图像传感器的安装高度要足够高。这样可以使得智能车在CMOS图像传感器的安装角度不是很大的情况下就能够前瞻到前方足够远处的路况信息。因为当摄像头的角度过大时候,采集进来的图像形变过大,且图像中的干扰信息增多,对模型车的处理算法十分的不利。而且当摄像头的安装位置较高时,所能扫描到的图像靠近智能车的部分范围较大,当智能车偏离赛道一定距离时,依然可以扫描到黑线,这样会便于图像的算法处理。一般要求该范围为45cm宽。
3、CMOS图像传感器的安装是可调整的。这样以便于CMOS图像传感器居中的校正,以及在实际调试中选择最佳探测角度,以及对CMOS图像传感器视野范围进行标定。经过多次的实验和总结,我们对CMOS图像传感器的远度进行了标定,对CMOS图像传感器的采集的图像信息进行了中心位置的校正。将CMOS图像传感器的视频信息通过视频采集卡传到计算机中,通过调节CMOS图像传感器各个旋转变量使得摄像头的图像位置居中。校正后的摄像头能够采集到小车前方上底为60cm,下底为240cm,高为220cm的近似等腰梯形图像。
经过上述设计,前轮的静态侧翻极限是55 度,后轮的侧翻极限是70度,而在赛道上侧滑极限一般不会超过50度,所以赛车在侧向加速度很大的极限情况下会先发生侧滑而不会发生侧翻。
2.6 电路板安装
电路板应安装于智能车的最低的部位,并且固定于底盘。由于电池的安装后移了6cm,考虑到赛车的空间,PCB板应设计成长方形以便于安装。PCB设计形状示意如图2.3 所示。这个形状有利于电路板的安装,同时防止了前轮转角过大时与电池接触。
图2.3 电路板的形状与安装
第三章 硬件设计
3.1 总体方案
系统硬件电路主要由一块PCB板构成,集成了整个系统的逻辑电路和驱动电路。主控制芯片采用官方推荐的32位微控制器MK60DN512,但速度很高且工作性能较稳定。主电机驱动电路采用BTN7971B搭建的H桥电路,该驱动电路导通内阻小,能承载的电流大,相比之下赛车可获得更大的加速度和直道上限速度。
3.2 电源模块
由于电源对高频干扰具有较强的抑制作用。同时由于其低功耗特点,在进行电路板设计时,可以减少散热片的体积和PCB 板的面积,有时甚至不需要加装散热片,方便了电路设计与使用,提高了稳定性能。
3.2.1 电机供电与单片机供电分离电路
主电机在启动的瞬间和反转的瞬间会产生高达20A的冲击电流。由于对赛车速度的控制采用的是bang-bang控制,因此在赛车的行驶的过程中始终存在较大的电流波动。而主电机和单片机都是由单独电池供电,若在主电机电源和单片机电源系统之间不加任何隔离措施,有可能导致在赛车行驶的过程中单片机复位,这是绝对不允许的。所以在主电机电源和单片机电源系统之间加了一极π型滤波器。电路图如图3.2所示。
图3.1 单片机电源和电机电源分离
3.2.2 单片机供电电路
单片机电源模块我们选用TPS76850QD和LT1117芯片,输入电压用电池电压通过TPS76850QD先稳到5V再通过LT1117稳压到3.3V,最后给单片机供电。
其典型应用电路图如图
图3.2 单片机电源电路
3.2.3 摄像头供电电路
CMOS的工作电压为5V,所以单独采用一块TPS76850QD给CMOS供电。
图3.3 CMOS电源电路
3.3 传感器模块
3.3.1 摄像头的选择
目前市面上常见的摄像头主要有CCD和CMOS两种:CCD摄像头具有对比度高、动态特性好的优点,但需要工作在12V电压下,对于整个系统来说过于耗电,且图像稳定性不高;CMOS摄像头体积小,耗电量小,图像稳定性较高。因此,经过实验论证之后我们决定采用CMOS摄像头。
对于CMOS摄像头分为数字和模拟两种。其中数字摄像头OV7620可以直接输出8路数字图像信号,使主板硬件电路的简化成为可能,且能够达到60帧/S的帧速率,只需要对其内部寄存器进行适当设置,因此,最终我们选择了CMOS数字图像传感器的方案。
3.2.2编码器测速模块
光电编码器是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器, 这也是目前应用最多的测速传感器之一。其获取信息准确、精度高、应用简单。
采用增量式1024线光电编码器,其供电电压为5V,输出为小幅值的正弦信号。为了将此信号放大整形,设计了信号调理电路,其基本原理是使用一个运放做成比较器电路,调节参考电压,使输出变为0/5V的方波信号,送入单片机进行运算。
3.4 主控模块
MCU最小系统包括滤波电路,晶振模块,主控芯片为MK60DN512ZLV10。
K60,32位微控制器系列针对一系列成本敏感型汽车车身电子应用进行了优化。K60产品满足了用户对设计灵活性和平台兼容性的需求,并在一系列汽车电子平台上实现了可升级性、硬件和软件可重用性、以及兼容性。
紧凑的封装使得这些器件适于空间受限应用,如小型执行器、传感器模块和转向柱集成模块。
3.5 电机驱动模块
驱动单元是控制系统的重要组成部分,驱动电路经过改进,最终选取BTN7971B作为驱动芯片,其电路结构简单,负载能力强,为赛车的加速和制动性能以及上限速度得到了很大程度的提高。电路如图3.4 所示。
图3.4 H桥控制电路
第四章 软件设计
系统硬件位于底层,是整个系统的基础,系统软件结构则根据硬件和控制需求来制定。系统的基本软件流程为:首先,对各功能模块和控制参数进行初始化。然后,通过图像采集模块获取前方赛道的图像数据,同时通过速度传感器模块获取赛车的速度。根据采集到的赛道信息,采用PD 对舵机进行反馈控制。另外根据检测到的速度,结合速度控制策略,对赛车速度不断进行适当调整,使赛车在符合比赛规则的前提下,沿赛道快速行驶。
4.1 黑线的提取和图像中心的计算
4.1.1原始图像的特点及校正
在单片机采集图像信号后需要对其进行处理以提取主要的赛道信息,同时,由于起点线的存在,光线、杂点、赛道连接处以及赛道外杂物的干扰,图像效果会大打折扣。因此,在软件上必须排除干扰因素,对赛道进行有效识别,并提供尽可能多的赛道信息供决策使用。
因为CMOS图像传感器所扫描到的图像是一幅发射式的图像,产生了严重的畸变,如果不进行校正,那么扫描到的数据的正确性将无法保证,那么对于道路形状的判定将会不准确,造成赛车判断失误,走的不是最优路径,严重时甚至冲出轨道。因此,在进行赛车方向控制时,进行坐标的校正显得至关重要。下面对坐标校正的方法进行具体的介绍。
由于CMOS图像传感器所扫描到的图像总是向外扩张,扫描到的图像并非为一个标准的长方形,在不考虑纵向畸变的情况下可以近似认为是一个梯形[7],严重影响到了数据采集的准确性,所以我们必须对扫描到的数据进行校正。我们根据实验发现,越是靠近CMOS图像传感器的地方,扫描到的范围就越窄,离CMOS图像传感器距离较远的地方,扫描到的范围就越宽,因此,在相同的情况下,如果CMOS图像传感器在最近处和最远处采集到黑线的数字信号距离中心位置均是30的话,事实上最远处偏离中心位置的距离可能比最近处偏离中心位置的距离大很多。按照赛车的安装方法,在扫描到的数字量相同的情况下,在第40行处偏离中心位置的距离超过了第0行偏离中心位置的4倍还要多,故必须进行校正,校正的方法就是在不同的行乘以一个不同的系数,系数大小的确定是先进行理论粗略的计算,然后再在事物上进行校正。
4.1.2黑线的提取和中心的计算
由于智能汽车大赛在第八届对规则进行了改变,其中最为明显的就是在小S弯处设置了长为一米的虚线,这就为我们黑线的提取增加了难度。另外由于十字交叉也存在黑线不连续的特点,我们在黑线提取的过程中引入一次线性预测、黑线校验和一次线性插值等方法,这样可以将黑线不连续的边界也连接起来。
黑线提取算法的基本思想如下:
Step1:首先确定图像二值化的灰度级阈值THRESHOLD;对于左边界,如果左边两列灰度值均小于阈值并且右边一列大于等于阈值,则判断为左边界;同理,对于右边界,如果右边两列小于阈值并且左边一列大于等于阈值,则判断为右边界;
Step2:从图像的第0行开始遍历,直到连续三行找到图像的左右边界,置标志变量beginFlag为1;否者如果遍历到图像HEIGHT-1行,表明提取失败,退出;
Step3:当找到该行的左右边界时,同时记录下前三行已找到的边界(可以不连续),如果前一行已找到的边界所在行与当前行不相邻,则利用一次线性插值补全未找到边界的行;否者,搜索下一行的左右边缘;
Step4:利用前三行已找的边界信息,进行一次线性拟合出直线方程,并利用该直线方程预测改行边界的位置col,根据经验左右设定一个余量e,在[col-e,col+e]范围内搜索该行的黑线边缘,当搜索到边缘后,进行边缘校验,滤掉明显不是边缘的噪点;
赛道中心线提取:
由于智能车大赛在第八届赛道中心的黑线调成了赛道两边,而智能车想要在赛道上平稳的行驶,不冲出赛道,必须知道赛道的中心,为此,我们利用提取的左右两边的黑线坐标对赛道的中心进行了计算,基本思想如下:
(1)当该行左右黑线均已提取到时,则将左右黑线位置的平均值作为中心线的位置;
(2)当只有单边黑线找到时,则根据找到的边界平移半个赛道宽度作为中心线的位置;
(3)当左(右)边界的结束行小于右(左)边界的开始行时,如果按照步骤(2)来计算赛道中心线的位置会出现中心线不连续的情况。为了解决该问题,我们利用前半部分连续的中心线一次线性预测下半部分第一行的中心线位置,则下半部分的中心线位置以该部分第一行的位置来计算。
图4.1 十字交叉
图4.2 小S虚线
4.2方向控制方案
图4.3 方向控制流程图
起跑线的判断:
全国大学生智能车竞赛规定,智能车必须能够识别起跑线,并在跑完一圈以后能够自动停止在3米以内的赛道中,否则在本来的时间基础上加上1秒,如果加上1秒那必须将速度加大很多才能挽回。然而,当速度本来就较快时,由于智能车本身的结构原因,很难再进行提速,因为速度过快可能会导致翻车等一系列不利现象。因此,对于起跑线的精准识别显得至关重要。观察图4.9可知,起跑线的颜色从左到右依次为“黑”→“白”→“黑”→“白”→“黑”→“白”→“黑”,对应于微控制器内的数字信号即是0→1→0→1→0→1→0,因此我们可以利用这个特征来识别起跑线。即当这部分图像中出现这样的颜色规律时就判定为是起跑线。当跑完第二圈,第三次检测到起跑线时,表明已经完成了比赛,要在冲过起跑线后刹车,在三米范围内停车。
4.3 分类进行方向控制算法
4.3.1 直道的方向控制算法
对于赛道中的直道,是方向控制中最好处理的一种情况,因为只要小车没有偏离赛道,就可以不进行偏转,而当智能车偏离赛道时也只需要一个较小的偏转,让智能车能缓慢回归赛道就可以了,具体的方法是计算扫描到黑线的偏离中心线的平均值和黑线的斜率,再将这两个数分别乘上各自的比例系数,加上舵机偏向中心位置时需要给出的高电平的值,作为PWM波的高电平送入给舵机,就可以实现直道上的智能车方向控制了。
4.3.2 大弯的方向控制算法
在道路中遇到大弯时需要转弯,转向角只受弯道的弯曲程度影响,但是距离大弯多远就开始转弯却需要受到当前速度的影响,因为舵机在转向时有一定的延时,舵机转60度大约需要110毫秒,而智能车的最快速度可以达到10米/秒,如果智能车当时运行的速度就是10米/秒,那么当舵机转过60度时智能车已经走过1米多了,所以不能等到了弯道才开始转弯,而是需要提前转弯,而且速度越快,越是要提前得多,所以智能车转弯提前多少就由速度控制,用比例控制就能收到很好的效果,而转弯时转多少却仅仅受弯道的弯曲程度控制,弯曲程度越大,转向角就也越大,弯曲程度越小,转向角也就越小。具体的对应关系通过实验获得,在此没有列举出具体的数据。
4.3.3 急弯的方向控制算法
急弯的方向控制算法与大弯的方向控制算法相似,也是需要提前转弯,而且提前多少转弯也要受当前速度的控制,速度越大,越要提前转弯,转向角也是用弯道的弯道程度来决定的,急弯比大弯的弯曲程度更加大,因此需要的转向角也要相应增大。急弯的方向控制比大弯更难,很可能出线,因此在急弯的方向控制时更应多加注意。
4.3.4 “大S型”道的方向控制算法
“大S型”道一般是指“S型”道最靠左的黑线和最靠右的黑线之间相差的距离大于60厘米,这是因为全国大学生智能车竞赛中的赛道为60厘米,冲出赛道就算违规,因此“大S型”道是不能直接冲的,但是我们可以转尽量小的弯来使智能车通过的路线为最短,而且转更小的弯也可以使得速度不至于减少太多,实现转尽量小弯的方法是扫描最左边和最右边的点,并得出这两个点中离智能车最近的点是左边还是右边的,如果这个点是最右边的,那么智能车的最佳行驶方向就为这个点靠左30厘米的方向,如果这个点是最左边的,那么智能车的最佳行驶方向就为这个点靠右30厘米的方向。利用这种算法可以实现智能车走最少的路程,转最小的弯。但是用这种算法智能车有可能偏离赛道的距离超过30厘米,为保险起见,这个阈值最好设低一点,根据赛车的运行情况来看,将阈值设为25厘米就比较保险了。
4.3.5 “小S型”道的方向控制算法
“小S型”道一般是指“S型”道最靠左的黑线和最靠右的黑线之间相差的距离不大于60厘米,智能车过这种弯道时,基本可以从中间直接通过,而不需要转弯和减速。因此,找准“小S型”道的正中心显得至关重要,因为只有找准了“小S型”道的正中心,智能车才能不转弯不减速地通过“小S型”道,如果“小S型”道的正中心找得不准,那么智能车就很容易冲出赛道。找“小S型”道的正中心的方法为:先找出“小S型”道最左边和最右边的坐标值,然后将最左边和最右边的坐标值相加之后再除以2,就得到了“小S型”道的正中心坐标,智能车就可以沿着这个方向前进,而不需要转弯。但是,由于CMOS图像传感器扫描到的图像可能出线误差,那么智能车就有可能产生误判,而冲出赛道。因此为了保险起见,必须当“小S型”道足够小时,才能采用直接冲的办法。通过本智能车的调试,建议当“S型”道最靠左的黑线和最靠右的黑线之间相差的距离不大于40到50厘米才能采用这种算法。
4.3.8 起跑线的方向控制算法
起跑线的作用是让智能车可以在跑完两圈以后自动停车,也即是第三次检测到时,当检测到的次数不足三次时,应该直接忽略,当检测次数到达三次时就应该直接停车,也不应该影响到智能车的方向控制。
4.4速度控制方案
4.4.1 速度控制的重要性
要想智能车以最短的时间跑完整个赛道,不但要求优越的方向控制算法,让智能车尽量走更近的路,转更少的弯。而且对于速度控制算法也有很高的要求,智能车在行驶过程中,不能够完全匀速,在直道上应该提速,而在弯道上应该减速。
在智能车沿着黑线行驶的过程中,速度不能够恒定不变,而应该根据道路的具体形状进行适当的调整。当然,最好的方法是让智能车始终以最快的速度通过整个赛道,但是如果速度始终调得太高,当小车遇到急弯或者是圆道时必然无法转过来,就会冲出赛道。因此不能够始终给最快的速度。然而,如果速度调得始终过低,就无法以最短的时间通过赛道。因此,速度应该要随着检测到的道路形状变化而变化。例如当前方道路为直道或类似直道时,应该将PWM波提得最高,让通过主电机的电流达到最大,从而让智能车以最快的速度行驶。当进入弯道时,应该将PWM波降到最低,让通过主电机的反向电流达到最大,从而让智能车以最短的时间将速度降到理想状态。
4.4.2 速度控制的算法设计
智能车速度控制的总体思路与智能车方向控制的思路完全相同,也是将道路的形状进行分类,对于不同的类给以不同的速度。而在某一时刻给出智能车的理想运行速度以后,采用棒-棒控制与PID控制相结合的算法实现对智能车的速度调节,以最短的时间使智能车达到这一理想速度。从而实现希望智能车的速度完全由道路情况所控制。
智能车速度控制的程序流程图如图4.6所示。
图4.6 智能车速度控制总体流程图
4.5 棒-棒控制算法
4.5.1 棒-棒控制算法简介
棒-棒控制的基本思路是当检测到的输出量大于理想输入量时,就急剧将控制量增加到最大,让输出量以最快的速度减少,当检测到的输出量小于理想的输入量时,就急剧将控制量降低到最小,让输出量以最快的速度减少。
4.5.2 棒-棒控制算法用于该赛车系统
本赛车系统的速度控制采用了棒-棒控制与PID控制相结合的方式。其基本思路为:智能车的理想速度由当前的道路信息决定。当光电编码器检测到的速度与理想速度相差较远时,采用棒-棒控制;当光电编码器检测到的速度与智能车的理想速度逐渐接近以后,就采用PID控制。对主电机的控制是通过一个H桥,将H桥的两个口分别接单片机的两个管脚,在本系统中,H桥的两端分别接单片机口中的PTP3和PTP1,当PTP1为高电平,PTP3为高电平时,主电机全速正转,当PTP1为低电平,PTP3为低电平时,主电机全速反转。采用棒-棒控制进行速度控制的原理就是检测智能车的当前速度,如果当前速度低于理想的速度,就PTP3置为高电平,从PTP1口输出一路占空比很高的PWM波,电机就能以最大的加速度升速。反之,就把PTP3置为高电平,从PTP1口输出一路占空比很大的PWM波,从而让电机以最大的加速度降速。
4.5.3 棒-棒控制与PID控制两种方法结合的必要性
棒-棒控制算法由于其快速性非常好,而本赛车系统的速度调节也正好要求很好的快速性,因而在本智能车的调速过程中用到了棒-棒控制算法也就理所当然,但是,棒-棒控制算法在用于本赛车调速时也存在着一定的不足,由于主电机的数学模型为一个惯性环节,存在着一定时间的延时,因此如果仅仅使用棒-棒控制一种算法可能导致超调,也不可能达到稳定,且在任何时刻通过主电机的电流都始终为最大,只是在不同的时刻可能会出现一正一反。正是出现一正一反的这种情况,对主电机以及主电机驱动电路的冲击最大,既造成整个智能车功耗的增加,又可能导致主电机及主电机驱动芯片因电流冲击过大而烧坏。因而在智能车的实际检测速度与理想速度接近时,可以采用PID控制算法,这样就既能实现调速的快速性,又能实现速度的平稳性,降低智能车的整体功耗,达到很好的调速效果。
4.6 PID控制算法
4.6.1 PID控制算法简介
PID控制是工程实际中应用最为广泛的调节器控制规律。问世至今70多年来,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。单位反馈的PID控制原理框图如图4.7所示。
图4.7 单位反馈的PID控制原理图
单位反馈e代表理想输入与实际输出的误差,这个误差信号被送到控制器,控制器算出误差信号的积分值和微分值,并将它们与原误差信号进行线性组合,得到输出量u。
(4.6)
对应的模拟PID调节器的传递函数为
(4.7)
其中,为比例增益,与比例带成倒数关系即,为积分时间常数,为微分时间常数,为控制量,为偏差。
4.6.2 数字PID控制算法
1. 数字PID位置型控制算法
在单片机控制系统中,PID控制规律的实现必须用数值逼近的方法。当采样周期相当短时,用求和代替积分,用后向差分代替微分,使模拟PID离散化变为差分方程。
为了便于单片机实现,必须把公式(4.6)变换成为差分方程,为此可作如下近似
(4.8)
(4.9)
式中,为采样周期,为采样序号。
由公式(4.6)、公式(4.7)、公式(4.8)可得数字PID位置型控制算式为
(4.10)
公式(4.10)表示的控制算法提供了执行机构的位置,所以被称为数字PID位置型控制算式。
2. 数字PID增量型控制算法
由公式(4.10)可以看出,位置型控制算法不够方便,这是因为要累加偏差,不仅要占用较多的存储单元,而且不便于编写程序,为此可对公式(4.5)进行改进。
根据公式(4.10)不难写出的表达式[8],即
(4.11)
将公式(5.10)和公式(5.11)相减,即得数字PID增量型控制算法为
(4.12)
其中称为比例增益
称为积分系数
称为微分系数
我们在实际代码实现时,处理成
error[0]=0;
error[1]=0;
error[2]=0;
PreU=0;
for(;;)
{error[0]=error[1];
error[1]=error[2];
error[2]=r-y;
PreU+=*(error[2]-error[1])+*error[2];
PreU+=*(error[2]-2*error[1]+error[0]);
……}
其中,error[2]为本次的偏差,error[1]为上一次的偏差,error[0]为上上次的偏差,PreU为输出的控制量。
这种算法用来控制步进电机特别方便,对直流电机也可以采用,其实如果对控制有更高的要求或者干扰因素较多,我们可以对PID算法做各种改进,比如用梯形法做数值积分以提高精度,将差分改成一阶数字滤波等等,在实际调车的过程中,我们确实遇到过由于光电编码器采样得到的脉冲上升下降沿不够陡,使得速度采样出现不稳定和失真,但由于这些附加处理比较耗费代码的运行时间,出于代码效率和实际效果的比较,我们没有采用这些改进的方案,另外可以考虑加反向器来整波形得到较为理想的方波。
运用PID控制的关键是调整三个比例系数,即参数整定。PID整定的方法有两大类:一是理论计算整定法。它主要是依据系统的数学模型,经过理论计算确定控制器参数。由于智能车整个系统是机电高耦合的分布参数系统,并且要考虑赛道具体环境,要建立精确的智能车运动控制数学模型有一定难度,而且我们对车身机械结构经常进行不断修正,模型参数变化较频繁,可操作性不强;二是工程整定方法,它主要依赖工程经验,直接在控制系统的试验中进行,且方法简单,我们采用了这种方法,同时,我们先后实验了几种动态改变PID参数的控制方法[8]。
4.7 经典PID算法实现速度的控制
4.7.1 经典PID算法实现速度控制的计算机仿真
智能车的主电机可以看着是一个惰性单元,应用PID控制算法可以达到较好的控制效果,该智能车在MATLAB上进行仿真得到的单位价跃响应如图4.12所示,因为在本赛车速度控制系统中,其中一个最重要的指标就是快速性,而对于超调量和过渡过程时间要求并不严格。特别是过渡过程时间,该智能车的速度时时刻刻都需要发生变化,所以还等不到速度稳定便又要变化,由仿真结果可见,该智能车速度调节的快速性很好,能够完全满足调速的要求。
图4.8 PID速度控制算法的MATLAB仿真
4.7.2 经典PID算法实现速度控制的具体实现
我们对速度的控制采用了增量式PID算法。该算法的基本策略是急弯降速,直道和小弯提速,由于我们的摄像头扫描到的范围较宽,所以在过急弯道时可以提前减速,先把扫描到的图像进行处理,然后得出经过反复实验,将图像经过算法处理后得到的黑线位置和对应的速度PID参照速度处理成二次曲线的关系。在实际测试中,发现小车直道和弯道相互过度时加减速比较灵敏,与舵机转向控制配合较好。
但是,存在的局限一方面是车在弯道进直道后的加速和直道入弯道的速度控制并达不到最好的控制效果,弯道入直道减速不够快速,直道入弯道加速得时机也不够及时。我们做了进一步的改进,根据入弯时黑线位置的特点动态改变二次曲线中最高点(直道的最高速度)和最低点(弯道的最低速度)的大小,使得控制效果更合理。
另一方面是没有考虑到实际比赛中长直道急速冲刺的情况,赛前在程序中人为设定直线速度不够灵活合理,所以在程序中根据赛道状态动态提高直线速度,使得我们可以在长直道的赛场充分发挥车的潜能。
4.7.3 PID参数调节
比例控制能迅速反应误差,从而减少误差,但是比例控制不能消除静态误差,的加大,会引起系统的不稳定;积分控制的作用是,只要系统存在误差,积分控制作用就不断地积累,输出控制量以消除误差,因而,只要有足够的时间,积分控制将能完全消除误差,积分作用太强会使系统超调加大,甚至使系统出现振荡现象;微分控制可以减小超调量,克服振荡,使系统的稳定性提高,同时加快系统的动态响应速度,减少调整时间,从而改善系统的动态性能。而在该智能车系统调速的过程中,由于快速性是最重要的指标之一,因而应主要考虑其快速性,在调试的过程中,把参数调得较大,这是为了增大速度调节的快速性,将参数调得较为适中,因为除了快速性以外,最重要的就是要减少系统的超调量,而将参数调得较小,因为在该速度调节中,并不需要达到静态,由于理想速度就在时时刻刻发生变化,所以也不可能达到静态。实验结果表明,参数取8,参数取为2,而参数取得尽可能小,大约为1时,可以取得较好的效果。
4.8 控制系统实时性能分析
智能车系统的控制周期为20ms,也就是每一场对车的转向和速度进行控制。新一场信号采集的同时,单片机既要相应行中断采集当前场的数据,又要在相应中断剩下的时间分析出上一场数据,集合相应的算法进行控制量的输出。在这20ms中单片机能否完成上面所说的任务是需要通过分析所得的。如果单片机不能在20ms内完成上述的任务,系统控制性能就会下降,甚至出现错误。如果可以在低于20ms的时间内完成任务,那么系统就能够按照一定的时序有条不紊的运行。引入多任务下单片机负载的概念[9]:
(4.13 )
下面是各个任务执行时间:
数据的计算 4ms-6ms 、摄像头数据采集 6ms– 8ms、速度采集1us、速度控制1us、舵机控制 1us。可以计算出系统的负载L大约为0.7,能够满足系统稳定性的要求。
第五章 仿真与调试
要想将所设计的算法运用到智能小车上,并很好的控制智能小车的各个机构协调工作,并不是一蹴而就的事情,必须经过初期的设计、仿真、制作和长期的调试工作。而这一系列工作也是反复循环进行的,在调试过程中对设计方案进行修改,然后重新仿真制作后再进行新一轮的调试。
5.1 调试阶段
5.1.1 摄像头调试
CCD/CMOS摄像头是智能小车最重要的传感器,知道安装在智能小车上的摄像头看到的路面图像是什么样的,这一点在调试过程中是很重要的。由于我们所使用的摄像头输出的是PAL制式的图像,和我国电视机采用的制式是一样的,因此,我们利用视频采集卡将摄像头的视频图像转接到电脑上,并用视频采集卡配套的软件对图像进行观察、截图等操作。通过视频采集卡,我们就可以知道智能小车看到的路面信息是什么样的,这就给我们的调试工作带来的很大的方便。
5.1.2 软件系统调试
本文之前已经详细的讨论了智能小车的硬件结构和图像处理算法、控制算法等,但是这些算法都需要用软件即使用程序语言来实现。我们使用IAR Systems以及硬件在线仿真调试工具——BDM来开发智能小车的软件系统。IAR Systems 是全球领先的嵌入式系统开发工具和服务的供应商。IAR Systems提供的产品和服务涉及到嵌入式系统的设计、开发和测试的每一个阶段,包括:带有C/C++编译器和调试器的集成开发环境(IDE)、实时操作系统和中间件、开发套件、硬件仿真器以及状态机建模工具。如图5.3所示,图中是IAR Systems集成开发环境(IDE)。
图5.3 IAR Systems集成开发环境和调试器(Debugger)
IAR Systems调试器(Debugger)通过BDM连接到我们设计的智能小车控制电路板上,这样我们就可以在线实时读到K60微控制器中寄存器的状态、变量的值等,大大方便了我们的调试工作,如图5.4所示。
图5.4 软件系统的调试
第六章 赛车具体参数
第七章 总结与展望
7.1 总结
要实现对高速行驶汽车的自主智能控制并不是一个简单的自动控制问题,它涵盖了控制、模式识别、力学、光学、电磁学、传感技术、电子、电气、计算机、机械及车辆工程等多个学科。本文采用的控制核心是一款飞思卡尔半导体公司生产的32位微控制器——MK60DN512,利用了微控制器的强大功能实现了智能小车对路径的自主寻迹,以及在未知环境下,结合一定的算法,实现了对智能小车的高速导航控制,从最终测试结果来看,本系统具有较好的控制性能与对未知环境的适应能力。
对智能小车系统的自主控制,可以分为三大部分:首先是对路径信息的提取与识别,即智能小车的寻迹;然后是对前轮舵机方向的控制,即智能小车的导航控制;最后是对后轮车速的控制,即智能小车的驱动控制。
智能小车的导航控制,主要就是对智能小车的舵机系统进行控制,但是,后轮舵机系统作为一个机械执行机构,舵机系统中存在着饱和、摩擦和间隙等非线性因素,再加上K60微控制器自身产生PWM波形机制的问题,使舵机系统具有机械延时和输出周期延时两部分,造成了比较大的延时。本文在详细论述了延时原因的基础上,提出了几点解决办法,分别从软件和硬件两方面下手,减少了舵机的延时,使对舵机控制的实时性更好。智能小车的舵机转向控制是一个复杂的随动控制问题,很难求得其准确的模型,此时PID 的控制效果将难于达到预期的目标。因此我们根据人驾驶车辆的经验,采用了分类控制算法。
在搭建好智能小车的软硬件平台后,我们进行了一系列的仿真和调试,实验证明,我们的寻迹方案与导航控制策略是稳定、有效的。完成了对智能小车的自动控制,并在制作的赛道上实现了智能小车的高速、自主行驶。在调试过程中,我们也发现了一些问题,由于对汽车工程理论与机械结构设计的不熟悉,使我们对智能小车结构的改造和对摄像头安装支架的设计存在着缺陷和不足,这就约束了智能小车的提速,例如,摄像头支架过重使智能小车重心偏高,导致在高速行驶转弯时会发生翻车的情况。此外,我们对图像信息的处理算法和导航控制算法也有改进和提升的空间,例如,可以尝试在导航控制中使用专家系统等先进的算法。这些都是我们今后努力的目标。
7.2 展望
智能车系统的研究十分复杂,需要解决的问题很多,任务非常艰巨,不是一蹴而就的,必须经过长期的理论研究和实践探索才能够取得突破和进展。展望未来,对于我们所研究的这类智能小车,我们认为今后还可在以下几个方面做进一步的研究和提升。
1)、采用优质的数字摄像头,数字摄像头可以非常方便的调整其参数,对环境适应能力更强。
2)、在舵机控制策略上,可以考虑使用更先进的控制算法。
3)、在图像处理方面,可以研究更先进的算法,不过,这需要配合微控制器性能的提升,可以考虑使用DSP、ARM等更先进的处理器。
4)、硬件传感器方面。可以尝试采用CMOS摄像头随动方案。
5)、小车机械性能方面。需要学习一些汽车工程方面的知识,以便对智能小车的车体改造有理论指导和依据。此外可以再考虑外增加制动装置在入弯时进行减速。这样直道速度可以提高,平均速度更快。但如何选择合适的制动装置并对其进行控制,还需要进一步深入探讨。
致 谢
今年能够参加第八届飞思卡尔杯全国大学生智能汽车赛我们首先要感谢信息科学与工程学院王击老师的悉心指导,指导老师多次询问研究进程并为我们指点迷津。其严谨的治学态度以及对我们的关怀使们获益甚多,感动颇深。
在准备比赛期间我们得到了参加过第七届比赛的学长的许多非常实用的帮助和建议,在这里要特别感谢他们。另外也感谢一起准备比赛的队员,没有他们的帮助我们不可能完成工作。
另外我们还要感谢德州仪器公司以及飞思卡尔公司为我们提供的芯片支持,没有一个大范围的比较是不可能选出最优最合适元器件出来的,我们的小车能够顺利的参赛要感谢这两大公司的帮助。
参考文献
[1] 教育部高等学校自动化专业教学指导分委员会. 关于举办第三届全国大学生“飞思卡尔”杯智能汽车竞赛的通知[EB/OL]. 20##-11-01.
[2] 邵贝贝. 单片机嵌入式应用的在线开发方法. 北京:清华大学出版社. 20##年10 月第1 版.
[3] 方兴,郭思明,马明煌. 上海交通大学速度之星队技术报告.
[4] 卓晴,黄开胜,邵贝贝.学做智能车[M].北京:北京航空航天大学出版社,2007.24~27.
[5] Freescale Semiconductor Inc. S12PWM8B8CV1/D Block User Guide V01.17[Z]. 2004. 1~51. [6] National Semiconductor. LM1881 Video Sync Separator General Description[Z]. June 2003
[7] 杨明,宋雪峰,王宏,张钹.面向智能交通系统的图像处理[J].计算机工程与应用.20##年09期.
[8] 余灿键,程东成,李伟强.PID算法在智能汽车设计上的应用.——《学做智能车——挑战“飞思卡尔”杯》[C].北京:北京航空航天大学出版社,2007.133~135.
程序附录
#include "includes.h"
extern int periph_clk_khz;
//----------宏定义-----------//
// 图像处理
#define HEIGHT 65//61
#define WIDTH 200
#define AD 30 // 灰度阈值
#define CENTER 95 //95
// 电机控制
#define SpeedPWMMax 800
#define MaxMoto 80 // 电机PWM周期
#define PBangBang 30 // 棒棒阈值
#define NBangBang 50
//sd卡速度记录
int sdimage=0;
int sdaddr=100;
unsigned char sp[512];
int sps=0;
int16 COUNT = 0;
// 舵机控制
#define DuoMiddle 1290 // 0 1290
#define DuoLeftMax 1045 //1050 //250 1018
#define DuoRightMax 1535 //1530 //-270 1562
uint8 a,b,c,d;
//----------全局变量定义-----------//
// 图像处理
uint8 THRESHHOLD = 100; // 二值化阈值
uint8 Buffer[HEIGHT+1][WIDTH] = {{0}};
int16 leftBoundary[HEIGHT] = {0}; // 图像的左边界
int16 rightBoundary[HEIGHT] = {0}; //图像的右边界
int16 midLine[HEIGHT] = {0}; //中心线
uint8 midBeginRow = 0;
uint8 midEndRow = 0;
int16 midEndCol =0; // 加入了赛道平移,可能出现负数
uint8 leftBeginRowFlag = 0; // 寻到左边界起始行标志
uint8 rightBeginRowFlag = 0; // 寻到右边界起始行标志
uint8 leftBeginRow = 0; // 寻到左边界的起始行
uint8 leftEndRow = 0; // 寻到左边界的结束行
uint8 rightBeginRow = 0; // 寻到右边界的起始行
uint8 rightEndRow = 0; // 寻到右边界的结束行
uint8 leftEndRowFlag = 0; // 寻到左边界结束行标志
uint8 rightEndRowFlag = 0; // 寻到右边界结束行标志
int16 lastLeftBoundary[3] = {0};
int16 lastRightBoundary[3] = {0};
int16 lastLeftRow[3] = {0};
int16 lastRightRow[3] = {0};
uint8 leftValidity = 0, rightValidity = 0;
uint8 imgValidity = 0; //图像有效性
int16 roadType; // 赛道类型
int16 yinDaoRowLen;
int16 leftMaxBoundary,leftMaxRow,rightMinBoundary,rightMinRow;
int16 leftRowLen,rightRowLen;
float midSlope; // 最后一行中心线相对与图像第一行中点的斜率倒数
int16 midColLength;
int16 avmidEndRow;
int16 lastMidColLen[3];
float slopeBoundary = 0;
uint8 handRangeHalf = 5;
int16 ImageCnt = 0;
int16 avmidLine = 0; // 有效行中心线平均值
int16 avmidLine40 = 0;
int16 avmidRow40 = 0;
float alf[HEIGHT] =
{
0.987753, 1.0, 1.01255, 1.02543, 1.03863, 1.05218, 1.06609, 1.08037, 1.09504, 1.11011, 1.1256,
1.14154, 1.15792, 1.17479, 1.19216, 1.21004, 1.22847, 1.24747, 1.26707, 1.28729, 1.30817, 1.32974,
1.35203, 1.37508, 1.39893, 1.42363, 1.44921, 1.47572, 1.50323, 1.53178, 1.56143, 1.59226, 1.62433,
1.65771, 1.6925, 1.72878, 1.76664, 1.80621, 1.84758, 1.8909, 1.9363, 1.98392, 2.03396, 2.08658, 2.14199,
2.20043, 2.26215, 2.32743, 2.39659, 2.46998, 2.54801, 2.63113, 2.71986, 2.81479, 2.91657, 3.026, 3.14396,
3.27148, 3.40979, 3.56031, 3.72473, 3.90507, 4.10377, 4.32377, 4.56869
};
unsigned char roadHalfWidth[HEIGHT] =
{
107,105,104,103,102,100,99,98,96,95,
94,92,91,90,88,87,86,85,83,82,81,79,
78,77,75,74,73,71,70,69,68,66,65,64,
62,61,60,58,57,56,54,53,52,51,49,48,47,
45,44,43,41,40,39,37,36,35,34,32,31,30,
28,27,26,24,23
};
//-----垂直距离-----//
float verDist[HEIGHT] =
{
-1.90864, -0.625085, 0.634093, 1.87006, 3.08411, 4.2777, 5.45241, 6.60997, 7.75227, 8.88131,
9.99927, 11.1084, 12.2113, 13.3104, 14.4085, 15.5085, 16.6133, 17.7263, 18.8506, 19.9897,
21.1473, 22.327, 23.5328, 24.7686, 26.0387, 27.3473, 28.699, 30.0983, 31.5499, 33.0588,
34.6299, 36.2685, 37.9799, 39.7695, 41.6429, 43.606, 45.6644, 47.8244, 50.0921, 52.4738,
54.9759, 57.6051, 60.3682, 63.272, 66.3235, 69.53, 72.8987, 76.4372, 80.153, 84.0539,
88.1479, 92.4429, 96.9471, 101.669, 106.617, 111.799, 117.225, 122.903, 128.843, 135.053,
141.543, 148.322, 155.4, 162.787, 170.493
};
uint16 SampleRow[HEIGHT] =
{
7,// 增加一行
45,47,49,
51,53,55,57,59,
61,63,65,67,69,
71,73,75,77,79,
81,83,85,87,89,
91,93,95,97,99,
101,103,105,107,109,
111,113,115,117,119,
121,123,125,127,129,
131,133,135,137,139,
141,143,145,147,149,
151,153,155,157,159,
161,163,165,167,169,
171
};
// 电机控制
int16 ek[3]= {0,0,0}; //本意为采样误差,此处定为历史编码器采样值
//-----1号车模参数-----//
float Kp = 1.3; // 2.535 1.5 空转临界稳定 Kp=(0.6--0.7)*3.9
float Ki = 0.8; // 0.8
float Kd = 0.2; // 微分系数影响不是很明显
//-----end1号车模参数-----//
//-----2号车模参数-----//
//float Kp = 0.3; // 0.3
//float Ki = 0.35; // 0.28 0.4 0.35
//float Kd = 0.03; //0.03 0.1微分系数影响不是很明显
//-----end2号车模参数-----//
int16 u = 0,lastU = 0; //记录输出量即速度输出值
int16 PulseCnt=0;
int16 setPulse = 0,setPulseMax = 0;
uint16 realSpeed = 0;
int16 SpeedChoose=0;
uint8 startLineFlag = 0; // 起跑线标志
uint8 startkey = 0; //起跑线开关
uint8 breakFlag = 0;
uint8 breakCount = 0;
// 舵机控制
int16 bias = 0;
float slope = 0;
float kBias = 1.1752, kSlope = 1.9; // 彎道參數
float kSlope1 = 2.0; // 直道/小S參數
float kBias1 = 0; //
int16 selectedRow = 40;
int16 duoE = 0;
int16 lastDuoPWM[2] = {0,0};// 历史舵机值
float duoKd = 2.0; // 舵机PD控制的微分系数
int16 staticDuoMiddle = DuoLeftMax;
// 其他
uint16 ActualRow=0;
uint16 DataRow=0;
uint8 ImageFlag=0;
uint8 Outwarn=0; //图像出界失效标志位
int16 t=0; // 拨码开关用
//uint16 Ay,Az;
int16 tempValue; // 写SD卡用
unsigned char floatString[8];
unsigned char intString[7];
char count[5];
void main(void)
{
// uint8 a,b,c,d;
uint8 m;
// uint8 *p;
// int sdimage=0;
// int sdaddr=100; //SD 卡
// char sccben=0;
//unsigned long int runcount;
//unsigned char lastPB21 = 1, lastPB22 = 1, lastPB22 = 1;
unsigned char i,j;
// int t = 0;
//float dKp=0;
DisableInterrupts;
pllinit125M();
IO_Init();
LCD_init();
BL1;
// sccb_init();
// sccb_stop();
// sccben=write_i2c(13,12293);
// sccb_regWrite(0x42,0x11,0x03); //地址0X11-中断四分频(1280*480) PCLK:166ns HREF:254.6us VSYN:133.6ms
// sccb_regWrite(0x42,0x14,0x24); //地址0X14-QVGA(640*240) PCLK:332ns HREF:509.6us VSYN:133.6ms
// sccb_regWrite(0x42,0x28,0x60); //地址0X28-黑白模式(320*240) PCLK:666ns HREF:509.6us VSYN:133.6ms
// sccb_wait();
if((GPIOB_PDIR&(1<<16))==0)
sden=1;
if((GPIOB_PDIR&(1<<18))==0)
uarten=1;
if((GPIOB_PDIR&(1<<19))==0)
startkey = 1;
if((GPIOB_PDIR&(1<<23))==0)
a=2;
else
a=0;
if((GPIOB_PDIR&(1<<22))==0)
b=1;
else
b=0;
if((GPIOB_PDIR&(1<<21))==0)
c=2;
else
c=0;
if((GPIOB_PDIR&(1<<20))==0)
d=1;
else
d=0;
//***********SD卡初始化*****************
if(sden)
{
m=SD_Init();
if(m==0) LCD_write_english_string(70,4,"s ");
else if(m==1) LCD_write_english_string(70,4,"o ");
else LCD_write_english_string(70,4,"l ");
m=LPLD_SPI_Init(SPI0 ,SPI_SCK_DIV_16,1);
LCD_write_english_string(75,4,"i ");
}
hw_FTM1_init();
// SPEED(0,30);
//-----延时2s-----//
Delays(2);
light_control(PORTD,13,1);
light_control(PORTD,14,1);
light_control(PORTD,15,1);
// LPLD_ADC_Init(ADC1, MODE_10, CONV_SING);
lptmr_pulse_counter_init();
hw_pit_init(0,10*periph_clk_khz); // 编码器定时10ms time
//light_init(Light_Run_PORT,Light_Run2,Light_OFF); //指示灯初始化
//light_init(Light_Run_PORT,Light_Run1,Light_OFF);
//light_init(Light_Run_PORT,17,Light_OFF);
if(uarten)
uart_init (UART3,periph_clk_khz,28800);
EnableInterrupts;//4 开中断
enable_irq(87);
for(i=0; i<HEIGHT; i++)
{
for(j=0; j<WIDTH ; j++)
{
Buffer[i][j]=0;
}
}
enable_irq(68);
COUNT = 0;
for(;;)
{
if(ImageFlag==1)
{
disable_irq(87);
light_change(PORTD,12);
ImageDeal(); // 图像处理
//*****发送原始图像*****//
//14khz 60hz
if(uarten)
{
uart_send1(UART3,0xFF);
for(i=0; i<HEIGHT; i++)
{
for(j=0; j<WIDTH ; j++)
{
if(Buffer[i][j] == 0x00)
uart_send1(UART3,0x01);
else if(Buffer[i][j] == 0xff)
uart_send1(UART3,0xFE);
else
{
uart_send1(UART3,Buffer[i][j]);
}
}
}
uart_send1(UART3,0xFF);
}
speedset();
DuoControl();
// 发送到上位机示波器显示
// uart_send1(UART3,0xFF);
// uart_send1(UART3,0xFF);
// uart_send1(UART3,PulseCnt);
// uart_send1(UART3,0x00);
// uart_send1(UART3,0x00);
// uart_send1(UART3,0x00);
// uart_send1(UART3,0x00);
//*********加速度值液晶显示***************//
/*
// X轴
Adc1_Result = LPLD_ADC_SE_Get(ADC1, 10);
LCD_write_english_string(5,3,"X:");
int2string(Adc1_Result);
LCD_write_english_string(15,3,intString);
// Y轴
Adc1_Result = LPLD_ADC_SE_Get(ADC1, 11);
LCD_write_english_string(5,4,"Y:");
int2string(Adc1_Result);
LCD_write_english_string(15,4,intString);
// Z轴
Adc1_Result = LPLD_ADC_SE_Get(ADC1, 12);
LCD_write_english_string(5,5,"Z:");
int2string(Adc1_Result);
LCD_write_english_string(15,5,intString);
*/
//**********end*************************//
// Ay=LPLD_ADC_SE_Get(ADC1, 11);
// Az=LPLD_ADC_SE_Get(ADC1, 12);
//***********sd卡存数据**********
//*****从第1000个扇区开始****//
// if(sden)
// {
// if(sdimage<1001)
// {
// unsigned char speed[2] = {0,0};
// unsigned char* pp = speed;
// if(FTM1_C1V==0)
// tempValue = FTM1_C0V;
// else
// tempValue = FTM1_C1V;
// speed[0] = (unsigned char)(tempValue/256);
// speed[1] = (unsigned char)(tempValue%256);
// m=SD_WriteMultiBlock(sdaddr,pp,31);
// sdaddr+=31;
//// p=&Buffer[0][0];
//// tempValue = FTM2_C0V;
//// Buffer[HEIGHT][0]=(unsigned char)(tempValue/256); //舵机值商
//// Buffer[HEIGHT][1]=(unsigned char)(tempValue%256); //舵机值余数
//// Buffer[HEIGHT][2]=(unsigned char)(setPulse/256); //给定速度商
//// Buffer[HEIGHT][3]=(unsigned char)(setPulse%256); //给定速度余数
//// Buffer[HEIGHT][4]=(unsigned char)(PulseCnt/256); //实际速度商
//// Buffer[HEIGHT][5]=(unsigned char)(PulseCnt%256); //实际速度余数
//// Buffer[HEIGHT][6]=(unsigned char)(0); //加速度y商
//// Buffer[HEIGHT][7]=(unsigned char)(0); //加速度y余数
//// Buffer[HEIGHT][8]=(unsigned char)(0); //加速度z商
//// Buffer[HEIGHT][9]=(unsigned char)(0); //加速度z余数
//// tempValue = FTM1_C0V;
//// Buffer[HEIGHT][10]=(unsigned char)(tempValue/256); //电机商
//// Buffer[HEIGHT][11]=(unsigned char)(tempValue%256); //电机余数
//// Buffer[HEIGHT][12] = (unsigned char)(selectedRow); // 选择的行
//// tempValue = FTM1_C1V;
//// Buffer[HEIGHT][13]=(unsigned char)(tempValue/256); //电机商
//// Buffer[HEIGHT][14]=(unsigned char)(tempValue%256); //电机余数
//
//// m=SD_WriteMultiBlock(sdaddr,p,31);
//// sdaddr+=31;
//// if(m==0) LCD_write_english_string(70,5,"w ");
//// else LCD_write_english_string(70,5,"f ");
// sdimage++;
// }
// }
//***********end of sd save******
ImageFlag=0;
PORTA_ISFR=1<<13;
enable_irq(87);
}
}
}