浙江赛区-光电组-杭州电子科技大学-杭电光电3队,杭电电子科技大学,电子科技大学光电学院,电子科技大学光电信息

发布时间:2012-11-16 来源: 浙江杭州电子科技大学

杭电光电三队 预赛小组第2 决赛一等奖 光电组 B67 杭州电子科技大学信息工程学院 杭电... 回复??龚能能:我们学校这个比较厉害,别的马马虎虎.不过我们好像是华东赛区 ??...

第九届“飞思卡尔”杯全国大学生智 能汽车竞赛 技术报告 学 校:杭州电子科技大学 队伍名称:杭电光电3队 参赛队员:刘 勇 常玉锋 叶建明 带队教师:刘国华 黄继业 日期:

2014年8月11日 目录 第九届“飞思卡尔”杯全国大学生智能汽车竞赛 ..................................................................... 2 摘要 ........................................................................................................................................ 5 第一章引言 ............................................................................................................................ 6 1.1 概述 ......................................................................................................................... 6 1.2 整车设计 ................................................................................................................. 7 1.3 小结 ......................................................................................................................... 9 第二章机械设计与修改 ...................................................................................................... 10 2.1 前轮定位 ............................................................................................................... 10 2.2 底盘高度 ............................................................................................................... 13 2.3 主动悬挂 ............................................................................................................... 13 2.4 传感器支架 ........................................................................................................... 14 2.5 舵机的安装 ........................................................................................................... 15 2.6 差速调整 ............................................................................................................... 16 第三章硬件设计 .................................................................................................................. 17 3.1 硬件电路整体架构设计 ....................................................................................... 17 3.2 单片机最小系统板电路设计 ............................................................................... 18 3.3 传感器设计 ........................................................................................................... 18 3.4 起跑线检测电路 ................................................................................................... 18 3.5 电机驱动电路设计 ............................................................................................... 19 3.6 舵机驱动电路设计 ............................................................................................... 20 3.7 液晶按键电路设计 ............................................................................................... 21 3.8 系统电源电路设计 ............................................................................................... 22 3.9 系统主板电路设计 ............................................................................................... 22 3.10 电源电路设计 ..................................................................................................... 23 3.11 小结 ..................................................................................................................... 23 第四章软件系统设计 .......................................................................................................... 24 4.1 软件控制的总体思路 ........................................................................................... 24 4.2 主程序结构 ........................................................................................................... 24 4.3 程序的运行 ........................................................................................................... 25 4.4 路径识别子程序设计 ........................................................................................... 26 4.5 摇头舵机控制子程序设计 .................................................................................... 26 4.6 转向舵机控制子程序设计 ................................................................................... 27 4.7 悬挂舵机控制子程序设计 .................................................................................... 28 4.8 速度控制子程序设计 .......................................................................................... 29 4.9 小结 ....................................................................................................................... 34 第五章开发、调试过程说明 .............................................................................................. 35 5.1 开发工具 ............................................................................................................... 35 5.2 调试工具 ............................................................................................................... 35 5.2.1 串口调试方法 ................................................................................................ 36 5.2.2 按键调试模块 ................................................................................................ 36 5.2.3 SD 卡与大容量 FLASH 调试模块 .................................................................... 36 5.2.3 上位机调试 .................................................................................................... 37 第六章车模技术参数说明 .................................................................................................. 38 6.1 车模主要技术参数 .............................................................................................. 38 第七章总结 .......................................................................................................................... 39 致谢 ...................................................................................................................................... 40 参考文献 .............................................................................................................................. 41 附录 A 程序源代码 ............................................................................................................. 42 附录 B 电路设计图 ................................................................................ 错误!未定义书签。 4 摘要 本文介绍了杭州电子科技大学杭电光电三队队员们在准备第九届飞思卡尔 智能车大赛中的工作成果。智能车的硬件平台采用Kinetis 微控制器,软件平 台为IAR开发环境,车模采用大赛组委会统一提供的B型仿真车模。文中主要介 绍了智能小车控制系统的机械结构、软硬件结构及设计开发过程。整个系统涉 及车模机械结构调整、传感器电路设计及信号处理、控制算法和策略的优化等 多个方面。车模以MK60DN512ZVLQ10单片机为控制核心,以安装在车身上的线性 CCD为循迹传感器, 采用红外对管检测起跑线, 以正交光电编码器检测速度信息。

车模系统的简单工作原理是MK60DN512ZVLQ10单片机采集线性CCD传来的赛道信 息,结合舵机控制算法控制舵机转角,单片机再综合赛道信息并结合旋转光电 编码器的速度反馈信号,利用电机控制算法控制速度变化。结合MATLAB软件仿 真和上位机软件的监控调试,最终确定了各项控制参数。

关键字:智能车;PID控制;上位机;MATLAB;线性CCD 第一章引言 1.1 概述 飞思卡尔杯全国大学生智能车竞赛以“立足培养,重在参与,鼓励探索, 追求卓越”为指导思想,涵盖了机械、模式识别、电子、电气、传感技术、计 算机、自动化控制、汽车理论等多方面知识,从一定程度上反映了当代大学生 综合运用所学知识和探索创新的精神。

我们积极组队参加第九届“飞思卡尔”杯全 国大学生智能车比赛。

光电组采用线性CCD检测赛道。其信号采集与摄像头组和电磁组有很大差别, 主要在于线性CCD对于光线的要求比较高,适应性相对较差,而且前瞻也有局限 性,结合上述特点,我们采用双CCD及“摇头”策略,加以合理的传感器布局, 经过后续电路处理,完成对赛道信号检测并以此来控制车子的转向和行驶速度。

关于软件,我们采用鲁棒性较强的PID控制算法来作为车子的主导控制。为满足 智能车在高速与急转等恶劣情况下的动力性能和稳定性能,我们参考了前几届 的队伍参赛经验,经过深思熟虑对整车经行了合理的重心与电路等的布局。

本技术报告主要讲述杭电光电三队智能车的制作历程,包括机械和硬件的 设计、改装,以及单片机的学习和使用,控制算法的研究与应用,车模机械参 数的讨论和修改等。 6 1.2 整车设计 1.2.1 车辆布局 鉴于赛道的摩擦力和复杂性以及车模的机械结构等因素, 我们认为在确保不 伤害赛道的情况下最大限度降低重心有利于车子行驶,主要是因为这对车子转 弯的性能以及直道加减速性能有很大帮助。故而在设计 PCB 及机械架构时主要 以降低重心及车模对称性为核心进行改装。

另外,由于 CCD 对于抖动比较敏感,所以我们采用特制支架对其加固,支架 以碳杆及铜柱为主要材料,这样可以在保证质量足够轻的前提下最大限度使在 车模运动时 CCD 不发生抖动。

此外,我们采用 500P 的 OME-A Ф18 光电编码器,直接用编码器齿轮咬合车 模后轮齿轮的方法来获取速度信息,从而对车子运行速度进行闭环控制。

车模主体部分:

1:

底盘及附属部分,包括电机、舵机、电池等; 2:

赛道信息检测部分,包括线性 CCD、红外对管等; 3:

编码器测速部分; 4:

单片机最小系统及电源电路; 5:

传感器支架; 6:

红外对管及 OLED。 图1.1 车模整体图 1.2.2 控制简述 由于传感器感应得到的电压信号相对较小,黑白线电压差值较小,所以我们 采用蓝宙电子提供的带运放的线性CCD,信号值经过运放后,黑白线差值较大, 然后再通过单片机AD口采集。同时编码器的信号也同步输入,由单片机的正交 编码模块进行采集计算,从而得到车子行驶的速度。舵机采用PID控制算法根据 速度及赛道信息进行控制,并且加入连续控制函数进行修正,使前轮的转向更 加具有连续性和精确性;驱动电机在最佳的驱动频率(15kHz)下,采用增量式 PID控制PWM通道的占空比而调整电机输出功率。 图1.2 车模控制系统概述 8 1.2.3 光电组的优势与劣势 光电组的信号采集与处理与摄像头组和电磁组有很大差异,对于光线要求 较高,所以适应性较差,我们尝试过动态曝光时间及动态阈值等算法加强其适 应能力。

线性CCD采集到的图像信息很少, 赛道识别难度比较大, 而且容易丢线, 前瞻也有局限性,所以对算法要求比较高,另外B车模本身机械架构较差,尤其 是前轮虚位及其严重,我们采用粘贴锡箔纸及AB胶固定等方法减小虚位。

