简 介: 本文以第十六届全国大学生智能车竞赛为背景,介绍了 AI视觉四轮智能车系统的软硬件结构和开发流程。采用大赛组委会指定的 C型车模,以恩智浦 32位微控制器 MIMXRT1064最小系统板作为核心控制单元,在 IAR开发环境中进行软件开发,使用 MT9V032摄像头以及电感进行赛道信息采集。我们对小车的机械结构,硬件设计,软件编程方面进行了深入的研究。多次尝试改变小车的机械结构,深入考虑衡量硬件 PCB的布局,走线等。软件采用多种算法结合,核心为摄像头循迹与电磁 PID控制结合的算法,实现拥有较强鲁棒性的寻迹小车。我们独立完成了控制方案及系统设计,包括电磁信号采集处理、赛道图像信号采集处理、循迹控制算法及执行、动力电机驱动、十分类神经网络训练、靶标图片识别、单片机之间通信等,最终实现了具有 AI视觉功能的基于电磁与摄像头的快速寻迹智能车控制系统。
智能车是一个软硬件与机械相结合的整体,其中硬件主要包括电源模块、电机驱动模块、速度测量模块、图像采集处理模块、电磁传感模块、舵机控制模块和单片机模块等;软件主要包括单片机初始化程序、速度测量程序、速度设定程序、速度控制程序、舵机控制程序、元素识别程序等方面的内容,使用 Matlab进行了大量的数据分析以及上位机的设计调试,确定了现有的机械结构和相关控制参数。
关键词
: 智能车,MIMXRT1064,MT9V032摄像头,电感
队伍名称:会飞的车
参赛队员:杨一鹤 薛梦晴 梁金桐
带队教师:张林 贾存良
引言
全国大学生智能汽车竞赛以 “立足培养、重在参与、鼓励探索、追求卓越”为宗旨,是一项鼓励创新的科技竞赛活动。智能车设计内容涵盖了控制、模式识别、传感技术、汽车电子、电气、计算机、机械等多个学科的知识,对学生的知识融合和实践动手能力的培养,具有良好的推动作用。竞赛要求在规定的汽车模型平台上,使用微控制器作为核心控制模块,通过增加道路传感器、电机驱动模块以及编写相应控制程序,制作完成一个能够自主识别道路的模型汽车。
智能汽车竞赛 AI视觉组别,要求采用第十六届全国大学智能汽车竞赛的 C型车模,采用恩智浦 32位微控制器 MIMXRT1064最小系统板作为核心控制单元,主频为 600MHZ。我们对小车的机械结构,硬件设计,软件编程方面进行了深入的研究。多次尝试改变小车的机械结构,深入考虑衡量硬件 PCB的布局,走线等。软件采用多种算法结合,核心为摄像头循迹与电磁 PID控制结合的算法,实现小车鲁棒性较强的寻迹。我们独立完成了控制方案及系统设计,包括电磁信号采集处理、赛道图像信号采集处理、循迹控制算法及执行、动力电机驱动、十分类神经网络训练、靶标图片识别、单片机之间通信等,最终实现了具有 AI视觉功能的基于电磁与摄像头的快速寻迹智能车控制系统。
本次报告主要介绍摄像头智能车硬件电路及车模机械的设计方案,以及软件控制系统建立的方式方法。
第一章 车模机械设计
智能车能够稳定的运行,良好的机械性能是必不可少的,机械安装的布局、质量将影响到道路信息的探测效果以及车子的拐弯转向、加减速效果。只有整体把握好之后,才能对细节进行有效处理。前期我们花了一定时间去研究车模的安装,摄像头的选择,电感的安装,以及其他硬件安装方案的实验,大体上确定了车模的机械架法和硬件上的芯片选型, PCB布局等。中期是软件调试为主,同时完善硬件,实践证明在机械上的优化对软件的调车有很大的推动作用。后期软件算法已经确定,硬件上也比较稳定。正是这种对智能车精益求精的追求,使得我们的智能车有了比较可靠得稳定性。本章将介绍根据实际情况对车模机械做出的改进。
1.1前轮定位调整
四轮智能车出现直线走偏、转弯费力、轮胎磨损快等情况时大多与轮胎安装角度有关,涉及到一个非常重要的转向轮位置角度定位问题,叫做“前轮定位”。它的作用是保障智能车直线运行时的稳定性,使其转向轻便并减少轮胎的磨损。前轮是转向轮,它的安装位置由主销内倾、主销后倾、前轮内倾和前轮前束等四个项目决定,反映了转向轮、主销和前轴等三者在车架上的位置关系。
1.1.1主销后倾角
在汽车纵向平面内,主销轴线上端略向后倾斜,这种现象称为主销后倾。在纵向垂直平面内,主销轴线与垂线之间的夹角叫主销后倾角,其值大小对汽车转向与操纵性能密切相关。设置主销后倾角后,主销中心线的接地点与车轮中心的地面投影点之间产生距离,使车轮的接地点位于转向主销延长线的后端,车轮就靠行驶中的滚动阻力被向后拉,使车轮的方向自然朝向行驶方向。设定很大的主销后倾角可提高直线行驶性能,同时主销纵倾移距也增大。但主销纵倾移距过大,会使转向沉重,而且路面干扰会加剧车轮的前后颠簸。
1.1.2主销内倾角
从车前后方向看轮胎时,主销轴向车身内侧倾斜,该角度称为主销内倾角。当车轮以主销为中心回转时,车轮的最低点将陷入路面以下,但实际上车轮下边缘不可能陷入路面以下,而是将转向车轮连同整个车模前部向上抬起一个相应的高度,这样车模本身的重力有使转向车轮回复到原来中间位置的效应,因而车模容易回正。
▲ 图 1主销内倾角
1.1.3前轮外倾
从前后方向看车轮时,轮胎并非垂直安装,而是稍微倾倒呈现 “八”字形张开,称为负外倾,而朝反方向张开时称正外倾。车模一般将外倾角设定得很小,接近垂直。若设定大外倾角会使轮胎磨偏,降低轮胎摩擦力。
1.1.4前轮前束
四轮定位前束值脚尖向内,所谓 “内八字脚 ”的意思,指的是左右前轮分别向内。采用这种结构目的是修正上述前轮外倾角引起的车轮向外侧转动。如前所述,由于有外倾,转向变得容易。另一方面,由于车轮倾斜,左右前轮分别向外侧转动,为了修正这个问题,如果左右两轮带有向内的角度,则正负为零,左右两轮可保持直线行进,减少轮胎磨损。在智能车程序基本完整,可以完成各类赛道元素后,根据实际情况对前轮定位进行调整。通过改变上横梁垫片的数目,增大后倾角。在智能车长期调试后,发现适当增大内倾角,可使转弯时车轮和地面有更大的接触面积,继而增大车与地面的摩擦程度,使车转向更灵活,减小因摩擦不够而引起的转向不足的情况。
1.2摄像头安装调整
本车模采用 MT9V032摄像头采集赛道信息。摄像头的安装方式是否稳固合理,是其能否采集到优质图像的关键。经过多次尝试调整,最终使用一根碳素杆搭架摄像头的方式,以减轻可能产生的不必要的重量。使用螺母将摄像头支撑杆底部固定在车模中轴线上,保证与车身保持垂直。同时,碳素杆固定在车身左右中心位置,使车模转向时不存在水平分量,保证图像的稳定性。
▲ 图 2摄像头安装效果图
1.3编码器安装调整
为使智能车能够平稳地沿着赛道运行,需要对车速进行精确控制,使赛车在急转弯时速度不至过快而冲出赛道。理论上,通过控制驱动电机上的平均电压即可控制智能车速度,但是如果开环控制电机转速,会受很多因素影响,例如电池电压、电机传动摩擦力、道路摩擦力和前轮转向角度等。这些因素会造成赛车运行不稳定,需要检测出智能车当前速度。通过速度检测,对车模速度进行闭环反馈控制,即可消除上述各种因素的影响,使得车模运行得更稳定。本次使用 mini编码器,根据车模自身实际结构,自行制作了编码器的安装结构件,使编码器使用时不对电池的安装产生影响。在使用时注意到,编码器容易受到静电或连接松动的影响,所以需要对编码器进行保护,在编码器各连接处进行加固处理,防止以上情况发生。
▲ 图 3编码器安装效果图
1.4电感的安装
传感器是电磁组小车最重要的模块之一,能够对变化的磁场信号作出敏的检测,对道路状况的检测起着至关重要的作用。谐振电路产生感应电流,再通过滤波、放大、检波,然后将结果送入单片机 AD进行相应的处理,以判断赛道当前信息。传感器的排布,直接影响了对磁场的敏感程度,针对直道和弯道的磁场特点,在传感器的排布上,分别有对其敏感的检测电感,以适应各种情况的赛道要求。
▲ 图 4电感安装效果图
1.5智能视觉模块安装
因为本届赛道添加了数字动物水果标靶, AprilTag码等元素,所以我们队在传统的车模上自主添加了智能视觉模块模块,采用 UART实现智能视觉与主控芯片的通信,用以实现数字和水果 /动物的分类与小车控制。使用两个数字舵机 M3512D,控制摄像头旋转,摄像头旋转至合适位置,使用带有可调透镜的微型激光器发射激光,触发打靶装置。激光器输出功率为 5mW。
此外,起跑线检测直接使用干簧管。当干簧管处于磁铁上方时,干簧管导通从而产生下降沿,信号送到单片机引发单片机外部中断。
▲ 图 5智能视觉模块安装效果图
1.6整车效果图
▲ 图 6整车效果图
第二章 硬件系统设计
2.1主控板
▲ 图 7主控板
主控板对称布置,每个电源网络均设置 LED显示各个供电芯片是否正常工作,减少故障排查时间,其中包括主 3.3V,5V,总钻风摄像头 3.3V和舵机可调稳压。根据各个传感器的车身分布位置合理安排接口位置,为减轻质量同时使电路板简洁,同时主控板四个角采用圆角的形式,美观且防止划伤手指,四个固定孔的位置与底座空隙相吻合,固定孔周围没有元器件,这样防止了铜柱安装时压坏元件。
2.1.1主控芯片
采用逐飞科技制作的恩智浦 32位微控制器 MIMXRT1064最小系统板作为核心控制单元,主频相较 K66大大提高,达到了 600MHZ,省去了在主控板上为主控芯片布线的工作,弊端是占据了主控板更多的空间。核心板通过插针与主板相连,这样防止了因主板故障而无法使用核心板的问题。
▲ 图 8主控芯片
2.1.2电源管理模块
电源模块主要分为四部分,分别是舵机可调电源, 5V部分,主 3.3V部分和总钻风摄像头供电 3.3v,摄像头单独拥有 3.3v供电是为防止主 3.3v供电稳压芯片因通过电流过大而发热严重。这是四个部分将电池电压转换为对应电压,为车模各个部分供电。
5V电压使用的是 SY8205FCC稳压芯片,稳定且不易发烫,首先给核心板供电,此外还为 uart串口和激光接口提供电压,保证 OPENARTmini模块和激光头供电正常。
主3.3V电压是保证 OLED模块、运算放大器、编码器、超声波模块等的供电需求,并对一些模块提供上拉,我们采用 RT9013-33芯片将 5V转换为 3.3V较为稳定。
总钻风摄像头 3.3v单独供电,使其电压稳定充足,响应更快。
舵机可调电路是将 7.2V电池电压,转换到舵机可用电压,一般为 5-6V,为不损伤舵机且响应尽量块通常是调至接近舵机的最大工作电压 6v,这里使用的仍是高性能的稳压芯片 SY8205FCC,通过电位器调节输出电压。
在隔离方面由于 AI视觉组的舵机使用较多,容易在工作时对其他模块产生影响,故通过 0欧姆电阻分割地的方法将舵机 GND和其他模块的 GND分割隔离。
▲ 图 9舵机稳压电路
▲ 图 105V稳压电路
▲ 图 11总钻风摄像头 3.3v稳压电路
2.1.3蜂鸣器模块
我们采用蜂鸣器来帮助我们对某些判别条件触发时有更加直观的感受,方便更改参数。
▲ 图 12蜂鸣器电路
2.2驱动板
使用 H桥驱动原理采用 DRV8701芯片和 MOS管进行正反双向驱动,并利用 74HC125PW与主板隔离,有效保护核心板。
▲ 图 13驱动电路隔离部分
▲ 图 14驱动电路驱动部分
▲ 图 15驱动板
2.3运放板
采用 opa4377芯片放大四路信号,通过调节电位器来改变放大倍数。
▲ 图 16运放电路
▲ 图 17运放板
2.4电感板
将五个电感的走线集成在电感板中,使车模更加美观,信号更不易干扰。
▲ 图 18电磁模块
▲ 图 19电感采集板正面
▲ 图 20电感采集板背面
第三章 软件系统设计及实现
稳定的程序是智能车高速平稳自动寻线的基础。本设计的智能车采用 CMOS摄像头进行图像的采集和二值化,图像的采集和赛道信息的提取是整个程序的核心部分,只有在提取到正确信息的情况下我们才能对智能车作出精确有效的控制。而在智能车的转向和速度控制方面,参考往届的经验,使用了鲁棒性很好位置式 PID控制算法,配合使用理论计算和动态参数补偿的办法,使智能车能够稳定快速寻线并作出相应的控制。
3.1图像处理部分
3.1.1赛道边缘提取
在单片机采集图像信号后需要对其进行处理以提取主要的赛道信息,同时,由于交叉道、起点线的存在,光线、杂点、赛道远处图像不清楚的干扰,图像效果会大打折扣。因此,在软件上必须排除干扰因素,对赛道进行有效识别,并提供尽可能多的赛道信息供决策使用。
▲ 图 21摄像头采集回传图像
3.1.2赛道信息分析与处理
中心线提取算法的基本思想如下:
1) 直接逐行扫描原始图像,根据硬件二值化结果直接提取出边界坐标;
2) 图像数据量大,全部扫描一遍会浪费很多时间,利用前面已经求出的中线位置判断出中线的趋势,从而推断出下一行的中线大概位置,确定出扫描范围,避免整行逐点扫描,节省时间。求中线时,因为近处的中线稳定,远处中线不稳定,所以采用由近及远的办法;根据上一行的左右两边的坐标,确定本行的边线扫描范围。在确定的赛道宽度范围内提取有效赛道,这样可以滤除不在宽度范围内的干扰;
3) 根据采集到的赛道宽度,判断是否采集为真正赛道,滤除噪点造成的影响;
4) 图像是远处小近处大,所以赛道宽度范围和前后行赛道中心的位置差别都要动态调整;
5) 比较左右赛道边界坐标的大小,判断赛道的有效性;
3.1.3坡道处理
坡道在扫描到特征的那几行,赛道宽度都会突变得特别明显,坡道的赛道宽度突变后不会突变回来,起跑线只是 2-3行有明显的赛道宽度变小。据这个特征,当检测到坡道时,目标速度降低,使得小车不会因为速度太快而飞起来,小车通过 PID控制,快速通过坡道。
▲ 图 22坡道图
3.2舵机控制
智能车是一个复杂的非线性系统, PID控制的应用十分广泛。但是有很多不确定因素,导致传统的 PID算法在智能车转弯方面并不能很好的应用,会出现入弯过慢,出现出弯不正等现象,为了让智能车在转弯时表现出更加优秀的运动性能,通过将 PID控制中去掉 I项来加快系统的响应速度,并将二次函数曲线结合 PD算法来优化路径,使得小车过弯更加流畅。通过测试发现用 PD控制来控制舵角可以取得较好的效果。将图象经过算法处理后得到的黑线位置和对应的舵机 PD参照角度处理成一次线性关系。在 Ki置零的情况下,舵机在这种动态随动系统对动态响应性能要求更高。更重要的是,通过合理调节 Kp参数,发现车能在直线高速行驶时仍能保持车身非常稳定,没有震荡,所以基本没有必要使用 Ki参数。
3.3速度控制
要想智能车以最短的时间跑完整个赛道,不但要求优越的方向控制算法,让智能车尽量走更近的路,转更少的弯。而且对于速度控制算法也有很高的要求,智能车在行驶过程中,不能够完全匀速,在直道上应该提速,而在弯道上应该减速。在智能车沿着既定轨迹行驶的过程中,速度不能够恒定不变,而应该根据道路的具体形状进行适当的调整。当然,最好的方法是让智能车始终以最快的速度通过整个赛道,但是如果速度始终调得太高,当小车遇到急弯或者是圆道时必然无法转过来,就会冲出赛道。因此不能够始终给最快的速度。然而,如果速度调得始终过低,就无法以最短的时间通过赛道。因此,速度应该要随着检测到的道路形状变化而变化。例如当前方道路为直道或类似直道时,应该将 PWM波提得最高,让通过主电机的电流达到最大,从而让智能车以最快的速度行驶。当进入弯道时,应该将 PWM波降到最低,让通过主电机的反向电流达到最大,从而让智能车以最短的时间将速度降到理想状态。
赛道中的直道,是方向控制中最好处理的一种情况,因为只要小车没有偏离赛道,就可以不进行偏转,而当智能车偏离赛道时也只需要一个较小的偏转,让智能车能缓慢回归赛道就可以了,具体的方法是计算扫描到图像中线偏离赛道中线的平均值和中线的斜率,再将这两个数分别乘上各自的比例系数,加上舵机偏向中心位置时需要给出的高电平的值,作为 PWM波的高电平送入给舵机,就可以实现直道上的智能车方向控制了。
3.3.1大弯的方向控制算法
在道路中遇到大弯时需要转弯,转向角只受弯道的弯曲程度影响,但是距离大弯多远就开始转弯却需要受到当前速度的影响,因为舵机在转向时有一定的延时,舵机转 60度大约需要 140毫秒,而智能车的最快速度可以达到 10米/ 秒,如果智能车当时运行的速度就是 10米/秒,那么当舵机转过 60度时智能车已经走过 1米多了,所以不能等到了弯道才开始转弯,而是需要提前转弯,而且速度越快,越是要提前得多,所以智能车转弯提前多少就由速度控制,用比例控制就能收到很好的效果,而转弯时转多少却仅仅受弯道的弯曲程度控制,弯曲程度越大,转向角就也越大,弯曲程度越小,转向角也就越小。具体的对应关系通过实验获得,在此没有列举出具体的数据。
3.3.2急弯的方向控制算法
急弯的方向控制算法与大弯的方向控制算法相似,也是需要提前转弯,而且提前多少转弯也要受当前速度的控制,速度越大,越要提前转弯,转向角也是用弯道的弯道程度来决定的,急弯比大弯的弯曲程度更加大,因此需要的转向角也要相应增大。急弯的方向控制比大弯更难,很可能出线,因此在急弯的方向控制时更应多加注意。
3.3.3“小 S型”道的方向控制算法
“小 S型”道一般是指“ S型”道弯曲角度小于等于 60度形成来回转向,智能车过这种弯道时,基本可以从中间直接通过,而不需要转弯和减速。因此,找准 “小 S型”道的正中心显得至关重要,因为只有找准了“小 S型”道的正中心,智能车才能不转弯不减速地通过 “小 S型”道,如果“小 S型”道的正中心找得不准,那么智能车就很容易冲出赛道。找 “小 S型”道的正中心的方法为:先找出“小 S型”道最左边和最右边的坐标值,然后将最左边和最右边的坐标值相加之后再除以 2,就得到了“小 S型”道的正中心坐标,智能车就可以沿着这个方向前进,而不需要转弯。但是,由于 CMOS图像传感器扫描到的图像可能出线误差,那么智能车就有可能产生误判,而冲出赛道。因此为了保险起见,必须当 “小 S型”道足够小时,才能采用直接冲的办法。
3.4智能车程序流程图
▲ 图 23智能车程序流程图
3.5 PID算法
3.5.1PID控制算法简介
PID控制是工程实际中应用最为广泛的调节器控制规律。问世至今 70多年来,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。
▲ 图 24单位反馈的 PID控制原理框图
单位反馈 e代表理想输入与实际输出的误差,这个误差信号被送到控制器,控制器算出误差信号的积分值和微分值,并将它们与原误差信号进行线性组合,得到输出量 u。
其中,
KP为比例增益, KP与比例带 δ成倒数关系即 KP=1/δ, TI为积
分时间常数, TD为微分时间常数, u(t)为控制量, e(t)为偏差。
3.5.2增量式 PID控制算法
增量式 PID是指数字控制器的输出只是控制量的增量 Δu(k)。采用增量式算法时,计算机输出的控制量 Δ u(k)对应的是本次执行机构位置的增量,而不是对应执行机构的实际位置,因此要求执行机构必须具有对控制量增量的累积功能,才能完成对被控对象的控制操作。执行机构的累积功能可以采用硬件的方法实现;也可以采用软件来实现,如利用算式程序化来完成。由式可得增量式 PID控制算式
u(k)=u(k-1)+u(k)
Δu(k)=u(k)-u(k-1)=Kp[Δe(k)-e(k-1)]+Kie(k)+Kd[Δe(k)-2Δe(k-1)-e(k-2)]代码实现:
motor_duty=last_motor_duty+motor_kp*(speed_pc[0]-speed_pc[1])+motor_kispeed_pc[0]+motor_kp(speed_pc[0]+speed_pc[2]¬2*speed_pc[1]);
增量式 PID具有以下优点:
1) 由于计算机输出增量,所以误动作时影响小,必要时可用逻辑判断的方法关掉。
2) 自动切换时冲击小,便于实现无扰动切换。此外,当计算机发生故障时,由于输出通道或执行装置具有信号的锁存作用,故能保持原值。
3) 算式中不需要累加。控制增量△ u(k)的确定仅与最近 k次的采样值有关,所以较容易通过加权处理而获得比较好的控制效果。在使用过程中我们发现传统的增量式 PID,车速控制不及时 ,容易超调 ,积分饱和。最终我们选择的是增量式的 PID,能够很好的满足智能车的加减速以及停车问题。
3.5.3经典 PID算法实现速度控制的具体实现
我们对速度的控制采用了增量式 PID算法。该算法的基本策略是急弯降速,直道和小弯提速,由于我们的摄像头扫描到的范围较宽,所以在过急弯道时可以提前减速,先把扫描到的图像进行处理,然后得出经过反复实验,将图像经过算法处理后得到的黑线位置和对应的速度 PID参照速度处理成二次曲线的关系。在实际测试中,发现小车直道和弯道相互过度时加减速比较灵敏,与舵机转向控制配合较好。但是,存在的局限一方面是车在弯道进直道后的加速和直道入弯道的速度控制并达不到最好的控制效果,弯道入直道减速不够快速,直道入弯道加速得时机也不够及时。我们做了进一步的改进,根据入弯时中线位置的特点动态改变二次曲线中最高点(直道的最高速度)和最低点(弯道的最低速度)的大小,使得控制效果更合理。
第四章 AI视觉部分
4.1任务概述
4.1.1.数字识别
在三岔路口需要对路口处的数字进行识别,并根据数字的奇偶性,来决策应该走左边还是走右边。
4.1.2.AprilTag识别
AprilTag是一个视觉基准库,在 AR,机器人,相机校准领域广泛使用。设定为与二维码相似但相对更简单的特定标志,实现快速检测。
在赛题中 AprilTag码也代表着数字,依然通过识别其所代表的数字,并判断奇偶性来得知靶标牌是在赛道的哪一侧。
4.1.3.物体识别
赛题中包含动物图案和水果图案,动物类包含狗、猫、马、猪、牛五个子类别,水果类包含苹果、橘子、葡萄、香蕉、榴莲五个子类别,图案对象均为全身或整体照片。
如果路边目标牌上的图案属于动物类,则车模需要在二维码所在的区域(前后 50厘米)内不少于 3秒钟,方能驶出车模停止区域。如果路边目标牌上的图案属于水果类,则车模需要使用激光发射器对准靶点中心发送一束激光,激发目标靶响应。
4.2基于卷积神经网络的图像识别的实现
待检测图片内部只包含其中一种物体,不涉及多物体检测。其次待检测图片背景不复杂,全图只有待检物体本身,降低背景噪声的引入对分类模型的影响。待检测物体及其靶标如图 25所示。
根据任务分别设计两个十分类的模型,用来实现数字和水果 /动物的分类。实现流程相似,主要包括制作数据集,搭建神经网络,模型训练,模型量化,硬件实现五个模块,实现流程如图 26所示。
▲ 图 25靶标正面照
▲ 图 26卷积神经网络实现图像识别流程用
到的模块和包的版本如表 1:
用到的包版本号
4.2.1收集数据及预处理
训练模型之前,我们需要先采集数据然后才能开始训练模型 .需要安装任务分别采集数字与动物水果的照片。采集数据共有三种方法。
1. 通过爬虫程序网上下载需要的图片,爬虫程序虽然能很快下载大量的图片,但是存在图片质量低的问题,会下载很多错误的图片,需要手动删除掉。
2. 在网站上人工筛选符合要求的图片,然后一张一张的下载下来,比较费时费力。
3. OpenARTmini模块拍照并保存图片在 SD卡,这种方法图片质量高,符合实际情况。
针对数据集不够的问题,主要解决方法是数据增广。用于增加训练数据集,使得训练的模型具有更强的泛化能力。需要根据自己的数据集特征来确定应该使用哪几种数据增广方式,主要包括:水平翻转,旋转,缩放,噪声等。图 27是根据要求制作的原图,图 28是数据增广后的数据集部分截图,图 29是拍摄的部分图片。
▲ 图 27原始图像
▲ 图 28原始图像数据增强部分后样本
▲ 图 29摄像头拍摄图像数据增强后部分样本
▲ 图 30文件夹分类命名为 0-9
使用以上方法生成的图片保存在十个文件夹,命名为 0-9。编写脚本从 Picture文件夹读取图片并转换为数据集,生成 x.npy和 y.npy两个文件。部分代码图 27所示。
▲ 图 31读取图片转换为 npy文件
设计模型进行训练之前,要进行数据预处理。在进行深度神经网络训练时,一般要求输入的数据范围在 (-1,1)或(0,1)之间。对数据拆分 ,将其划分为 80%的训练集与 20%测试集,训练集用于模型自身迭代,测试集用于诊断模型能力。然后,对数据进行归一化处理,并通过 to_categorical函数将标签数据转换为 one-hot码.本设计要训练一个 10分类的网络,那么要将标签(图片所对应的类别号)转换为长度为 10,并且仅有其所对应的类别号的位置的数据为 1,其余均为 0,这样一组 n维向量就被称为 one-hot码,以方便网络进行迭代学习。
4.2.2搭建神经网络
Keras是一个用 python编写的深度学习 API,在机器学习平台 Tensorflow上运行,换句话说他以 Tensorflow为后端,作为神经网络的推理引擎。最近的 Tensorflow也“高清复刻“了 Keras的 API。Keras的 API非常直奔主题,可以让人尽快地将构想转变为结果,简化研究过程。正如官网对他的评价:简单,灵活,强大。本设计采用的 Keras2.2.4版本以及 Tensorflow1.14.0版本,用到的库、模块和函数如表 2.
表 2用到的库、模块和函数 Keras有两种排布的方式,一种是 Sequential方式,一种是 Function方式。前者像是串冰糖葫芦,每一个都是一个单独的个体,小兵之间是顺序排列的,不能前后颠倒,不能互通有无。而 Function方式,像是各自组队,可以一起也可以分开,但是最终还是一个整体,简单的说, Sequential方式使用简单,但是,只能搭建那些串行网络。而 Function方式,则可以根据不同需求,进行排列布阵,形成各种各样的阵型,搭配到一起使用,就像是编程时候用到的函数。
本设计将主要采用 Sequential模型构建模式,相对来说, 0-9数字数据集颜色特征很少,数据集数目小,因此搭建一个具有 3层卷积和 1层全连接的简单卷积神经网络 3Conv+1Dense的 CNN。如图 30所示,该卷积神经网络的中间层采用 rule激活函数,输出层采用 softmax激活函数。
在动物 /水果十分类任务中,每一类原始图片分别有 100张左右,经过数据集增广至每类 2000张左右,总共 2万张左右。同样搭建一个具有 3层卷积和 1层全连接的简单卷积神经网络,该卷积神经网络的中间层采用 rule激活函数,输出层采用 softmax激活函数。与数字分类不同的是,如图 31所示,每个激活层前面添加 BatchNormalization层,使训练过程更加稳定,提高训练速度,并且减少过拟合。在池化层后面加 dropout层,随机丢弃一部分中间特征,防止模型过拟合。
4.2.3模型训练
优化器负责模型的调优,学习率( lr)的设置有讲究,过大的学习率会提高模型的学习速度,但是太大了可能反而适得其反,还可能会导致模型无法得到最优解;而过小的学习率,会导致训练速度过慢,陷入局部最优不能自拔,选择上要进行试错调整,这里选择 opt = Adam(lr=0.001)。这里的评价标准,选择 categorical_crossentropy,这也是专门适用于多分类问题的损失函数。这里的 epochs代表总共迭代遍历数据集多少多少次, batch_size为一次迭代需要使用多少数据。小了能让模型迭代快,但是训练效果容易震荡,还妨碍学到全局特征;大了能让学习过程更平稳,但模型收敛效率会下降,还可能陷入局部最优。回调函数 ModelCheckpoint负责模型的保存,会将训练过程中遇到的最好结果即时保存下来。数字分类模型训练部分代码如图 32所示。
▲ 图 32 3*Conv+1*Dense的 CNN(数字任务)
▲ 图 33模型训练
训练好的模型用可视化模型结构工具 Netron进行查看。本设计搭建的网络模型如图 34、图 35所示。
▲ 图 34Netron可视化数字分类网络模型结构
▲ 图 35可视化动物 /水果分类网络模型结构
4.2.4模型量化
神经网络模型权重的多少往往直接反映出一个模型的复杂程度,而权重越大,模型的效果一般会更加好。 MCU的计算资源和存储资源都远不能和 PC相比,在 PC端可以良好运行的 AI模型在 MCU上运行有很大困难。出于这一目的,模型量化技术应运而生。而量化又分为训练中量化,以及训练后量化。在模型训练时需要较高精度的权重,这样才能精准地降低损失值,但是在模型预测时没有这个要求,所以本设计选择训练后进行模型量化。训练后量化技术可以理解成一种有损压缩,会损失一点精度,但是,会显著降低模型尺寸,同时提高运行效率。量化的原理其实很简单。模型在训练时一般是使用 float32类型来存储的,每一个权重数据需要占用 4个字节,模型的推理改用 int8,这样,每存储一个权重,将只消耗 1个字节,模型的尺寸会缩小为之前的 1/4,而且这样对精度的影响通常极小,只要是在可接受的范围内,我们就降低了模型的存储尺寸。而且,目前神经网络加速器或是神经网络加速库,一般只支持 int8类型的数据输入,对 float类型无能为力。模型小也大大减轻了对存储器系统和 Cache的压力。这样一来,在减小了模型尺寸的同时,还可以加速模型的运行。本设计借用 NNCU模型转换器,其 GUI界面如图 36所示。
▲ 图 36NNCU模型转换器
4.2.5实现结果
模型文件已经量化完毕,接下来我们量化之后的模型文件放入 OpenART mini中跑起来。实现步骤的流程图如下图 37。
▲ 图 37模型载入流程图
运行模型进行模型预测,识别到带黑框的图片后可通过串行终端界面看到提示数据。实现结果表明,识别准确度较高与实时性较好,模型运行效果良好。实现结果如图 38至图 42图像所示。
▲ 图 38水果识别正确示例 -葡萄
▲ 图 39水果识别正确示例 -香蕉
▲ 图 40动物识别正确示例 -猪
▲ 图 41动物识别正确示例 -马
图 42分类错误,结果正确示例本设计分别对 0-9数字图片和十种水果动物进行识别,实际测试中调整合适光照以及图片大小,识别的准确率如下表 3所示。
▲ 表 3数据集及其识别准确率
4.3AI识别控制算法
利用上文提到的 openmvIDE,采用 python编程控制 openartmini模块及其外设。任务实现流程图如图 43所示。
▲ 图 43任务实现流程图
4.3.1识别 AprilTag
AprilTag的家族为 TAG25H9,包含 0-34共35个数字,只需识别 0-9。首先制作AprilTag,直接从 OpenMV的IDE里生成。如图所示。
▲ 图 44TAG25H9 0-9
由于 openartmini模块自带识别 AprilTag库函数,调用函数即可识别。
4.3.2舵机控制
伺服电机通常被称为舵机,它是一种带有输出轴的小装置。向伺服器发送一个控制信号时,输出轴就可以转到特定的位置。只要控制信号持续不变,伺服机构就会保持轴的角度位置不改变。如果控制信号发生变化,输出轴的位置也会相应发生变化。
我们使用了两个数字舵机,设定舵机频率均为 200HZ,控制信号来自 openartmini模块给出的两个 PWM信号。下方舵机实际控制角度范围为 180°,用于改变摄像头方向,以便寻找待识别图像。上方舵机的控制信号保持不变,作用是稳定摄像头支架。
4.3.3激光发射器
使用带有可调透镜的微型激光器,输出功率为 5mW。调整光斑直径至合适大小。条件触发后, openartmini模块给出时长 1.2s,频率 100HZ、占空比 50%的控制信号。激光发射器发射激光至靶心,即可认为打靶成功。
第五章 仿真与调试
要想将所设计的算法运用到智能小车上,并很好的控制智能小车的各个机构协调工作,并不是一蹴而就的事情,必须经过初期的设计、仿真、制作和长期的调试工作。而这一系列工作也是反复循环进行的,在调试过程中对设计方案进行修改,然后重新仿真制作后再进行新一轮的调试。
5.1 IAR在线调试
程序开放在 IAR Embedded Workbench IDE下进行, Embedded Workbench forARM是 IAR Systems公司为 ARM微处理器开发的一个集成开发环境 (下面简称 IAR EWARM)。比较其他的 ARM开发环境, IAR EWARM具有入门容易、使用方便和代码紧凑等特点。 EWARM中包含一个全软件的模拟程序 (simulator)。用户不需要任何硬件支持就可以模拟各种 ARM内核、外部设备甚至中断的软件运行环境。从中可以了解和评估 IAR EWARM的功能和使用方法。 IAR EWARM中包括集成开发环境 IDE、处理器专家、全芯片仿真、可视化参数显示工具、项目工程管理、 C交叉编译器、汇编器、链接器以及调试器。其中在本设计中重要的部分就是集成开发环境和调试器, IAR软件自带在线调试功能,在下载器下载完成后可以对智能车的各个参数进行直观准确的观察。
5.2MATLAB数据处理
MATLAB是矩阵实验室( Matrix Laboratory)的简称,是美国 MathWorks公司出品的商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括 MATLAB和 Simulink两大部分。本次主要使用 MATLAB完成数据的可视化处理以及算法仿真。通过蓝牙串口将需要观测的数据发至电脑,使用 MATLAB进行绘图处理。根据采集到的数据进行相关参数的整定。
5.3按键及液晶辅助调试
调试赛车是比赛的重要一环。为了调试方便,设计了按键加 OLED的方案。这样一来,可以通过 OLED屏幕很方便地观看车模运行参数及摄像头看到的路面图像,方便对路况进行人工分析并采用按键和拨码开关的方式及时调整,使得车模可在赛场上快速切换速度模式以适应比赛。
▲ 图 46按键液晶调试
5.4串口通信调试
openartmini模块与主控单片机进行串口通信。先初始化串口,波特率设置为115200,设置发送和接受信息引脚。可以发送接受字符串、列表、多种进制数等信息。我们选择双方传递信息的形式为十六进制数据, openartmini模块发送信息使用 uart.write()函数,接受信息使用 uart.read()函数。
实际测试时,先使用串口转 TTL模块在电脑端进行测试,使用串口助手界面如下,简单大方,满足测试需求。后续测试与主控单片机能够进行正常通信。
▲ 图 47串口助手调试界面
第六章 心得总结
报名参加“恩智浦杯”智能汽车竞赛,我们遵循学习知识第一,志同道合友谊第一,比赛获奖第二的原则。
设计制作过程中,通过小组成员的努力思考与实践,以及学长比赛的经验,我们有了基本思路,包括机械,电路,以及最重要的控制上的创新思想。机械方面我们的特色在于轮胎与舵机转向结构在传感器布局。对于电感 ,我们采用传统的电感排布方法。在电路方面,有 RT1064主控模块、电机驱动模块、电源模块、传感器模块、放大电路、辅助模块。这六个模块分别设计,不同成员负责不同部分,比较芯片优异和构造合适电路。最终确定现在的电路。
在控制方面,我们使用比赛推荐的开发工具调试程序,充分利用上位机等工具以提高效率经过小组成员不断研讨、争论、改进,终于设计出三套适用于不同情况下的,稳定的程序。
在几个月的准备中,在场地、经费方面都的到了学校和学院的大力支持,在此特别感谢一直支持和关注智能车比赛的学校和学院领导以及各位老师。同时也感谢比赛组委会能组织这样一项很有意义的比赛。
这段历程,我们一同熬过无数个日夜,熟悉了彼此也成长了自己。从走时关灯到天亮了记得把灯,关上实验室就像我们另一个家。这段经历将永伴我们一生。比赛很艰辛 ,但我们享受其中的快乐,受益匪浅,智能车竞赛的历程会成为我们最珍贵的回忆。
参考文献
[1]卓晴 ,黄开胜 ,邵贝贝等编 .学做智能车 —挑战 “飞思卡尔 ”杯[M].北京 :北京航空航天大学出版社 ,2007.
[2]谭浩强著. C程序设计 [M].北京:清华大学出版社, 2003.
[3]童诗白,华成英.模拟电子技术基础 [M].北京 :高等教育出版社, 2001.
[4]黄开胜,金华民,蒋狄南,韩国智能模型车技术方案分析 [J],电子产品世界 .
[5] [5]邓惜仁 ,宋学树 .基于 PID算法和 ABS点杀思想的智能车高速行驶研究 [J].软件 , 2013, 34(5):60-63.
[6]何西海 ,胡延忠 . (1997).汽车主销后倾角内倾角测量原理分析 [J].汽车实用技术 (4), 15¬17.
[7]雷贞勇 ,谢光骥 .飞思卡尔智能车舵机和测速的控制设计与实现 [J].电子设计工程 , 2010
[8]张男 ,毛琼 . PID模糊控制器的设计及在智能车转向控制上的应用 [J].科技风 , 2012
[9]汪波 .智能小车避障与路径优化研究 [D].重庆理工大学 ,2015.
[10]阿斯顿•张 ,李沐 ,扎卡里• C.立顿 ,亚历山大• J.斯莫拉 .动手学深度学.http://zh.d2l.ai/chapter_preface/preface.html#
[11]卓晴、逐飞科技、恩智浦等公众号文章
■ 附录控制程序代码
/*****************编码器初始化 *****************函数: voidencoder_init(void)功能:编码器初始化参数:无
*/ voidencoder_init(void) {
qtimer_quad_init(QTIMER_1,QTIMER1_TIMER0_C0,QTIMER1_TIMER1_ C1);
qtimer_quad_init(QTIMER_1,QTIMER1_TIMER2_C2,QTIMER1_TIMER3_ C24);//初始化编码器 } /*****************速度测量 *****************函数: voidspeed_measure(void)功能:测量实时速度,两个轮的平均速度编码器采集值,参数:无说明:该函数可以测出速度返回值:
*/ voidspeed_measure(void) {
real_speed =(qtimer_quad_get(QTIMER_1,QTIMER1_TIMER2_C2)¬
qtimer_quad_get(QTIMER_1,QTIMER1_TIMER0_C0))/2;//测速 qtimer_quad_clear(QTIMER_1,QTIMER1_TIMER0_C0); qtimer_quad_clear(QTIMER_1,QTIMER1_TIMER2_C2); //清零
distance+=real_speed*0.0105; //测距离化为厘米为单位 0.0085 }
/*********************速度 PI*********************/ staticfloatSpeedErrorInteg =0; //偏差积分 floatI_Calculate=0;//积分 I计算值 floatP_Calculate=0;//比例 P计算值 staticint8separate=1; //积分分离系数 floatSpeed_P_I_Control(float *PID,int16speed, int16set_speed)//因为角度
变化小,需要是浮点型
{ float SpeedControlOut;//最终计算量 int16SpeedError; //当前误差
staticuint8k; staticfloat PreError[10]={0}; SpeedError =set_speed -speed; //计算速度偏差 SpeedErrorInteg=0; //误差积分 for(k=9;k>0;k--) //20次误差( --比++快) {
PreError[k]=PreError[k-1]; SpeedErrorInteg+=PreError[k]; } PreError[0]=SpeedError; SpeedErrorInteg+=PreError[0];//积分项
I_Calculate =separate *PID[KI] *SpeedErrorInteg; //积分 I计算值
P_Calculate=PID[KP]*SpeedError;//比例 P计算值
///////////////////// if(SpeedError<0)//超速, {
SpeedControlOut=0;
///SpeedControlOut=-5; } else {
SpeedControlOut =P_Calculate+I_Calculate; //最终输出
} return SpeedControlOut; }
/********************电机初始化 ***************函数: voidinit_PWM(void)参数:无说明:
*/ voidinit_PWM(void) {
gpio_init(D0,GPO,0,GPIO_PIN_CONFIG); gpio_init(D1,GPO,0,GPIO_PIN_CONFIG);
pwm_init(PWM2_MODULE3_CHA_D2,17*1000,0);
pwm_init(PWM2_MODULE3_CHB_D3,17*1000,0); } /****************************电机输出 **********************函数: voidgo_motor (int16left_PWM,int16right_PWM)参数: int16left_PWM,int16right_PWM说明: */ #defineDuty_Max 40000 int32motor1,motor2;//两个变量控制转速 ;motor1(右轮 );motor2(左轮 ) voidgo_motor (int32PWM_Duty) {
motor1=motor2=PWM_Duty; if(motor1>0) {
gpio_set(D0,0);
pwm_duty(PWM2_MODULE3_CHA_D2,motor1); } else {
gpio_set(D0,1);
pwm_duty(PWM2_MODULE3_CHA_D2,-motor1); } if(motor2>0) {
gpio_set(D1,0); pwm_duty(PWM2_MODULE3_CHB_D3,motor2);
} else {
gpio_set(D1,1); pwm_duty(PWM2_MODULE3_CHB_D3,-motor2); }
} floatPID_Realize(PID *sptr,float *PID, int32NowData,int32Point) {
//当前误差,定义为寄存器变量,只能用于整型和字符型变量,提高运
算速度 int32iError; //当前误差 float Realize; //最后得出的实际增量
iError =Point -NowData; //计算当前误差设定减当前 sptr->SumError+= PID[KI] *iError;//误差积分 sptr->SumError = limit(sptr->SumError,PID[KT]);//积分限幅
Realize =PID[KP] *iError
+sptr->SumError
+PID[KD] *(iError -sptr->LastError); //PI D相加 sptr->PrevError =sptr->LastError; //更新前次误差 sptr->LastError =iError; //更新上次误差 sptr->LastData = NowData; //更新上次数据没用 */ if(NowData<100&&NowData>-100) {
Realize=Realize+20000; }
returnRealize;//返回实际值 } int32PID_Increase(PID *sptr,float *PID, int32NowData, int32Point) {
//当前误差,定义为寄存器变量,只能用于整型和字符型变量,提高运算速度 int32iError, //当前误差 Increase; //最后得出的实际增量
iError =Point -NowData; //计算当前误差
Increase = PID[KP] *(iError -sptr->LastError)
+PID[KI] *iError
+PID[KD] *(iError -2*sptr->LastError + sptr->PrevError);
sptr->PrevError =sptr->LastError; //更新前次误差 sptr->LastError =iError; //更新上次误差 sptr->LastData = NowData; //更新上次数据
returnIncrease; //返回增量
} int16Cubic_Function(int16DATE,floatA,float B) {
int16Final_Date; Final_Date =(DATE*DATE*DATE)*A+DATE*B; return Final_Date;
}
////////去除极值求平均 int16I_Median_Average_Filter(int16 *DATE) {
uint8i; int16max,min; //定义极值以及和 int16sum =0;
max =DATE[0]; min =DATE[0];
for(i=0;i<sizeof(DATE);i++)
{ if(max<DATE[i])max =DATE[i]; if(min>DATE[i])min = DATE[i]; sum+= DATE[i];
}
sum =(sum-max-min)/(sizeof(DATE)-2); //>>3 returnsum; }
● 相关图表链接:
- 图 1主销内倾角
- 图 2摄像头安装效果图
- 图 3编码器安装效果图
- 图 4电感安装效果图
- 图 5智能视觉模块安装效果图
- 图 6整车效果图
- 图 7主控板
- 图 8主控芯片
- 图 9舵机稳压电路
- 图 105V稳压电路
- 图 11总钻风摄像头 3.3v稳压电路
- 图 12蜂鸣器电路
- 图 13驱动电路隔离部分
- 图 14驱动电路驱动部分
- 图 15驱动板
- 图 16运放电路
- 图 17运放板
- 图 18电磁模块
- 图 19电感采集板正面
- 图 20电感采集板背面
- 图 21摄像头采集回传图像
- 图 22坡道图
- 图 23智能车程序流程图
- 图 24单位反馈的 PID控制原理框图
- 图 25靶标正面照
- 图 26卷积神经网络实现图像识别流程用
- 图 27原始图像
- 图 28原始图像数据增强部分后样本
- 图 29摄像头拍摄图像数据增强后部分样本
- 图 30文件夹分类命名为 0-9
- 图 31读取图片转换为 npy文件
- 图 32 3Conv+1Dense的 CNN(数字任务)
- 图 33模型训练
- 图 34Netron可视化数字分类网络模型结构
- 图 35可视化动物 /水果分类网络模型结构
- 图 36NNCU模型转换器
- 图 37模型载入流程图
- 图 38水果识别正确示例 -葡萄
- 图 39水果识别正确示例 -香蕉
- 图 40动物识别正确示例 -猪
- 图 41动物识别正确示例 -马
- 表 3数据集及其识别准确率
- 图 43任务实现流程图
- 图 44TAG25H9 0-9
- 图 46按键液晶调试
- 图 47串口助手调试界面