光电的优势就在于B车模速度性能好,速度提升空间很大,合适的机械结构 及软件算法可以使之发挥出巨大的潜力。 1.3 小结 本章主要介绍了车模的整体设计思路和大致的布局,以上将会为以下章节 的介绍起到铺垫的作用。 第二章 机械设计与修改 2.1 前轮定位 为了使模型车在直线行驶时更加稳定,转向轻便,转向后能自动回正,并 减少轮胎和转向系零件的磨损等,在转向轮、转向节和前轴之间形成一定的相 对安装位置,叫车轮定位。其中包括主销后倾、主销内倾、车轮外倾和前束。

我们今年的比赛车模主销后倾角与前轮外倾不可直接调整,但是通过对前悬挂 系统的适当打磨(规则允许)可以达到一定的调整。接下来主要介绍主销后倾、 主销内倾和前束对车子行驶的影响及调教。 2.1.1 主销后倾 主销在车模的纵向平面内(汽车的侧面)有一个向后的倾角γ,即主销线 与地面垂直线在车模在纵向平面的夹角,称为“主销后倾角”,如图2.1示例所 示。车模采用主销后倾的原因是由于汽车在车轮偏转后会产生一回正力矩,纠 正车轮偏转。

车模的主销后倾不可直接调教, 在此我们采用预设的主销后倾角, 大概5度。如图2.2所示。 图2.1 主销后倾角示例 图2.2主销后倾角 10 2.1.2 主销内倾 主销在车模的横向平面内向内倾斜一个β角,即主销轴线与地面垂直线在 车模的横向断面内的夹角,称为“主销内倾角”,如图2.3示例所示。主销内倾 角β也有使车轮自动回正的作用,当转向轮在外力作用下发生偏转是时,由于 主销内倾的原因,车轮连同整个车模的前部将会被抬高;外力消失后,车轮在 重力作用下恢复到中间位置。

另外主销内倾还会使主销线延长线与路面的交点到车轮中心平面的距离减 小,同时转向时赛道作用在转向轮上的阻力矩也会减小,从而减小转向阻力, 使转向轻便,灵敏。最后,之所以这么做,是为了弯道。轮胎调整为倾斜以后 直线行走的时候是轮胎内侧着地。而当过弯的时候,由于惯性车体会要向弯道 外侧倾斜,而这时候的外侧轮胎如果倾斜角度事先调整得当则正好可以胎面着 地,从而使车辆在弯道获得最佳抓地力。而如果事先把轮胎装成是完全垂直于 地面的话,尽管直线行驶的时候轮胎是胎面着地,而到弯道就会变成轮胎外侧 着地了,那样将大大减小轮胎与地面的有效接触面积,从而导致弯道抓地力大 幅降低。不可过度调整,否则在直道和弯道时均使用轮胎内侧,导致轮胎严重 磨损,抓地力极低。可适当提高(向左侧调整)前轮内倾角,以便在过弯时保 持转向灵敏度。高速赛道提高(向左侧调整),低速赛道降低(向右侧调整)。

由于我们的车模要在高速下连续转弯,在此我们将车模主销内倾调教为-8 度左右。 图2.3 主销内倾角示例 图2.4 主销内倾角 2.1.3 前轮前束 前束是转向灵敏度与稳定性的权衡。

前束不可以无限度增大 (向左侧调整) , 太大了的话,直道行驶时车轮与地面发生的就不是滚动摩擦,而是滑动摩擦, 轮胎磨损将急剧增大,且会导致阻力加大,降低直道速度。过度减小(向右侧 调整),会导致稳定性降低,车辆抖动,难以操控。如图2.5示例所示。

为了增加车子的转向性能以及满足阿克曼转弯原理,我们将车子的前束调教 为tou out,大概5度左右。如图2.6所示。 图2.5 前束示例 图2.6 前轮前束 经过对以上车子前轮定位调整找到最佳参数后,车子在高速情况下获得较 好的稳定性与速度性能。 12 2.2 底盘高度 由于车模在赛道上高速行驶和连续急转弯,所以整车重心的高低决定了车 模的加减速性能、转向性能、行驶稳定性等。吸取了前几届摄像头车模在比赛 中翻车的教训后,我们坚持将整车重心最大限度的降低(前提是不伤害赛道)。

在包裹上后来组委会指定的防滑套后,我们进行了“先滑先翻”试验。就 是将车模放在赛道板子上, 然后逐渐倾斜板子, 看车模是先发生滑动还是先翻。

如果是先滑动,那么就是摩擦力或者抓地力不足,重心不会导致过弯时翻车; 如果是先翻车,那么说明重心太高。结果是车模先滑动,说明车模重心不是很 高了,一般不会发生弯道翻车。

为了增加转向的灵敏度,我们将前底盘的高度设定为低于后底盘高度,从 而在转弯时能够更灵敏的转弯。 2.3 主动悬挂 根据往届比赛我们了解到车模在加了主动悬挂以后对车对车模行驶有一定 帮助。 图 2.7 主动悬挂 2.4 传感器支架 关于支架的选取,我们历经多种方案。最开始采用“铜柱&塑料板&碳杆&AB 胶”,后来发现该方案铜柱太沉重,使车模前部重量大幅增加,而且铜柱质地 较脆硬,撞击或者过度拆卸就会“滑丝”甚至折断。直至最后采用碳杆的方案, 该方案一直使用到现在。优点在于:

1:架构简单,质量轻,强度大; 2:可以使传感器支架做长,获得较远前瞻。因为这种架构的转动惯量较 小,而且车模行驶时传感器支架抖动较小,所引起的传感器值改变小(后级的 运放放大后会使信号出现异常,因此减小抖动很重要); 3:可以做在任何位置,从而我们直接将支架固定在降低重心的配件里, 很牢固而且整车看起来简洁、坚固; 4:该组合架构拆卸和维修较为方便,如果碳杆折断,只需更换即可。 图 2.8摇头舵机安装 14 图 2.9 摇头舵机安装 图 2.10 固定CCD支架 2.5 舵机的安装 新车模的舵机是立式安放的,为了降低重心和减小前悬架的运动,我们将 舵机改为爬式放置。 图 2.11 舵机安装图 2.6 差速调整 今年B车模差速分为内外差速,差速效果较为理想,所以无需任何高难度调 整,只要保证差速在加速时不打滑即可。 图 2.12 差速 16 第三章硬件设计 这一章将说明我们车模的每一部分硬件电路的原理及设计的实现方法。 3.1 硬件电路整体架构设计 图3.1 车模系统电路总体构架图 系统整体结构如图3.1所示,我们将电路分成几个模块——单片机最小系统,电 源电路,传感器电路,电机驱动电路,调试用的液晶显示&按键电路。部分模块独 立在单独的电路板上,方便随时修改方案,并实现物理上的隔离。强电流和弱电流 分别分布在电路板上的两个角落。数字地与模拟地隔离。上述措施可以防止电磁干 扰,显著的提高电路的稳定性。 3.2 单片机最小系统板电路设计 为提高队员的动手能力和减小模型车总重量,我们自己设计了单片机最小系统 板。最小系统板使用MK60DN512ZVLQ10芯片。最小系统板中包括单片机时钟(有源 晶振提供)与复位电路、3.3V稳压电路、JLINK接口,并引出其他需要的IO。而光 电编码器接口、舵机接口、驱动电路接口等就直接设计在主板上,因为他们的供电 比较麻烦而且供电必须稳定才行。整个最小系统电路板按照Freescale提供的PCB Layout设计,保证了电路的稳定性。为了提高单片机最小系统的稳定性,防止540 电机和伺服舵机在大功率工作时(例如直到加速或者急转弯减速时)将电池电压拉 低导致最小系统工作出现故障,我们修改了最小系统的供电方案。首先我们将电池 电压降压到5.5V,再稳压到3.3V,显著提高了单片机的抗干扰能力。 图 3.2 单片机最小系统 PCB 图 图 3.3 单片机最小系统实物图 3.3 传感器设计 传感器模块我们直接采用了蓝宙电子的线性CCD模块。 3.4 起跑线检测电路 按照比赛规则,起跑线是两条10cm长的黑线。用四个线性排列的红外对管 进行检测即可。通过调整红外对管的相对距离可以确保每次车模经过都至少有 18 两个对管检测到黑线。 图3.4 红外对管检测电路 3.5 电机驱动电路设计 对于电机驱动电路,可有多种选择,像专用电机驱动芯片MC33886、L298N 等,但是以上芯片效果不好。因为电感作为传感器前瞻比较小,因此需要用H桥 的全桥电路刹车才能够使得车及时刹车,减速入弯。另外,今年电磁组的电机 采用540电机, 功率较大, 我们大概测试过启动或者堵转时电流可以达到7.5A (适 当的驱动频率下),甚至烧毁电池的保护连接件。开始我们采用英飞凌的集成 半桥芯片BTS7960B构成H桥来驱动电机,由于速度提升后电机耗电较大,所以发 热严重,使得BTS7960B进入过热保护而导致车子停止前进。后来改用MOS H桥来 驱动电机,当速度达到一定水平后焊接MOS的焊锡融化后使MOS掉落,烧毁很多 电路。于是我们又开始艰难的尝试新的驱动方案。最终我们找到了4N MOSFET的 H桥方案,于是采用4N MOSFET 的H桥使得电机驱动问题彻底解决。该电路也较 为简单,百度文库即可搜到。往届技术报告亦有所提及。 图3.5 驱动电路 图3.6 驱动电路 3.6 舵机驱动电路设计 今年B车转向舵机采用的是S-D5数字舵机,工作电压小于5.5V。为了稳定性 和舵机寿命,我们于是给该舵机提供5.2V到5.4V的电压。早期检测表明该舵机 耗电较大,因此我们就没有使用使用比较广泛的LM2576和LM2596,而是采用新型 的8133降压稳压器(输入级直接是电池电压),8133足够提供舵机的供电,还能有 较大电流的裕量。实际测试的过程中也没有出现因为舵机供电的问题导致舵机反映 迟钝。所以最终就采用了这种方案。舵机的控制除了需要5.4V的供电电压还需要一 路PWM波,以20ms为周期(实际S-D5数字舵机可以用最大300HZPWM信号控制), 不同的占空比会使舵机稳定在不同的角度上,具体如图3.12所示。 20 图 3.6.1 不同PWM对应的舵机旋转角度 3.7 液晶按键电路设计 为使软件上参数调节的方便,我们特意制作了这个液晶加键盘模块。调试中, 这个模块给我们对参数的确定带来了极大的方便,不用为改一个参数而重新为单片 机下载一下程序。模块采用键盘+ OLED液晶。此模块直接与最小系统板连接,并将 其直接固定在主板。 图3.7 液晶按键PCB图图 3.8 液晶按键PCB图 3.8 系统电源电路设计 系统要稳定工作, 首先电源要稳定, 系统中有多路电源, 7.2V, 5.5V, 3.3V等。

7.2V电池电压直接接到电机启动模块, 5.5V为舵机供电, 3.3V为单片机、 红外模块、 CCD以及液晶供电。 3.9 系统主板电路设计 由于硬件是分模块设计的,最终要接在一起才能相互通信。主板电路主要有电 池接口、单片机最小系统板插座、电源电路板插座、舵机及电机驱动接口。另外, 主板上还集成了出3.3V稳压电路。接口电路板的PCB设计是要充分考虑与车模机械 的配合,于是更多的采用高效优质的牛角插座及排线来完成远距离连接。 图3.9 主板电路PCB图 图 3.10 整体电路实物 22 3.10 电源电路设计 由于主板空间有限,故将部分电源模块单独做出,包含 3 路 5.5V 电源电路,分别为打 角舵机、摇头舵机和扭腰舵机、3.3V 稳压芯片供电。 图 3.11 电源电路 PCB 图 3.12 电源电路实物图 3.11 小结 对于硬件电路部分,一定要用料扎实,稳定第一,抗干扰性能一定要高。单片 机电压一定要稳定,防止舵机和电机启动的时候拉低电压导致复位。解决这个问题 最实用的办法就是加上储能器件,加上适当大小的电容是必要的。整个电路板的制 作过程也要十分严谨。电路简单的线路板直接使用手工制作。复杂的电路要经过好 几个步骤。首先手工制作电路板,长时间工作以测试其稳定性。当稳定性达标之后 根据原理图重新布线,到工厂生产PCB,制作出第一批样品。没有问题的样品电路 板直接使用,布局不好或者是影响性能的电路板要重新制作,直至纹波、质量、体 积、布局都达标才是最终产品。硬件电路是智能车的基础,只有打好基础才能继续 软件方面的工作。 第四章软件系统设计 4.1 软件控制的总体思路 软件控制即将自己的思路通过代码形式灌输到单片机中,并让其高速有序 的执行。对于所有智能车来说软件控制基本是按照路径识别=>摇头控制=>主动 悬挂控制=>舵机控制=>速度控制。其目的是在比赛时以最快速度,最佳路径跑 完全程。具体方案就是采集CCD传来的赛道电压值,判断赛道两侧黑线的位置, 控制摇头打角,主动悬挂,进而控制舵机打角,控制电机转速。思路清晰可行, 但真正想达到好的效果还是有一定难度的。 4.2 主程序结构 软件设计,主要包括以下几个部分:初始化、路径信息采集、决策控制等 几个部分。程序的主体采用顺序结构。为了方便控制,Main函数里面除了初始 化程序就是起跑线检测, 而所有的核心操作放在定时中断中。

如果说画流程图, 从宏观上来看是两条线同时执行。如图4.1所示: 24 图4.1 主程序结构示意图 4.3 程序的运行 电源打开后后,对智能车所有参数进行初始化处理,接着进行PIT 定时中 断,对线性CCD传感器采回来的数值进行分析,由此判断出赛道的两边黑色引导 线的位置坐标,根据实时信息设置合适的参数,并由此执行以下的控制步骤。

根据CCD采集的黑线位置计算出赛道两侧的黑色导线与车正中心的偏差(下简称 黑线偏差)。并由黑线偏差的大小调节合适的CCD前瞻远近以实现最合适的路径 采集与处理。获得赛道信息与目前的车身与赛道间的黑线偏差后,即可结合舵 机的PID控制算法控制舵机的打角值,打角与黑线偏差的关系由PID控制,调节 最适的PID参数用以最佳的路径跑法。同时根据两个CCD的远近关系以及黑线偏 差可以相互切换使用,由黑线的偏差量即时改变给定电机的目标转速。在获取 到目标转速后,通过电机的PID控制器迅速稳定的控制电机达到目标转速。 4.4 路径识别子程序设计 路径识别包括对CCD传感器的控制以及采集信号的处理。我们利用PIT 定时 中断,在一定的中断时间后进行CCD的采集函数,将CCD的128个位置的采集电压 值用数组line[128]储存下来。对128个点的电压值进行精细分析,通过设定阈 值的方法滤除杂波之后,利用二值化或者边沿检测的方法对数据的有效性判断, 并确定采集到的赛道黑色引导线在CCD上的坐标值,左边黑线坐标Lx,右边黑线 坐标Rx,由此借助前瞻的最适状态可以计算出车身与赛道的偏离情况:Mid = Lx + Rx - 128,进而可以进行一下的舵机以及速度等控制。另外,为适应今年的 赛道规则,我们特地对今年的人字,坡道,障碍等元素通过CCD采集来的值进行 了适当处理,得到相关信息,进而可以相应的进行打角或速度控制。 4.5 摇头舵机控制子程序设计 摇头舵机的作用在于, CCD 传感器的角度可以根据上次黑线的采集情况以及 车身的偏离大小变化,使得 CCD 采集的黑线不会因为弯道过急造成丢线情况并 出现复杂反应。

摇头舵机打角是基于黑线采集判断。路径识别中得到的黑线偏差量 Mid 在 26 摇头舵机的控制中起到到关键的作用。通过分析本场数据和上一场数据的关系, 可以得到两次黑线偏差量的差值变化,由此还可以判断黑线的变化率 Mid_cha, 即可判断出进出弯道的情况,在接下来的 PID 控制中 Mid_cha 的作用在于增强 了过弯打角的敏感度。

经过舵机调试设定摇头舵机占空比给定的大小,通过黑线的偏差量和变化 率计算出应该给定的数值 PWMDTY_yaotou=Mid*P+Mid_cha*D,其中 P、D 参数的 设定是要根据实际情况做出最合适的调整的,它的大小影响了 CCD 的摇头量, 进而影响 CCD 的采集状态,影响转向舵机打角,还会影响速度的控制,所以, 摇头舵机的控制将是我们智能车的很重要的一部分,当然其他控制也是极其重 要,缺一不可。图 4.2 是摇头舵机占空比给定的模拟曲线图。 图4.2 PWMDTY_yaotou给定的效果图 4.6 转向舵机控制子程序设计 关于转向舵机打角是建立在赛道分析和黑线采集判断的基础上的。路径识 别中得到的黑线偏差量Mid在接下来的控制中起到到关键的作用。通过分析本场 数据和上一场数据的关系,可以得到两次黑线偏差量的差值变化,由此还可以 判断黑线的变化率Mid_cha,即可判断出进出弯道的情况,在接下来的PID控制 中Mid_cha的作用在于增强了过弯打角的敏感度。通过长时间的调试,设定好不 同的PID参数,用来给定舵机PWM的占空比的比例,另外加上摇头舵机的摇头大 小基于打角占空比PWMDTY_zhuanxiang = PWMDTY_yaotou + Mid*Mid*A+Mid*B + Mid_cha*C。其中A、B、C是长时间调试出来的结果。其中二次项的系数越打角 会沿二次函数,一次项系数越大打角就越剧烈,C项越大直道就会抖动,但是过 弯很灵敏。但最后实现的效果图如4.3 所示。 图4.3 PWMDTY_zhuanxiang给定的效果图 4.7 悬挂舵机控制子程序设计 悬挂舵机的作用在于, 车子在过弯的时候, 可以使得车身往一侧略显倾斜, 就像人骑摩托车过弯一样,可以让过弯道更加灵活,对车身的机械寿命也有一 定的改进作用,防止往一侧过弯,因为重心向外测便宜,造成另一侧的车身损 28 伤过于厉害。

悬挂舵机控制是依赖于转向的大小的。针对不同转向舵机的打角值,给定 不同的悬挂舵机打角大小,可以给定不同的车身倾角,进行悬挂控制经过不断 的调试设定悬挂舵机占空比给定的大小,通过转向的大小和变化率计算出应该 给定的数值 PWMDTY_xuangua=zhuanxiang*P1+zhuangxiang_cha*D1,其中 P1、 D1 参数的设定是要经过不断的调试得到的。 4.8 速度控制子程序设计 速度控制部分是智能车除了舵机控制之外最为核心的内容。一个好的速度 控制就是在不同的赛道处可以十分准确的给出目标速度,以求借助最适合和最 快的速度过不同的赛道,电机对目标速度响应迅速,系统在干扰下速度依然稳 定。 4.8.1 模拟 PID 控制原理 第一步要求有合理的速度决策。我们最终采用的速度决策方法是一次函数。

速度的一次函数是根据黑线的偏差情况给定的,不同的速度适合不同的偏差量, 这个一次函数的关系需要不断调试实现,再设定出最高速度和最低速度,确保 能够最快最稳定的进行。另外,由于本届规则设定了人字和障碍,以及坡道, 通过赛道的判断,给予这三个元素不同的速度控制。而且这些速度都是可以根 据赛道的具体情况通过按键在比赛准备时设定。同时我们基于对路况的识别对 速度进行分配,速度分配的基本原则是长直道加速,入弯减速,弯道中适当加 速。同时给不同的弯道(如大弯,S 弯)其所能运行的最高速度。 图4.4 PWMDTY_sudu给定的效果图 速度给定了之后执行也大有学问。

直接列出速度和占空比的关系是一种十分 不稳定的做法。这种做法受电池电量影响严重,而且只能适应某一种摩擦力的 赛道。所以我们决定根据编码器反馈回来的数值进行换算。实际我们给定的目 标速度与目标编码器的值是匹配的,当编码器反馈回来的速度没有达到目标速 度,那么正转占空比自加,反之则自减。只要调节自加和自减的步进就能很好 的对速度进行控制。这种步进,就是经典的增量式PID。

对车速的 PID 闭环控制策略是将建立在经典的 PID 控制算法的基础上。

有关 PID 的控制策略在这里做相关的介绍说明。

将偏差的比例(Proportion) 、积分(Integral)和微分(Differential)通过线 性组合构成控制量,用这一控制量对被控对象进行控制,这样的控制器称 PID 控 制器。 4.8.2 模拟 PID 控制原理 在模拟控制系统中,控制器最常用的控制规律是 PID 控制。为了说明控制器 的工作原理,先看一个例子。如图 4.5 所示是一个直流电机的调速原理图。给定 速度 n0 (t ) 与实际转速 n(t ) 进行比较,其差值 e(t ) = n0 (t ) ? n(t ) ,经过 PID 控制器调 30 u (t ) 经过功率放大后, 整后输出电压控制信号 u (t ) , 驱动直流电动机改变其转速。 图 4.5 直流电机调速系统 e(t ) = r (t ) ? y (t ) 常规的模拟 PID 控制系统原理框图如图 4.4 所示。 该系统由模拟 PID 控制器和被控对象组成。图中 r (t ) 是给定值, y (t ) 是系统的实 际输出值,给定值与实际输出值构成控制偏差 e(t ) 。 e(t ) 作为 PID 控制的输入, u (t ) 作为 PID 控制器的输出和被控对象的输入。 所以模拟 PID 控制器的控制规律如式(4.2) ,原理图如图 4.6 所示。 ? 1 u (t ) = K p ?e(t ) + Ti ? kp ∫ t 0 e(τ )dτ + Td de(t ) ? ? t ? (4.2) 式中: ——控制器的比例系数 Ti ——控制器的积分时间,也称积分系数 Td ——控制器的微分时间,也称微分系数 图 4.6 模拟 PID 控制原理图 4.8.3 增量式 PID 控制原理 由于计算机的出现,计算机进入了控制领域。人们将模拟 PID 控制规律引入 到计算机中来。对式(4.2)的 PID 控制规律进行适当的变换,就可以用软件实 现 PID 控制,即数字 PID 控制。 ?un = K p (en ? en?1 ) + K i en + K d (en ? 2en?1 + en?2 ) 由于计算机控制是一种采样控制,它只能根据采样时刻的偏差计算控制量, 而不能像模拟控制那样连续输出控制量量, 进行连续控制。

由于这一特点式 (4.2) 中的积分项和微分项不能直接使用,必须进行离散化处理。离散化处理的方法 为:以 T 作为采样周期, k 作为采样序号,则离散采样时间 kT 对应着连续时间 t ,用矩形法数值积分近似代替积分,用一阶后向差分近似代替微分。这样就将 模拟 PID 控制演变为数字 PID 控制的增量式的 PID 控制,增量式 PID 控制算法可 以通过式(4.2)推导出。其算法公式如下: ? 1 u (t ) = K p ?e(t ) + Ti ? ∫ e(τ )dτ + T t 0 d de(t ) ? ? t ? (4.2) e e ?u e 其中, n 为第 n 次输出增量; n 为第 n 次偏差; n?1 为第 n-1 次偏差; n?2 为第 n-2 次偏差。

具体控制流程如图 4.7 所示: 32 图 4.7 增量式 PID 控制算法原理图 速度的软件控制算法流程图如图 4.8 所示。 图 4.8 速度的软件控制算法流程图 4.9 小结 软件部分是整个控制系统的核心。软件上主要有以下几个难点:

1) 怎样处理CCD传感器采样回来的赛道信息; 2) 怎样根据传感器信息判断车身位置和状态; 3) 怎样根据车身状态打角; 4)怎样针对不同的弯道给定合适的目标速度,以及速度PID的整定; 5)本届智能车比赛的三个重要元素:人字,不对称坡道,障碍的判断和处理。

对于车模来说,软件控制是核心部分,而对于软件来说,舵机打角和速度控制 都不算是核心,真正的核心应该是舵机打角和速度控制的相互匹配! 本车模软件系统对两个舵机及速度的控制均以PID控制技术为原理,适当发 挥再加以利用。 34 第五章 开发调试过程说明 5.1 开发工具 好的程序控制思维很重要, 一套全面的开放热啊工具和调试工具也十分重要。

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

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

开发使用语言是 C 语言 C 语言的使用特点:

1.具有很强的功能性、结构性和可移植性 2.具有语言简洁、紧凑,使用灵活、方便,运算符和数据类型丰富 3 可以直接对硬件进行操作 4.当特殊情况下,使用 C 代码中嵌入式汇编 5.2 调试工具 为了能够更好更清晰地实时了解车子情况,从而有目的有方向地整改车子, 修改相应的程序。调试时,我们在车子上加装了各种调试模块,使其可以通过发 送数据,显示数据或图像,储存数据,修改参数等功能来了解小车的各项信息与 指标。进而可以方便地实时显示、统计以及保存小车行驶过程中各项参数如车子 速度、转向舵机转角大小及方向,悬挂舵机的给定大小以及摇头舵机转角等的变 化,储存各个赛道元素的相关信息精确调试。

调试工具简介:

串口 无线串口或蓝牙 液晶按键装置 SD 卡 大容量 Flash 遥控 调试辅助软件技术 5.2.1 串口调试方法 1.拖线式串口 直接使用单片机的SCI串口,用线直接与笔记本PC相连接,跟着车跑或者静 态数据传输。

优点:实时回传传感器信息与动作控制信息 优点:简单高效,数据速率也可以比较高 缺点:拖线 2.无线串口或蓝牙 通过无线串口或蓝牙装置传输数据,可以动态传输,车子在跑的时候可以不 需跟着车子跑就能实时观察赛道信息 优点:不拖线,方便 缺点:传输速度有限,容易丢失数据 5.2.2 按键调试模块 特点:直观的显示传感器数据和赛道信息状态 显示控制状态以及各项参数 5.2.3 SD 卡与大容量 FLASH 调试模块 特点:

储存小车运行时各项指标数据用作后期分析 本地存储 大容量存储 36 5.2.3 上位机调试 智能车的调试需要用到上位机系统,有针对性的开发一个便于人机交互的上位机 系统,通过简单明了的可视化界面直观的显示智能汽车的状态对调试有很大帮助。因 此,我们开发了用于监测智能车实时状态的实时监测系统,大大提高了调试效率。智 能汽车通过串口或无线串口与实时监测系统进行通讯。通过该系统,我们可以实时了 解到智能汽车的实际行驶路线,并且能够监测智能汽车在行驶过程中转角、传感器状 态及速度等相关信息。实时监测系统还有一些其他辅助功能,为智能汽车调试过程提 供了大量有用的信息。 1.基于C#的CCD显示上位机设计和使用 本款 CCD 信息显示上位机系统用 C# 开发完成。该系统通过 PC 机串口与无线模块 连接。

CCD 信息显示上位机主界面如图 5.1 所示: 5.1 上位机界面图 2.基于matlab的控制信息显示上位机的设计和使用 本款控制信息显示上位机系统用 matlab 语言开发完成。

该系统通过 PC 机串口与 无线模块连接。该上位机系统可以通过处理将 Flash 或 SD 卡储存的信息,将有效数据 形象,人性化的显示在电脑 PC 上。控制信息显示上位机主界面如图 5.1 所示: 5.2 上位机显示信息 第六章车模技术参数说明 6.1 车模主要技术参数 表6.1车模主要技术参数 名称参数 车模总质量 1400.g 车模长度 796.0mm 车模宽度 245.0mm 车模高度 213.0mm 电路总功耗 10.0W 电路电容总容量1800.0uF 传感器个数 6个 传感器种类电感×4+干簧管×1+编码器×1 赛道检测精度 5.0mm 赛道检测频度 200次/秒 前轮距 156.0mm 后轮距 174.0mm 前后轴距 192.0mm 额外伺服器 1个 futaba S3010 编码器精度 500.0P/r 38 第七章总结 本报告详细介绍了我们为第六届全国大学生智能汽车大赛而准备的智能车 系统方案:涉及传感器制作等方法,前轮舵机打角控制策略以及速度控制算法 集实现。

分析整个车模系统,我们在车模硬件及软件上都有许多改进与创新。系统 上主要有以下特色:

1)采用极少数的几个电感作为传感器,并使用其模拟量来探测赛道,精度 更高。

2)传感器使用单排,除了计算车身与导线的距离以外,还计算了偏差角度, 同时还能够在一定程度上增加一点前瞻。这对于磁导航的智能车来说是难能可 贵的。

3)主板采用可插拔的接口,方便电路的升级和局部维修,同时也降低了成 本。

4)完全按照自己的需求定制了单片机最小系统板。最小系统板集成度非常 高,极大的减轻了重量和减小了体积,方便机械布局。

5)增加了按键与液晶辅助调试电路。配合参赛选手的临场发挥,增强了车 对赛道的适应能力。

6)整个程序的控制部分只开启一个定时中断,控制步骤简单,容易调试。

7)单片机最小系统板是采用水平放置的,充分的利用空间降低重心。

但是横观我们车模的整个设计,我们觉得系统几个方面还有可以改进的地 方:

1)测速传感器虽然使用500P/r,但是精度还是不够,尤其是对5ms的反馈 周期来说。当设定到一个很低的速度时会有严重的速度震荡; 2)传感器改进。目前我们使用的传感器由于信号的白噪声,在人工差分的 时候无法提高精度,所以有必要在后级电路上加上一级有源带通滤波。

3) 传感器支架虽然已经做得较好,但是新型材料层出不穷,我们知道的材 料也是很少,所以在支架方案还有待做得更加完美。这也符合大赛举办的目的。 致谢 在为本次大赛制作智能车期间,我们遇到过很多问题,从最初的传感器选型 与方案确定,到后来的软硬件联合调试。在解决一个个问题之后,我们发现,我 们技术上在不断成长,思想上不断成熟。而在这过程中,离不开学校,老师和同 学的支持。

首先,我们要感谢学校对这次比赛的重视,感谢学校教务处对我们比赛的大力支 持。没有他们的支持,我们的车模绝对上不了赛场,更不用说在浙江赛区有的良 好发挥。

其次,我们要感谢两位老师的悉心教导。没有他们在思想上的指导和整体的 规划安排,我们很难有今天的成果。

最后,我们要感谢同实验室的其他同学,感谢我们同时工作在这么和谐的实 验室。感谢他们在赛道制作和其它方面的帮助。 40 参考文献 [1] 孙同景,陈桂友 Freescale 9S12 十六位单片机原理及嵌入式开发技术, 北京-机械工业出版社,2008 [2] 邵贝贝. 单片机嵌入式应用的在线开发方法. 北京-清华大学出版社 2004 年10 月第1 版 [3] 卓晴,黄开胜,邵贝贝学做智能车北京-北京航空航天大学出版社 2007 [4] 王威 HCS12微控制器原理及应用北京-北京航空航天大学出版社 2007 [5] 李宁,刘启新电机自动控制系统北京-机械工业出版社,2003 [6] 谭浩强 C++程序设计北京-清华大学出版社 2004 [7] 潘松,黄继业现代数字电路基础教程北京-科学出版社 2008 [8] 王水平开关稳压电源原理及设计北京-人民邮电出版社 2008 [9] TI公司 Use of Rail-to-Rail Operational Amplifiers / Application Report 1999 [10] infineon公司 BTS7970 Rev2.0/ Datasheet 2006 [11] 钱江一号第四届“飞思卡尔”杯全国大学生智能车大赛技术报告杭州 电子科技大学 2009 [12] 钱江六号第五届“飞思卡尔”杯全国大学生智能车大赛技术报告杭州 电子科技大学 2010 [13] 第五届“飞思卡尔”杯全国大学生智能车大赛清华大学三角洲电磁队技 术报告 [14] 韩绍坤,许向阳,王晓华编.自动控制原理.北京理工大学出版社,2009 [15] 张笑天,杨奋强编.MATLAB7.x基础教程.西安-西安电子科技大学出版社, 2008 [16] hudy_set-up_book,车模调教说明。来自智能车制作论坛。 I 附录 A 程序源代码 #include "common.h"

#include "include.h"

uint8_t usb_com_rx_len = 0;

uint8_t rx_buf[64];

byte ExposureTime = 12 ;

byte Delay_Time_Control ;

byte Delay_Time_Speed ;

int Key_Delay ;

extern int Speed_Number ;

extern byte STOP_Flag ;

extern byte A ;

extern int Speed_Want ;

extern byte Ren_R , Ren_L ;

int dd ;

int ee ;

int ff ;

int rr ;

int Car_Stop_Delay_3 = 3000 ;

int Car_key_Stop ;

int Tuo_X , Tuo_Y ;

extern byte Enter_Obstacle_R ;

extern byte Enter_Obstacle_L ;

extern int steer_P ;

extern int steer_PP ;

extern int steer_D ;

int p , pp , d ;

byte GO_Flag = 0 ;

int GO_Delay_CNT = 400 ;

int STOP_ID_Delay_CNT = 500 ;

void void { pit_hander(void);

main(void) DisableInterrupts;

LCD_Init();

KEY_Init();

CCD_Init();

PWM_Init();

pit_init(PIT0,3 * bus_clk_khz); 42 set_vector_handler(PIT0_VECTORn,pit_hander);

gpio_init(PTC13, GPO, 0);

adc_init(ADC1_SE17);

adc_init(ADC0_SE18);

adc_init(ADC0_SE8);

adc_init(ADC0_SE9);

adc_init(ADC0_SE12);

adc_init(ADC0_SE13);

EnableInterrupts;

enable_irq(PIT0_IRQn);

p = steer_P ;

pp = steer_PP ;

d = steer_D ;

while(1) { Data_Control();

} } void pit_hander(void) { PIT_Flag_Clear(PIT0);

if(Key_Delay <

100) Key_Delay ++ ;

rr=adc_once(ADC0_SE8, ADC_8bit);

dd=adc_once(ADC0_SE9, ADC_8bit);

ee=adc_once(ADC0_SE12, ADC_8bit);

ff=adc_once(ADC0_SE13, ADC_8bit);

Tuo_X = adc_once(ADC1_SE17, ADC_8bit);

Tuo_Y = adc_once(ADC0_SE18, ADC_8bit);

if(GO_Flag == 0) { STOP_Flag=1;

} else { if(GO_Delay_CNT >

0 ) GO_Delay_CNT--;

if(GO_Delay_CNT <10 &&GO_Delay_CNT>5) { STOP_Flag= 0 ;

} } if(GO_Delay_CNT == 0 ) { if(STOP_ID_Delay_CNT>0) STOP_ID_Delay_CNT--;

} STOP_ID();

if(STOP_Flag == 1) { Speed_Want = 0 ;

} Speed_Test_Control();

Delay_Time_Speed = 0 ;

Delay_Time_Control += 3 ;

if(Delay_Time_Control>= ExposureTime) { Delay_Time_Control = 0 ;

CCD_Update_Control();

CCD_Update_Ren();

Car_Control();

Suspension_Control();

} } byte CCD_Data[128];

byte CCD_Ren[128];

int Speed_Now , Speed_Number , Speed_Time , Speed_Now_Old , Speed_Want , Speed_Want_Old ;

int Speed_Control = 240 , Speed_I_Number , Speed_I_Number_Old;

int Speed_P = 100 , Speed_I = 100 , Speed_D = 140;

int CCD_PP = 20 , PP_DATA1 , PP_DATA2, PP_DATA ;

int CCD_P = 210 , P_DATA ;

int CCD_D = 340 , D_DATA;

int Steering_CCD_Old = 0 ;

int Steering_CCD = 10000 ;

int CCD_Centre = 10000 ;

byte Ramp_Data = 100 ;

byte Ren_R_Delay_CNT = 20 ;

byte Ren_L_Delay_CNT = 15 ; 44 byte Speed_Minus = 30 , Speed_Multis = 10;

int Speed_Data = 170 , Speed_L = 0 , Speed_R = 0;

int Speed_Straight ;

byte Speed_Init = 4 ;

float speedp , speedi , speedd ;

int Speed_Add_R , Speed_Add_L ;

int Straight_Long_Delay ;

byte Long_Stop ;

int Speed_Minus_D ;

int Straight_Line ;

int Straight_Number ;

int steer_P =280 , steer_I=0 , steer_D=900 ;

//70 int steer_PP = 10 , steer_PPP = 0;

byte Steering_L_1 , Steering_R_1 ;

byte Steering_L_2 , Steering_R_2 ;

byte S_Sign = 1 , S ;

int S_Time , Speed_S ;

int Steering_Data = 9700 ;

int Steering_Data_Old = 9700 ;

int Steering_Real_Old ;

int Centre_Number = 9640 ;

int Steering_Max = 11830 ;

Int Steering_Min=7450;

int CCD_Max = 14500 ;

int CCD_Min = 5500 ;

int Steering_Real ;

byte yao_L11 = 18 , yao_R11 = 13 , you11 = 7 ;

int Steering_Data_P , Steering_Data_I , Steering_Data_D ;

int Steering_Data_PP , Steering_PP_1 , Steering_PP_2 , Steering_PPP_1 , Steering_PPP;

int Number_I = 0 ;

int Seat_Line ;

byte LX , RX ;

byte I_Old_Line = 1 ;

byte K_Old_Line = 126;

byte Shi_L , Shi_R ;

byte Ren_LX, Ren_RX ;

byte Centre_Shi ;

extern byte ExposureTime ;

byte Black_White_Compare = 12 ;

byte Centre_Line = 64 ;

byte Centre_Ren = 64 ;

byte Centre_Line_Old = 64 ;

byte Centre_Line_Shi ;

byte A , A_Old ; byte sy,Send_Control;

int Yao_Centre = 10710 ;

// 10710 int Yao_Max = 10600 ;

int Yao_Min = 9300 ;

int Yao_Data ;

int Yao_Speed ;

int Yao_Steering ;

byte STOP_Flag = 0 ;

byte Stop_Number = 35 ;

int Stop_DD ;

int Stop_EE ;

int Stop_FF ;

int Stop_RR ;

int Car_Stop_Delay_2 ;

byte Outside_STOP_L_Flag , Outside_STOP_R_Flag ;

byte Outside_STOP_L_CNT , Outside_STOP_R_CNT ;

extern int STOP_ID_Delay_CNT ;

int Straight_Long , Straight_Stop ;

char Ren_Straight_L , Ren_Straight_R ;

char Ren_Straight_Long ;

byte Chang ;

byte L_Line , R_Line , A_Line ;

int Bias,Bias1,Bias2,Bias1_old,Bias_old;

byte Ren_L , Ren_R ;

char Enter_Ren_L1 , Enter_Ren_R1 , Enter_Ren_Speed_L , Enter_Ren_Speed_R byte Ren_Line_L , Ren_Line_R ;

byte Enter_Ren_L2 , Enter_Ren_R2 ;

byte Enter_Ren_L3 , Enter_Ren_R3 ;

byte Ren_L_Delay , Ren_R_Delay ;

byte Ren_R_Width , Ren_L_Width ;

byte Ren_LX_Old , Ren_RX_Old ;

byte Ren_White , Ren_White_Delay ;

byte Ren_Speed_Down , Ren_Speed_Delay ;

byte Ren_L_Old , Ren_R_Old ;

byte Enter_Obstacle_L1 , Enter_Obstacle_R1 ;

byte Obstacle_Number ;

byte Ramp_1 , Ramp_2 , Enter_Ramp1 , Enter_Ramp2 , Enter_Ramp3 ;

int Ramp_Keep ;

int Ramp_Delay ;

extern int dd ;

extern int ee ;

extern int ff ;

extern int rr ;

byte Ramp_ee , Ramp_rr , Ramp_dd , Ramp_ff ; 46 ; byte Ramp_Delay_m ;

byte Ramp_m_1 , Ramp_m_2 ;

byte Ramp_Flag ;

byte Ramp_Interval_CNT=10;

byte Keeping , Keeping_A , Keeping_Wan ;

byte Keep_L_Line , Keep_R_Line ;

byte Keep_White ;

byte Enter_Keep_L , Enter_Keep_R ;

byte Close_Keep_L , Close_Keep_R ;

byte Keep_L_Stop , Keep_R_Stop ;

int CCD_average , CCD_average_White ;

byte LX_Old , RX_Old ;

byte l_temp = 0, r_temp =0;

byte Shi_L , Shi_R ;

byte Stop_Car_Wan ;

byte Stop_Car_Shi ;

byte Ren_EN = 0;

byte Obstacle_EN = 1 ;

byte Ramp_EN = 1;

byte STOP_EN = 0; void Car_Control(void) { CCD_average = (CCD_Data[45]+CCD_Data[55]+CCD_Data[65]+CCD_Data[75]+CCD_Data[85]) / 5;

if((LX >

30) &&

(RX <

100)) CCD_average_White = (CCD_Data[55] + CCD_Data[65] + CCD_Data[75]) / 3 ;

CCD_Black_Line();

if(Obstacle_EN == 0) Obstacle();

if((LX <

7) &&

(RX <

80)) Centre_Shi = 30 ;

if((LX >

50) &&

(RX >

120)) Centre_Shi = 97 ;

if((LX<=10) &&

(RX>=117)) A ++ ;

else A = 0;

if(A_Old == 1) Keeping_A = 20 ;

if(Keeping_A >

0) Keeping_A -- ;

if(Ren_EN == 0) Ren_Discriminate();

if(Ramp_EN == 0) Ramp_Discriminate();

PID_Compute() ;

if(Jue_Dui_Zhi(Steering_Data , Centre_Number) >

1500) Stop_Car_Wan = 20 ;

if(Stop_Car_Wan >

0) Stop_Car_Wan -- ;

if((LX <

7) &&

(RX >

120) &&

(CCD_average >

(CCD_average_White - 17))) Stop_Car_Shi = 40 ;

if(Stop_Car_Shi >

0) Stop_Car_Shi -- ;

Speed_Want_Control();

Speed_Steering_Control();

I_Old_Line = LX ;

K_Old_Line = RX ;

Steering_Data_Old = Steering_Data ;

Steering_Real_Old = Steering_Real ;

Steering_CCD_Old = Steering_CCD - CCD_Centre;

Centre_Line_Old = Centre_Line ;

if(A >= 3) A_Old = 1 ;

else A_Old = 0 ;

Ren_LX_Old = Ren_LX ;

Ren_RX_Old = Ren_RX ;

} void Speed_Test_Control(void) { Speed_Number = FTM_QUAD_get(FTM2);

Speed_I_Number = Speed_Want - Speed_Number;

if(Speed_I_Number >

400) Speed_I_Number = 400 ;

if(Speed_I_Number <

-400) Speed_I_Number = -400 ;

Speed_Time = 3 ; 48 if(Speed_Time == 3) { Speed_Now = Speed_Number ;

if(Speed_Init <

3) { Motor_Zheng_Control(Speed_Control) ;

if(Speed_Now >

Speed_Want) Speed_Init ++ ;

//BL = 1 ;

} else { Bias = Speed_Want - Speed_Now;

Bias1 = Bias - Bias_old;

Bias2 = Bias1 - Bias1_old;

speedp = (float)(Bias1 * Speed_P) / 10.0 ;

speedd = (float)(Bias2 * Speed_D) / 15.0 ;

speedi = (float)(Bias * Speed_I) / 100.0 ;

Speed_Control += (int)(speedp + speedi - speedd) ;

if(Speed_Control >

900) Speed_Control = 900 ;

if(Speed_Control <

-500) Speed_Control = -500 ;

if(Speed_Control >= 0) Motor_Zheng_Control(Speed_Control) ;

else Motor_Fan_Control(-Speed_Control) ;

} Speed_Now_Old = Speed_Now ;

Speed_Want_Old = Speed_Want ;

Speed_I_Number_Old = Speed_I_Number ;

Speed_Time = 0 ;

Speed_Number = 0 ;

Speed_I_Number = 0 ;

FTM_QUAD_clean(FTM2);

Bias_old = Bias;

Bias1_old = Bias1;

} } void Suspension_Control(void) { Yao_Speed = Speed_Now / 6 ;

if(Steering_Data >

Centre_Number) { Yao_Steering = (Steering_Data - Centre_Number) / yao_R11;

//右 Yao_Data = Yao_Centre + Yao_Steering ;

} else { Yao_Steering = (Centre_Number - Steering_Data) / yao_L11;

// 左 Yao_Data = Yao_Centre - Yao_Steering ;

} Yao_Max = Yao_Centre + (Steering_Max - Centre_Number) / yao_R11;

Yao_Min = Yao_Centre - (Centre_Number - Steering_Min) / yao_L11;

if(Yao_Data >

Yao_Max) Yao_Data = Yao_Max ;

if(Yao_Data <

Yao_Min) Yao_Data = Yao_Min ;

Steer_Suspension_Control(Yao_Data);

if(Enter_Obstacle_L1 >

0) { Steer_Suspension_Control(Yao_Max) ;

} if(Enter_Obstacle_R1 >

0) { Steer_Suspension_Control(Yao_Min) ;

} } void Car_Stop(void) { Speed_Now = FTM_QUAD_get(FTM2);

if((Speed_Now >

5) &&

(Speed_Now <

200)) Motor_Fan_Control(150) ;

else Motor_Zheng_Control(0) ;

} void Ren_Discriminate(void) { byte i , k ;

byte line1 , line2 , line3 , line4 ; 50 for(i = Centre_Ren ;

i >= 4 ;

i --) { if(CCD_Ren[i + 2] - CCD_Ren[i - 3] >= Black_White_Compare ) { line1 ++ ;

if(line1 >= 2) { Ren_LX = i ;

break ;

} } else line1 = 0 ;

} if(line1 <

2) Ren_LX = 4 ;

for(k = Centre_Line ;

k <= 123 ;

k ++) { if(CCD_Ren[k - 2] - CCD_Ren[k + 3] >= Black_White_Compare ) { line2 ++ ;

if(line2 >= 2) { Ren_RX = k ;

break ;

} } else line2 = 0 ;

} if(line2 <

2) Ren_RX = 123 ;

Centre_Ren = (Ren_LX +Ren_RX) ;

Centre_Ren = Centre_Ren / 2 ;

for(i = (Ren_LX) ;

i >= 4 ;

i --) { if(CCD_Ren[i] >

(CCD_Ren[i + 3] + Black_White_Compare)) { line3 ++ ;

if(line3 >= 2) break ;

} else line3 = 0 ;

} for(k = (Ren_RX) ;

k <= 123 ;

k ++) { if(CCD_Ren[k] >

(CCD_Ren[k - 3] + Black_White_Compare)) { line4 ++ ;

if(line4 >= 2) break ;

} else line4 = 0 ;

} if(line4 >= 2) Ren_R_Width = k - Ren_RX ;

else Ren_R_Width = 0 ;

if(line3 >= 2) Ren_L_Width = Ren_LX - i ;

else Ren_L_Width = 0 ;

if((Ren_L_Width >

10) &&

(Ren_L_Width <

40) &&

(Ren_L != 1) &&

(Ren_R != 1) ) Enter_Ren_R1 ++ ;

else Enter_Ren_R1 = 0 ;

if((Ren_R_Width >

10) &&

(Ren_R_Width <

40) &&

(Ren_L != 1) &&

(Ren_R != 1) ) Enter_Ren_L1 ++ ;

else Enter_Ren_L1 = 0 ;

if(((RX - Ren_R_Old) >

10) &&

(LX <

50) &&

(LX >

4) &&

(Ren_L != 1) &&

(Ren_R != 1) &&

(RX >

118)) Enter_Ren_R2 = 35 ;

if(((Ren_L_Old - LX) >

10) &&

(RX >

80) &&

(RX <

120) &&

(Ren_L != 1) &&

(Ren_R != 1) &&

(LX <

7)) Enter_Ren_L2 = 35 ;

if(Enter_Ren_R2 >

0) Enter_Ren_R2 -- ;

if(Enter_Ren_R3 >

0) Enter_Ren_R3 -- ;

if(Enter_Ren_L2 >

0) Enter_Ren_L2 -- ;

if(Enter_Ren_L3 >

0) Enter_Ren_L3 -- ;

if(Ren_L_Delay >

0) Ren_L_Delay -- ;

if(Ren_R_Delay >

0) Ren_R_Delay -- ; 52 if((Enter_Ren_R1 >

1) &&

(Enter_Ren_R2 >

0) &&

(Ren_L != 1)) { Ren_R = 1 ;

Ren_R_Delay = Ren_R_Delay_CNT ;

Enter_Ren_L1 = 0 ;

Enter_Ren_L2 = 0 ;

Enter_Ren_R1 = 0 ;

Enter_Ren_R2 = 0 ;

} if((Enter_Ren_L1 >

1) &&

(Enter_Ren_L2 >

0) &&

(Ren_R != 1)) { Ren_L = 1 ;

Ren_L_Delay = Ren_L_Delay_CNT ;

Enter_Ren_L1 = 0 ;

Enter_Ren_L2 = 0 ;

Enter_Ren_R1 = 0 ;

Enter_Ren_R2 = 0 ;

} if(Ren_L == 1) { if((RX <

60) &&

(Ren_L_Delay == 0)) { Ren_L = 0 ;

} } if(Ren_R == 1) { if((LX >

70) &&

(Ren_R_Delay == 0)) { Ren_R = 0 ;

} } Ren_L_Old = LX ;

Ren_R_Old = RX ;

} void Speed_Want_Control(void) { if(Steering_Data >

Centre_Number) { Speed_Add_R = 0 ;

Speed_Add_L ++ ;

} else { Speed_Add_R ++ ;

Speed_Add_L = 0 ;

} if((Speed_Add_L >

2)) { Speed_Want = Speed_Data - Speed_Minus * (Steering_Data - Centre_Number) / 800 ;

Speed_Minus_D = Jue_Dui_Zhi((LX + RX) , 128) - Jue_Dui_Zhi((I_Old_Line + K_Old_Line) , 128) ;

if(Speed_Minus_D >

0) Speed_Want = Speed_Want - Speed_Minus_D * 10 ;

else Speed_Want = Speed_Want - Speed_Minus_D * 4 ;

if(Speed_Want >

Speed_Data) Speed_Want = Speed_Data;

if(Speed_Want <

(Speed_Data - Speed_Minus)) Speed_Want = Speed_Data - Speed_Minus ;

Straight_Long = 0 ;

} else if ((Speed_Add_R >

2)) { Speed_Want = Speed_Data - Speed_Minus * (Centre_Number - Steering_Data) / 800 ;

Speed_Minus_D = Jue_Dui_Zhi((LX + RX) , 128) - Jue_Dui_Zhi((I_Old_Line + K_Old_Line) , 128) ;

if(Speed_Minus_D >

0) Speed_Want = Speed_Want - Speed_Minus_D * 10 ;

else Speed_Want = Speed_Want - Speed_Minus_D * 4 ;

if(Speed_Want >

Speed_Data) Speed_Want = Speed_Data;

if(Speed_Want <

(Speed_Data - Speed_Minus)) Speed_Want = Speed_Data - Speed_Minus ;

Straight_Long = 0 ;

} else { Speed_Want = Speed_Data;

} } 54 void Speed_Steering_Control(void) { Steer_Direction_Control(Steering_Data) ;

Steer_CCD_Control(Steering_CCD) ;

if((Ren_L == 1) &&

(Enter_Ramp3 == 0)) { Steer_Direction_Control(Steering_Min) ;

Steer_Suspension_Control(Yao_Min - 200);

Steer_CCD_Control(12000) ;

Steering_CCD = 12000 ;

if(A >

8) A=8;

Enter_Ren_Speed_L = 15 ;

} else if((Ren_R == 1) &&

(Enter_Ramp3 == 0)) { Steer_Direction_Control(Steering_Max) ;

Steer_Suspension_Control(Yao_Max + 200);

Steer_CCD_Control(8000) ;

Steering_CCD = 8000 ;

if(A >

8) A=8;

Enter_Ren_Speed_R = 15 ;

} if(Enter_Ramp3 >

0) { if((LX + RX) >

115 &&

(LX + RX) <

140) { Steer_Direction_Control(Steering_Data) ;

Steer_CCD_Control(Steering_CCD) ;

} else { Steer_Direction_Control(Centre_Number) ;

Steer_CCD_Control(CCD_Centre) ;

Steering_CCD = CCD_Centre ;

} Speed_Want = 110 ;

} if(Enter_Ren_Speed_L >

0) { Speed_Want = 80 ;

Enter_Ren_Speed_L -- ;

} if(Enter_Ren_Speed_R >

0) { Speed_Want = 80 ;

Enter_Ren_Speed_R -- ;

} } void { PID_Compute(void) Steering_PP_1 = (int)(64 - Centre_Line) * (64 - Centre_Line) / 6 ;

Steering_PP_2 = Steering_PP_1 * steer_PP;

PP_DATA1 = (int)(64 - Centre_Line) * (64 - Centre_Line) / 6 ;

PP_DATA2 = Steering_PP_1 * CCD_PP;

if(64 - Centre_Line >

0) Steering_Data_PP = Steering_PP_2 / 20 ;

else Steering_Data_PP = -Steering_PP_2 / 20 ;

if(64 - Centre_Line >

0) PP_DATA = PP_DATA2 / 20 ;

else PP_DATA = -PP_DATA2 / 20 ;

Steering_Data_P = (64 - Centre_Line) * steer_P / 10 ;

P_DATA = (64 - Centre_Line) * CCD_P / 10 ;

Steering_Data_D = (int)((LX + RX - I_Old_Line - K_Old_Line ) * steer_D)/10;

D_DATA = (int)((LX + RX - I_Old_Line - K_Old_Line ) * CCD_D)/10;

Number_I = Number_I + 128 - LX - RX ;

Steering_Data_I = (int)(Number_I * steer_I) /100;

Steering_PPP_1 = (128 - LX - RX) * (128 - LX - RX) * (128 - LX - RX) * steer_PPP ;

Steering_PPP = Steering_PPP_1 / 500 ;

Steering_Data = Centre_Number - Steering_Data_P + Steering_Data_D - Steering_Data_I Steering_Data_PP - Steering_PPP - Steering_CCD_Old ;

if(Steering_Data >

Centre_Number) Steering_Data = Steering_Data + (Steering_Data - Centre_Number) / you11 ;

if(Steering_Data >= Steering_Max) Steering_Data = Steering_Max ;

if(Steering_Data <= Steering_Min) Steering_Data = Steering_Min ; 56 Steering_CCD =CCD_Centre + P_DATA - D_DATA + PP_DATA ; if(Steering_CCD >

(Steering_CCD_Old + CCD_Centre + 70)) Steering_CCD = Steering_CCD_Old + CCD_Centre + 70 ;

if(Steering_CCD <

(Steering_CCD_Old + CCD_Centre - 70)) Steering_CCD = Steering_CCD_Old + CCD_Centre - 70 ;

if(Steering_CCD >= CCD_Max) Steering_CCD = CCD_Max ;

if(Steering_CCD <= CCD_Min) Steering_CCD = CCD_Min ;

} void Obstacle(void) { if(((LX_Old + RX_Old) <

200) &&

((LX_Old + RX_Old) >

55) &&

(Keep_L_Line == 0) &&

(Keep_R_Line == 0)) { if(Obstacle_Number <

10 ) Obstacle_Number ++ ;

} else Obstacle_Number = 0 ;

if(Obstacle_Number >

200) Obstacle_Number = 200 ;

if((Obstacle_Number >

10)) Obstacle_Delay = 20 ;

if(Obstacle_Number == 10) { if(((LX - LX_Old) >

10) &&

(Jue_Dui_Zhi(RX , K_Old_Line) <

7) /*&&

(Enter_Obstacle_R == 0) &&

(RX - LX <

50)*/ &&

(RX <

115) /*&&

(I_Old_Line >

10)*/) Enter_Obstacle_L1 = 25 ;

if(((RX_Old - RX) >

10) &&

(Jue_Dui_Zhi(LX , I_Old_Line) <

7) /*&&

(Enter_Obstacle_L == 0) &&

(RX - LX <

50)*/ &&

(LX >

15) /*&&

(K_Old_Line <

120)*/) Enter_Obstacle_R1 = 25 ;

} if(Enter_Obstacle_L1 >

0) Enter_Obstacle_L1 -- ;

if(Enter_Obstacle_R1 >

0) Enter_Obstacle_R1 -- ;

if(((LX_Old - LX) >

10) &&

(Enter_Obstacle_L1 >

0)) Enter_Obstacle_L1 = 2 ; if(((RX - RX_Old) >

10) &&

(Enter_Obstacle_R1 >

0)) Enter_Obstacle_R1 = 2 ;

if(Ramp_Delay >

0) { Enter_Obstacle_R1 = 0 ;

Enter_Obstacle_L1 = 0 ;

} if(Enter_Obstacle_L1 >

0) Centre_Number = 10390 ;

else if(Enter_Obstacle_R1 >

0) Centre_Number = 8890 ;

else Centre_Number = 9640 ;

LX_Old = LX ;

RX_Old = RX ;

} void STOP_ID(void) { if(STOP_EN == 0) { if(STOP_ID_Delay_CNT == 0) StartLine_ID() ;

} Outside_STOP();

} void StartLine_ID(void) { if(ee <

60) { Stop_EE = 1 ;

Car_Stop_Delay_2 = 10 ;

} if(dd <

60) { Stop_DD = 1 ;

Car_Stop_Delay_2 = 10 ;

} if(ff <

60) { Stop_FF = 1 ;

Car_Stop_Delay_2 = 10 ;

} 58 if(rr <

60) { Stop_RR = 1 ;

Car_Stop_Delay_2 = 10 ;

} if(Car_Stop_Delay_2 >

0) Car_Stop_Delay_2 -- ;

if(Car_Stop_Delay_2 == 0) { Stop_EE = 0 ;

Stop_FF = 0 ;

Stop_DD = 0 ;

Stop_RR = 0 ;

} if((((Stop_FF == 1) &&

(Stop_DD == 1)) || ((Stop_EE == 1) &&

(Stop_DD == 1)) || ((Stop_FF == 1) &&

(Stop_EE == 1))|| ((Stop_EE == 1) &&

(Stop_RR == 1)) || ((Stop_FF == 1) &&

(Stop_RR == 1)) || ((Stop_RR == 1) &&

(Stop_DD == 1))) &&

(Stop_Car_Shi == 0) &&

(Stop_Car_Wan == 0)) STOP_Flag = 1 ;

if((Stop_Car_Wan >

0) || (Stop_Car_Shi >

0)) { Stop_EE = 0 ;

Stop_DD = 0 ;

Stop_FF = 0 ;

Stop_RR = 0 ;

} }

校:杭州电子科技大学 队伍名称:杭电光电3队 参赛队员:刘 勇 常玉锋 叶建明 带队教师... 没有他们的支持,我们的车模绝对上不了赛场,更不用说在浙江赛区有的良 好发挥. 其...

杯智能汽车竞赛浙江赛区暨第三届浙江省大学生智能汽车竞赛,在浙江理工大学下沙校区... 名列第三;由常玉峰、叶建明、常云洋等同学组成的“杭电光电3队”获得光电组第六名...

O谢谢~ 第五届智能车_总决赛_光电组_杭州电子科技大学 第五届智能车_总决赛_光电组_... WELCOME To HDU 2010年亚运会啦啦操徐娜罢赛浙江赛区杭州电子科技大学啦啦队 我...

浙江赛区-光电组-杭州电子科技大学-杭电光电3队,杭电电子科技大学,电子科技大学光电学院,电子科技大学光电信息》出自:QQ空间素材网
链接地址:http://www.qzoneai.com/sucai/tlNCGHBAIBsVu0Kp.html

网站地图 | 关于我们 | 联系我们 | 广告服务 | 免责声明 | 在线留言 | 友情链接 | RSS 订阅 | 热门搜索
版权所有 QQ空间素材网 www.qzoneai.com

浙江赛区-光电组-杭州电子科技大学-杭电光电3队,杭电电子科技大学,电子科技大学光电学院,电子科技大学光电信息