智能车竞赛技术报告 | 智能车视觉 - 西北工业大学 - 赤霄2021

举报
tsinghuazhuoqing 发表于 2021/12/26 01:17:14 2021/12/26
【摘要】 学 校:西北工业大学    队伍名称:赤霄2021      参赛队员:武锦辉 龙俊旺 石钰莹带队教师:曲仕茹 胡深奇       第一章 引言 ■ ...

学 校:西北工业大学    
队伍名称:赤霄2021      
参赛队员:武锦辉 龙俊旺 石钰莹
带队教师:曲仕茹 胡深奇    

 

第一章


■ 1.1 大赛介绍

  为加强大学生实践、创新能力和团队精神的培养,促进高等教育教学改革, 2005年10月受教育部高等教育司委托(教高司函[2005]201号文),教育部高等学校自动化专业教学指导分委员会(2013年已更名为“教育部高等学校自动化类专业教学指导委员会”,以下简称自动化教指委)创办了全国大学生智能汽车竞赛,并被教育部批准列入国家教学质量与教学改革工程资助项目(教高司函[2010]13号文)。在2020年转为中国自动化学会作为主办单位。

  该竞赛以智能汽车为研究对象的创意性科技竞赛,是面向全国大学生的一种具有探索性工程实践活动,是教育部倡导的大学生科技竞赛之一。该竞赛以“立足培养,重在参与,鼓励探索,追求卓越”为指导思想,旨在促进高等学校素质教育,培养大学生的综合知识运用能力、基本工程实践能力和创新意识,激发大学生从事科学研究与探索的兴趣和潜能,倡导理论联系实际、求真务实的学风和团队协作的人文精神,为优秀人才的脱颖而出创造条件。

  该竞赛由竞赛秘书处为各参赛队提供/购置规定范围内的标准硬软件技术平台,竞赛过程包括理论设计、实际制作、整车调试、现场比赛等环节,要求学生组成团队,协同工作,初步体会一个工程性的研究开发项目从设计到实现的全过程。该竞赛融科学性、趣味性和观赏性为一体,是以迅猛发展、前景广阔的汽车电子为背景,涵盖自动控制、模式识别、传感技术、电子、电气、计算机、机械与汽车等多学科专业的创意性比赛。该竞赛规则透明,评价标准客观,坚持公开、公平、公正的原则,保证竞赛向健康、普及、持续的方向发展。

  该竞赛以英飞凌半导体公司、江苏国芯科技有限公司为协办方,得到了教育部相关领导和各高校师生的高度评价,已发展成全国30个省市自治区近300所高校广泛参与的全国大学生智能汽车竞赛。2008年起被教育部批准列入国家教学质量与教学改革工程资助项目中科技人文竞赛之一(教高函[2007]30号文)。

  全国大学生智能汽车竞赛原则上由全国有自动化专业的高等学校(包括港、澳地区的高校)参赛。竞赛首先在各个分赛区进行报名、预赛,各分赛区的优胜队将参加全国总决赛。

  本届比赛分为基础四轮、节能信标、电磁越野、双车接力、全向行进、单车拉力、专科基础和智能视觉组八个竞速赛题组。本文主要介绍基于智能视觉组赛题的智能车系统设计与制作,从机械设计、硬件设计、软件设计三大方面进行阐述。

■ 1.2 智能视觉组任务要求

  对于智能视觉组,规定使用C型车模,车模尺寸不限。车模中微控制器使用NXP系列单片机,推荐使用i.MX RT系列的任意一款单片机。允许使用摄像头、电感、红外光电、激光传感器等器件进行赛道和环境检测。竞赛车模从车库出发沿着赛道运行两周,然后返回车库。车模需要分别通过三岔路口两条岔路。比赛时间从车模驶出车库到重新回到车库为止。在车模行进过程中,需要完成以下两种任务:

  1)选择三岔路口。在三岔路口中心前方放置一个靶标牌,上面有0 ~ 9单个数字。在车模出发后,由现场裁判员随机确定靶标牌上的数字。车模行进到三岔路口时,需要根据数字的奇偶特性判断左边路口还是右边路口。

  • 若为偶数(0、2、4、6、8),选择左侧路口;
  • 若为奇数(1、3、5、7、9),选择右侧路口。

  该任务示意图如图1.1所示。

▲ 图1.1 选择三岔路口任务示意图

▲ 图1.1 选择三岔路口任务示意图

  2)路边目标识别与定位。在赛道某一区域(直线或者弯道)中心放置AprilTag25h9二维码图片。根据二维码对应数字,分别在赛道左侧,或者右侧,二维码前后50厘米范围内放置靶标牌。其中,偶数表示以AprilTag指向的左侧放置靶标牌,奇数表示以AprilTag指向的右侧放置靶标牌。

  靶标上张贴有两类物品的图案:动物图案和水果图案。其中动物类包括狗、猫、马、猪、牛等,动物图案包含有动物全身照片;水果类包括苹果、橘子、葡萄、香蕉、榴莲等,水果图案包括有水果整体照片。

  如果路边目标牌上的图案属于动物类,则车模需要在二维码所在的区域(前后50厘米)内不少于3秒钟,方能驶出车模停止区域。

  如果路边目标牌上的图案属于水果类,则车模需要使用车载小型激光发射器对准靶点中心发送一束激光,激发目标靶响应。靶心检测激光束的范围是直径为5厘米的圆形区域,激光点落在靶心便可以触发目标靶位的响应。

  该任务示意图如图1.2所示。

▲ 图1.2 路边目标识别与定位任务示意图

▲ 图1.2 路边目标识别与定位任务示意图

■ 1.3 系统设计框架

  系统以检测电磁场信号、赛道图像信号为基础,通过单片机处理信号并实现对车体控制,实现车体能够准确沿着预设路径巡迹运行。系统电路部分包括电源管理系统电路、电机驱动电路、舵机驱动电路、电磁运放电路等;外部传感器设备包括用于获取赛道信息的摄像头、用于测速的编码器、用于获取车身姿态的陀螺仪、用于打靶的激光发射模块、用于调试的无线串口模块、用于人机交互的TFT屏幕和按键等;此外还有用于固定电池、电路板和各类传感器器件的机械装置。综上所述,本智能小车系统包含了以下模块:

  1. 单片机最小系统模块(NXP i.MX RT1064单片机)
  2. 电机驱动模块
  3. 舵机转向模块
  4. 摄像头传感器模块
  5. 电磁运放模块
  6. 编码器测速模块
  7. 陀螺仪模块
  8. OpenART模块
  9. 激光发射模块
  10. 云台模块
  11. 调试模块
  12. 人机交互模块

  系统框架图如图1.3所示。

▲ 图1.3 系统框架图

▲ 图1.3 系统框架图

 

第二章 统机械设计说明


2.1 系统机械设计参数要求

  本届竞赛中,智能视觉组别的要求如下:

  1. 车模要求:车模使用C型车模。车模作品尺寸不限。
  2. 微控制器要求:车模中微控制器使用NXP系列单片机,推荐使用i.MX RT系列的任意一款单片机。
  3. 传感器要求:允许使用摄像头、电感、红外光电、激光传感器等。

2.2 系统机械整体参数调校

  智能车的整体参数,包括车体重心、传感器排布方式等,都对整个智能车系统的稳定运行起着至关重要的作用。因此,对智能车机械系统的调节,有助于智能车速度上的提升。智能车的布局以要尽可能的精简和牢固,通过对车上传感器及电路板的合理布局,尽量保证整车重心应靠近整车的几何中心,使得车模的四个轮胎都有良好的抓地能力,提升车模整体运动能力。

  智能车整体机械布局图如图2.1所示。

▲ 图2.1 智能车整体机械布局图

▲ 图2.1 智能车整体机械布局图

2.3 云台安装

  云台的作用为控制摄像头的转向和激光发射的方向。云台通过3D打印设计与实现,前后共设计了3版。
  第一版,设计如图2.2所示。

▲ 图2.2 云台ver.1

▲ 图2.2 云台ver.1

  该设计方案为将舵机云台放置在智能车转向舵机的上方,由于该方案会使激光与OPENART无法放置在较低的位置,且整体靠前,不利于转向、打靶等动作的完成,因此放弃该方案 。

  第二版,设计如图2.3所示。

▲ 图2.3云台ver.2

▲ 图2.3云台ver.2

  该设计方案将视觉任务的舵机后移,下方不再有转向舵机,因此高度可调范围增大。但由于仅由两个铜柱与车身固定,智能车在行进的过程中舵机云台会有较大的晃动,这对视觉任务与行进任务都是不利的。综合考虑后,改善并确定了方案。

  第三版,在第二版的基础上增加了两个螺孔,使用4根铜柱将云台与车身连接,效果明显改善,智能车机械结构稳定性增强。如图2.4所示。

▲ 图2.4 云台ver3

▲ 图2.4 云台ver3

  考虑到激光左右打靶任务的对称性,设计3D打印件使激光能固定在碳素杆正前方,确定好任务后,用热熔胶固定。3D打印件设计如图2.5所示。

▲ 图2.5 激光器固定件

▲ 图2.5 激光器固定件

  最终,云台安装如图2.6所示。

▲ 图2.6 云台安装

▲ 图2.6 云台安装

2.4 电池及PCB安装

  PCB板用三根铜柱固定在车身前部,电池通过3D打印件固定在车身后侧,更加牢固同时方便更换。如图2.7所示。

▲ 图2.7 电池与PCB版安装

▲ 图2.7 电池与PCB版安装

2.5 本章小结

  机械结构是智能车的基础,其首先决定了智能车的性能,特别是转向和加速性能,本章主要通过对转向机构的分析以及对汽车理论知识的学习和应用,找到了影响小车转向范围和效率的因素并进行了改进,使得小车的转向灵敏度得到提高,同时电机差速效率也得到较大提高。此外还针对智能视觉组的任务要求,对电磁传感器、云台等硬件的布局进行合理规划。

 

第三章 统硬件电路设计说明


3.1 单片机最小系统模块

  基于NXP i.MX RT1064核心的单片机最小系统是本智能车的核心。图3.1为NXP i.MX RT1064核心板示意图。

▲ 图3.1 NXP i.MX RT1064核心板

▲ 图3.1 NXP i.MX RT1064核心板

  3.2 电源管理系统
  本智能车系统由一块2S锂电池进行供电。智能车系统各硬件组成部分分别需要5V、3.3V以及6V的电压供电。

  核心板、OPENART模块、OPENMV模块以及电磁传感模块需要5V的电压供电。在该硬件电路设计中,为避免各模块之间相互干扰,使用三块LP38692MP-5.0稳压芯片产生5V稳压。

  摄像头模块、TFT彩屏、人机交互模块、蜂鸣器、激光、信号缓冲芯片、编码器、无线串口以及陀螺仪需要3.3V的供电。其中,摄像头模块通过RT9013-33GB稳压芯片供电,这是因为本基于RT1064单片机的系统需要严格的上电次序,在单片机内核启动成功后才能给外设上电。单片机的CR引脚在内核启动成功后会变为高电平,再经过3.3V LDO输入RT9013-33G的使能引脚。除摄像头外,用一块LP38692MP-3.3供电。

  舵机部分需要6V的供电 ,该硬件系统设计了三个舵机,考虑到之后智能车性能提升的需要,选用了两片可调节输出电压的LM2941SX稳压芯片,分别给三个舵机供电。

  电源管理系统如图3.2所示。

▲ 图3.2 电源管理系统

▲ 图3.2 电源管理系统

3.3 传感器模块

  传感器是小车最重要的模块之一。本系统主要使用摄像头模块作为主传感器,辅以OpenART模块、OpenMV模块、编码器测速模块、陀螺仪模块等作为辅传感器。经过考虑后,没有使用电磁运放模块。

3.3.1 摄像头模块

  本系统使用逐飞总钻风MT9V034灰度传感器作为摄像头模块。摄像头模块接口原理图如图3.3所示。

▲ 图3.3 摄像头模块接口原理图

▲ 图3.3 摄像头模块接口原理图

3.3.2 OpenART模块

  OpenART是实现智能视觉组别AI任务的核心,其与主控之间通过UART接口进行通讯,该硬件电路共引出三个OpenART模块,接口原理图如图3.4所示。

▲ 图3.4 OpenART模块接口原理图

▲ 图3.4 OpenART模块接口原理图

3.3.3 OpenMV模块

  为了提高识别的准确性,除OpenART模块外,辅以OpenMV模块,其与主控的通信方式也是UART通信,接口原理图如图3.5所示。

▲ 图3.5 OpenMV模块接口原理图

▲ 图3.5 OpenMV模块接口原理图

3.3.4 编码器测速模块

  本小车使用逐飞1024线、带方向输出的光电编码器进行小车的测速。处理器通过读取编码器脉冲数来实现小车速度的检测,通过读取编码器旋转方向脚的高低电平来检测电机的正反转。其接口原理图如图3.6所示。

▲ 图3.6编码器测速模块接口原理图

▲ 图3.6编码器测速模块接口原理图

3.3.5 陀螺仪模块

  陀螺仪模块可获取车模的角速度和加速度,可辅助进行元素识别和运动控制。其接口原理图如图3.7所示。

▲ 图3.7陀螺仪模块接口原理图

▲ 图3.7陀螺仪模块接口原理图

3.4 电机驱动模块

  电机采用BTN8982芯片,构成完整的全桥驱动分别控制两个电机,可以很好实现电机的正转、反转和刹车制动。其电路原理图如3.8所示。

▲ 图3.8 电机驱动模块原理图

▲ 图3.8 电机驱动模块原理图

3.5 人机交互模块

  为了方便调试,本车有无线串口模块,通过UART通信方式进行通讯和传输数据。除此之外,主板还设置了按键、拨码开关和TFT显示屏,以方便控制参数的修改,便捷地进行智能车的调试。各模块原理图如图3.9所示。

▲ 图3.9 人机交互模块

▲ 图3.9 人机交互模块

3.6其他外设模块

3.6.1蜂鸣器模块

  蜂鸣器模块通过MOS管与主控的IO口连接,可进行调频实现各种效果。蜂鸣器模块接口原理图如图3.10所示。

▲ 图3.10 蜂鸣器模块

▲ 图3.10 蜂鸣器模块

·3.6.2激光模块

  激光模块用来实现任务中的打靶部分,由于裁判系统要求激光具有一定的频率,因此通过MOS管令激光与主控的I/0口连接,实现125Hz的调频。激光模块接口原理图如图3.11所示。

▲ 图3.10 蜂鸣器模块

▲ 图3.10 蜂鸣器模块

3.7 PCB板整体布局

 

第四章 统软件设计说明


4.1 AI任务部分

4.1.1 AI任务介绍

  本届竞赛,智能视觉组别在车模行进过程中,需要完成两种任务,分别为三岔路口选择和路边目标识别与定位。

  1)选择三岔路口。在三岔路口中心前方放置一个靶标牌,上面有0 ~ 9单个数字。在车模出发后,由现场裁判员随机确定靶标牌上的数字。车模行进到三岔路口时,需要根据数字的奇偶特性判断左边路口还是右边路口。

  • 若为偶数(0、2、4、6、8),选择左侧路口;
  • 若为奇数(1、3、5、7、9),选择右侧路口。

  该任务示意图如图4.1所示。

▲ 图4.1 选择三岔路口任务示意图

▲ 图4.1 选择三岔路口任务示意图

  2)路边目标识别与定位。在赛道某一区域(直线或者弯道)中心放置AprilTag25h9二维码图片。根据二维码对应数字,分别在赛道左侧,或者右侧,二维码前后50厘米范围内放置靶标牌。其中,偶数表示以AprilTag指向的左侧放置靶标牌,奇数表示以AprilTag指向的右侧放置靶标牌。

  靶标上张贴有两类物品的图案:动物图案和水果图案。其中动物类包括狗、猫、马、猪、牛等,动物图案包含有动物全身照片;水果类包括苹果、橘子、葡萄、香蕉、榴莲等,水果图案包括有水果整体照片。

  如果路边目标牌上的图案属于动物类,则车模需要在二维码所在的区域(前后50厘米)内不少于3秒钟,方能驶出车模停止区域。

  如果路边目标牌上的图案属于水果类,则车模需要使用车载小型激光发射器对准靶点中心发送一束激光,激发目标靶响应。靶心检测激光束的范围是直径为5厘米的圆形区域,激光点落在靶心便可以触发目标靶位的响应。
  该任务示意图如图4.2所示。

▲ 图4.2 路边目标识别与定位任务示意图

▲ 图4.2 路边目标识别与定位任务示意图

  其中,三岔路口选择任务需要针对阿拉伯数字进行识别,路边目标识别与定位任务则包含AprilTag码识别、动植物图案识别和激光打靶三个环节。故智能视觉组别的AI任务可细分为以下四个任务:数字识别与处理、AprilTag码识别与处理、动植物图案识别与处理、激光打靶处理。

4.1.2 神经网络模型部署

  根据智能视觉组赛题要求,本届比赛中的数字识别与处理任务、动植物图案识别与处理任务都需要使用神经网络模型进行部署实现。对于图像识别,由竞赛规则可知所用到的图像均为全身或是整体图片,可以得到以下推论:

  1)待检测图片内部只包含其中一种物体,也就是说不会涉及到多物体检测,不需要采用OD类模型(OD是object detection的简称,一般模型体量会比较大,执行耗时比可比图像分类多几十倍,但好处在于可以一次性检出画面上所有的待检物体,并且提供位置信息)来做。

  2)待检测图片背景不复杂,全图只有待检物体本身,大大降低了背景噪声的引入对分类模型的影响。

  无论是数字识别任务,还是动植物识别任务,任务本身都是一个典型的十分类问题,从任务难度上看并不会特别困难。CNN领域有一些经典的十分类问题,以最耳熟能详的例子cifar10和lenet为例,数据集本身的体量很大,每一子类都有1w的可用数据。然而我们所使用的基于RT1064核心的OpenART模块,对于一些体量比较大的模型,由于MCU算力有限,处理的速度会比较慢,会耗费大量的时间来进行目标的识别。算力和模型精度是一对欢喜冤家,往往好的模型,体量都不会太小,这也就使得我们在设计模型的时候,要通盘考虑,如何设计出一款小而精的模型,从而在识别速度和准确率上脱颖而出。

  本系统的神经网络模型使用开源人工神经网络库Keras进行设计、调试、评估和应用。Keras是一个用python编写的深度学习API,可以在机器学习平台Tensorflow上运行,作为神经网络的推理引擎。

  首先,需要对数据进行预处理。在进行深度神经网络训练时,一般往往要求输入的数据范围在(-1,1)或(0,1)之间,因此,我们要对数据进行归一化处理,并将标签数据转换为one-hot码。对于智能视觉组赛题,数字和动植物的识别都是10分类,要训练一个10分类的网络(对10种物体进行分类),那么要将标签(图片所对应的类别号)转换为长度为10,并且仅有其所对应的类别号的位置的数据为1,其余均为0,这样一组n维向量就被称为one-hot码,以方便网络进行迭代学习。同时,需要对数据集进行拆分,将其划分为训练集与测试集,训练集用于模型自身迭代,测试集用于诊断模型能力。相关代码如下:

	x = np.load('./x.npy') # 数据集读入  
	y = np.load('./y.npy') # 数据集读入  
	x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state = 40) # 拆分数据集,80%作为训练集,20%作为测试集  
	np.save("test_x", x_test)  
	np.save("test_y", y_test)  
	x_train = x_train / 128.0 - 1 # 数据集归一化处理  
	y_train = to_categorical(y_train) # 转换为one-hot码  
	x_test = x_test / 128.0 - 1 # 数据集归一化处理  
	y_test = to_categorical(y_test) # 转换为one-hot码 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  接着需要搭建一个神经网络模型。我们构建了一个拥有3Conv+1Dense的CNN,即一个具有3层卷积+1层全连接的简单卷积神经网络模型,如图4.3所示。

▲ 图4.3 3层卷积+1层全连接的简单卷积神经网络模型

▲ 图4.3 3层卷积+1层全连接的简单卷积神经网络模型

  相关代码如下:

	def model_sequential():  
	    mopdel = Sequential()  
	  
	    model.add(Conv2D(32, (3,3), padding='same', input_shape=(32,32,3)))
	    model.add(pooling((2,2)))  
	    model.add(Activation("relu"))  
	  
	    model.add(Conv2D(64, (3,3), padding='same'))  
	    model.add(pooling((2,2)))  
	    model.add(Activation("relu"))  
	  
	    model.add(Conv2D(128, (3,3), padding='same'))  
	    model.add(pooling((2,2)))  
	    model.add(Activation("relu"))  
	  
	    model.add(Flatten())  
	    model.add(Dense(10))  
	    model.add(Activation("softmax"))  
	  
	    return model  

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

  搭建完神经网络模型后,就可以开始训练。

  对于学习率(lr)设置,过大的学习率会提高模型的学习速度,但是太大了可能反而适得其反,还可能会导致模型无法得到最优解;而过小的学习率,会导致训练速度过慢,陷入局部最优不能自拔,选择上要进行试错调整。这里选择
  0.001作为学习率:

	opt = Adam(lr=0.001)  

  
 
  • 1

  对于训练的评价标准,我们选择categorical_crossentropy,是专门适用于多分类问题的损失函数:
  model.compile(optimizer=opt, loss=‘categorical_crossentropy’, metrics=[“acc”])

  训练函数如下:

	early_stop = EarlyStopping(patience=20)  
	reduce_lr = ReduceLROnPlateau(patience=15)  
	save_weights = ModelCheckpoint("./models/model_{epoch:02d}_{val_acc:.4f}.h5",  save_best_only=True, monitor='val_acc')  
	callbacks = [save_weights, reduce_lr]  
	model.fit(x_train, y_train, epochs = 100, batch_size=32,  validation_data = (x_test, y_test), callbacks=callbacks)  

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

  其中epochs代表总共迭代遍历数据集多少多少次,batch_size为一次迭代需要使用多少数据。小了能让模型迭代快,但是训练效果容易震荡,还妨碍学到全局特征;大了能让学习过程更平稳,但模型收敛效率会下降,还可能陷入局部最优。save_weights和callbacks函数负责模型的保存,会将训练过程中遇到的最好结果即时保存下来。
  以上即为神经网络模型训练的流程和相关代码,训练时的界面如图4.4所示,其训练后会得到如图4.5所示的.h5格式文件。

▲ 图4.4 神经网络模型训练界面

▲ 图4.4 神经网络模型训练界面

▲ 图4.5 神经网络模型训练导出文件

▲ 图4.5 神经网络模型训练导出文件

  训练完毕后,需要对训练导出的文件进行模型的量化和部署。由于所使用的模型层数较少,所以我们使用性能最佳的NNCU工具。

  首先针对导出的模型文件进行量化。量化可以在减小模型尺寸的同时,加速模型的运行。在nncu底层使用的CMSIS-NN老式库中,量化系数给出了是由多少个位来表达tensor中的整数部分和分数部分,并且整数都是有符号整数。比如,对于8位量化,如果由3个位表示分数,那么就有1个符号位,4个整数位,和3个分数位,表达范围是[-128/8,127/8],分辨率为1/8;如果是4个位表达分数,则表达范围就是[-128/16,127/16],分辨率为1/16。在nncu中量化模型,既可以由用户指定一个全局的数值来配置表达分数的位数,就像是在电磁AI中的做法;又可以像tflite那样提供一个代表性的数据集来估算各tensor的取值范围。图4.6为nncu工具调整量化参数的界面。

▲ 图4.6 nncu工具量化参数界面

▲ 图4.6 nncu工具量化参数界面

  模型量化后,需要把模型部署到OpenART模块上。量化导出的文件格式为.nncu,把该量化后的文件放在OpenART模块的SD卡根目录上,即可调用相关API实现模型部署。相关代码如下:

	net_path = "_1s_model_03_0.9957_xxxx.nncu" # 定义模型的路径  
	labels = [line.rstrip() for line in open("/sd/labels_animal_fruits.txt")] # 加载标签  
	net = nncu.load(net_path, load_to_fb=True) # 加载模型  
	while TRUE:  
	    for r in img.find_rects(threshold = 50000): # 在图像中搜索矩形  
	        img.draw_rectangle(r.rect(), color = (255, 0, 0)) # 绘制矩形外框,便于在IDE上查看识别到的矩形位置  
	        img1 = img.copy(r.rect()) # 拷贝矩形框内的图像  
	        for obj in nncu.classify(net , img1, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):  
	            sorted_list = sorted(zip(labels, obj.output()), key = lambda x: x[1], reverse = True)  

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  至此,完成了从数据集制备到模型部署的所有工作。神经网络模型部署这一步骤适用于后文的数字识别与处理任务和动植物图案识别与处理任务。

4.1.3 数字识别与处理

  在三岔路口需要对路口处的数字进行识别,并根据数字的奇偶性,来决策应该走左边还是走右边。我们使用OpenART模块来完成此任务。

  要实现该任务,首先需要实现被识别图片矩形框的寻找和提取。OpenART提供了寻找矩形的函数img.find_rects,但由于竞赛标靶与赛道间仍有一定距离,车模在实际运行时,标靶后的背景会严重干扰矩形框的寻找定位。针对该问题,由于比赛时标靶的图片矩形框颜色是固定的(如分赛区比赛时为紫色,其RGB值为(68,0,98)),我们使用指定颜色提取的方法,把非矩形框的颜色信息全部滤除。我们先对图像色彩空间进行预处理,把RGB色彩空间转换为HSI色彩空间,其转换公式为:

θ=cos^(-1)⁡〖{([(R-G)+(R-B)]/2)/((R-G)^2+(R-B)(G-B))}〗
H={(θ@360-θ)(B≤G)¦(B>G)
S=1-(3*min(R,G,B))/(R+G+B)
I=(R+B+G)/3

  
 
  • 1
  • 2
  • 3
  • 4

  相关代码如下:

	void RGBtoHSI()  
	{  
	  int i,j;  
	  double r,g,b,numm,den,min,theta,H,S,I;  
	  uint16 color_tran;  
	  for(i=0;i<SCC8660_CSI_PIC_H;i++)  
	    for(j=0;j<SCC8660_CSI_PIC_W;j++)  
	    {  
	      color_tran = ((image_RGB[i][j]>>8)|(image_RGB[i][j]<<8));  
	      b = 1.0 * (color_tran & 0x1f) / 0x1f;  
	      g = 1.0 * ((color_tran >> 5) & 0x3f) / 0x3f;  
	      r = 1.0 * ((color_tran >> 11) & 0x1f) / 0x1f;  
	      //几何推导法转换  
	      numm=0.5*((r-g)+(r-b));  
	      den=sqrt((r-g)*(r-g)+(r-b)*(g-b));  
	      if(den==0)  
	        H=0;  
	      else  
	      {  
	        theta=acos(numm/den);  
	        if(b>g)  
	          H=(2.0*M_PI-theta)/(2.0*M_PI);  
	        else  
	          H=theta/(2.0*M_PI);  
	      }  
	      min=(b>g)?g:b;  
	      min=(min>r)?r:min;  
	      den=r+g+b;  
	      if(den==0)  
	        S=0;  
	      else  
	        S=1-3.0*min/den;  
	      I=(r+g+b)/3.0;  
	      image_H[i][j] = (uint16)(H * 360.0);  
	      image_S[i][j] = (uint8)(S * 255.0);  
	      image_I[i][j] = (uint8)(I * 255.0);  
	    }  
	}  

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

  转换完毕后,根据矩形框的实际颜色给所提取的HSV三值设定阈值范围,处于阈值范围内的像素点设为白色,处于阈值范围外的像素点为黑色,把整幅图像二值化

  把图像进行颜色提取二值化后,即可大幅度滤掉背景的干扰,对于被识别图片矩形框的寻找和提取的效果、准确度和灵敏度有非常大的提升。

  我们使用约1500个数据集建立数字模型训练数据库,如图4.7所示。

▲ 图4.7 数字模型训练数据库

▲ 图4.7 数字模型训练数据库

  寻找到矩形框后,把矩形框内的图片放入部署好的数字神经网络模型里,即可得到识别结果。数字识别的具体效果如图4.8所示。(2代表奇数,1代表偶数)

▲ 图4.8 数字识别效果图

▲ 图4.8 数字识别效果图

4.1.4 AprilTag码识别与处理

  AprilTag是一个视觉基准库,在AR,机器人,相机校准领域广泛使用。设定为与二维码相似但相对更简单的特定标志,实现快速检测。在赛题中AprilTag码也代表着数字,依然通过识别其所代表的数字,并判断奇偶性来得知靶标牌是在赛道的哪一侧。我们使用OpenART模块来完成此任务。

  OpenART提供了识别AprilTag码的函数find_apriltags,其效果如图4.11所示。

▲ 图4.9 AprilTag识别效果图

▲ 图4.9 AprilTag识别效果图

4.1.5 动植物图案识别与处理

  赛题中包含动物图案和水果图案,这部分内容也是该组别最能体现“AI”的一个环节。动物类包含狗、猫、马、猪、牛五个子类别,水果类包含苹果、橘子、葡萄、香蕉、榴莲五个子类别,图案对象均为全身或整体照片。

  关于动物和水果的识别,需要采用第十五届AI电磁组部署神经网络模型的方式,来实现对图案的识别,区别是数据量大了许多,所以这个环节的任务采用OpenART模块部署AI模型进行训练和实现。

  与数字识别与处理任务的流程类似,要实现该任务,首先需要实现被识别图片矩形框的寻找和提取。此部分已在4.1.3中叙述,此处不再簪述。

  我们使用约14万个数据集建立动植物模型训练数据库,如图4.10所示。
(0代表动物,1代表水果)

▲ 图4.10 动植物模型训练数据库

▲ 图4.10 动植物模型训练数据库

  寻找到矩形框后,把矩形框内的图片放入部署好的动植物神经网络模型里,即可得到识别结果。动植物识别的具体效果如图4.11所示。

▲ 图4.11 动植物识别效果图

▲ 图4.11 动植物识别效果图

4.1.6 激光打靶处理

  在识别到图案为水果时,需要使用车载小型激光发射器对准靶心发送一束激光,打中才算完成该项任务。在识别到AprilTag后,OpenArt与激光向相应的方向旋转90°,然后车体缓缓向前移动,直到OpenART识别到水果,并确认图像位于OpenART位置中心时,确认为激光也对准水果图片中心,然后以125Hz的频率开启激光一秒后关闭,打靶结束。

4.2 巡线识别

4.2.1 电磁巡线原理

  比赛中存在两种磁场:一种是用来作为起跑线的永磁铁产生的固定磁场,用于标识终点;一种是赛道中通过100mA交变电流的导线所产生的电磁场,用于赛道识别。前者可用价格、灵敏度、重量都很合适的全极性霍尔开关作为传感器,后者可选取原理简单、价格便宜、体积小(相对小)、频率响应快、电路实现简单电磁感应线圈作为传感器。交流电信号产生交变磁场,交变磁场在电感线圈中产生与磁场强度相关的电流。通过车前接收到的电感值来判断路况,从而控制舵机的打角大小及拐弯时电机的差速大小。

4.2.2 摄像头巡线原理

  比赛的环境为在蓝色背景布上铺设白色赛道,两者的差距十分明显,通过使用总钻风灰度摄像头采集灰度图像,为了适应不同场地,使用动态阈值对灰度图像进行二值化(如图4.12所示),而后寻找像素点由黑到白的跳变点,对跳变点的行列坐标进行运算,得到每一行的中点列坐标,通过每一行的中点列坐标与直道上的中点列坐标做差,后多行进行累加,即可以得到偏差值,通过偏差值控制舵机的打角大小及拐弯电机的差速大小。

▲ 图4.12 灰度图像二值化效果图(左:二值化前,右:二值化后)

▲ 图4.12 灰度图像二值化效果图(左:二值化前,右:二值化后)

4.3 赛道元素处理

  4.3.1 十字处理
  在处理十字时,首先通过摄像头寻找拐点,当上下左右四个拐点都同时找到时,判断为遇到十字。然后将下方两拐点和上方两拐点相连补线(如图4.13所示),使进入十字的方向得以保证。当进入十字后,下方两拐点消失,用上方拐点和图像最下行边角点进行拉线,使车能够较为平稳的通过十字。

▲ 图4.13 十字斜率补线效果图

▲ 图4.13 十字斜率补线效果图

4.3.2 环岛处理

  环岛是从十三届开始出现的元素,给系统控制带来了很大的困难。我们采用的是摄像头识别并进行处理。首先,识别到下拐点和右边线斜率在固定范围内时,认为进入环岛;进入环岛后采用状态机进行环岛各阶段的补线处理,最主要的是进出拐点处的补线(如图4.14所示)。

▲ 图4.14 环岛补线处理

▲ 图4.14 环岛补线处理

4.3.3 坡道处理

  通过使用加速度计和陀螺仪来共同判断坡道元素,将加速度计值和陀螺仪值进行卡尔曼滤波(如图4.15所示),从而得到真实角度值,当角度值大于一定值时,判断当前正在上坡,由于在上坡过程车模存在倾角,所以摄像头可能会看到多余的干扰信息,因此在判断到坡道之后,此时其余所有元素都被屏蔽掉,防止误判。

▲ 图4.15 卡尔曼滤波效果图(黄线:滤波前,红线:滤波后)

▲ 图4.15 卡尔曼滤波效果图(黄线:滤波前,红线:滤波后)

4.3.4 车库处理

  出库采用的是固定打角,在形式一定距离车体基本驶出车库以后,变更为正常的摄像头循迹。
  第一圈需要直接驶过斑马线,故对车库进行了补线处理,第二圈结束后要驶进车库,为了节约时间,本系统没有采用倒车入库这种更稳定的方式,而是直接冲入车库,在搜索到斑马线以后,确定斑马线的位置,当斑马线位置在一定范围内时,使车模打固定角并行驶一定距离后,用摄像头微调车的姿态,然后识别停车。此方法的入库姿态与车模速度的关系较大。(补线如图4.16所示)

▲ 图4.16 车库处理效果图

▲ 图4.16 车库处理效果图

4.3.5 三岔处理

  三岔路口是今年新增的元素,我们采用了总钻风摄像头也是巡线的摄像头对三岔路口进行识别,核心方法是识别岔路的两个钝角夹角。在第一圈识别到三叉岔路口时提前减速并停车,并识别分岔路口的数字靶牌,偶数向左,奇数向右。利用补线的方法转向(如图4.17所示),在出三叉的时候同样的识别加补线。并记录标志位以便在第二圈三岔路口时不用停下来识别直接转向。

▲ 图4.17三岔补线效果图(左图:向左补线,右图:向右补线)

▲ 图4.17三岔补线效果图(左图:向左补线,右图:向右补线)

4.3.6 AI任务处理

  在巡线时识别到前方路面中央有AprilTag二维码,需要紧急刹车处理,并用OpenART对其进行智能读取,根据二维码对应数字,分别在赛道左侧,或者右侧,二维码前后50厘米范围内放置靶标牌。如果路边目标牌上的图案属于动物类,则车模需要在二维码所在的区域(前后50厘米)内不少于3秒钟,方能驶出车模停止区域。如果路边目标牌上的图案属于水果类,则车模需要使用车载小型激光发射器对准靶点中心发送一束激光,激光持续一秒,激发目标靶响应。

4.4 控制算法

4.4.1 PID控制

  在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。PID控制器问世至今已有近70年历史,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型时,控制理论的其它技术难以采用时,系统控制器的结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。即当我们不完全了解一个系统和被控对象,或不能通过有效的测量手段来获得系统参数时,最适合用PID控制技术。PID控制,实际中也有PI和PD控制。

  PID控制器是一种线性控制器,它根据给定值与实际输出值构成控制偏差。将偏差的比例§、积分(I)和微分(D)通过线性组合构成控制量,对被控对象进行控制,故称PID控制器,原理框图如图4.18所示。

▲ 图4.18 PID控制器原理框图

▲ 图4.18 PID控制器原理框图

  在计算机控制系统中,使用的是数字PID控制器,控制规律为:

式中:
  k——采样序号,k = 0,1,2…; r(k)——第k次给定值;
  c(k)——第k次实际输出值; u(k)—— 第k次输出控制量;
  e(k)—— 第k次偏差; e(k-1)—— 第k-1次偏差;
  KP——比例系数; TI——积分时间常数;
  TD——微分时间常数; T——采样周期。

  简单说来,PID控制器各校正环节的作用如下:

  • 比例环节:及时成比例地反映控制系统的偏差信号,偏差一旦产生,控制器立即产生控制作用,以减少偏差。
  • 积分环节:主要用于消除静差,提高系统的无差度。积分作用的强弱取决于积分时间常数,越大,积分作用越弱,反之则越强。
  • 微分环节:能反映偏差信号的变化趋势(变化速率),并能在该偏差信号变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作速度,减小调节时间。

  数字PID控制算法通常分为位置式PID控制算法和增量式PID控制算法。

4.4.2 位置式PID

  位置式PID中,由于计算机输出的u(k)直接去控制执行机构(如阀门),u(k)的值和执行机构的位置(如阀门开度)是一一对应的,位置式PID控制算法的缺点是:由于全量输出,所以每次输出均与过去的状态有关,计算时要对过去e(k)进行累加,计算机工作量大;而且因为计算机输出的u(k)对应的是执行机构的实际位置,如计算机出现故障,u(k)的大幅度变化,会引起执行机构位置的大幅度变化,这种情况往往是生产实践中不允许的,在某些场合,还可能造成严重的生产事故。

4.4.3 增量式PID

  所谓增量式PID是指数字控制器的输出只是控制量的增量△u(k)。当执行机构需要的是控制量的增量(例如:驱动步进电机)时,可由推导出提供增量的PID控制算式如下:

  可以看出由于一般计算机控制系统采用恒定的采样周期T,一旦确定了KP、TI 、TD,只要使用前后三次测量值的偏差,即可求出控制增量。

  增量式PID具有以下优点:

(1) 由于计算机输出增量,所以误动作时影响小,必要时可用逻辑判断的方法关掉。

(2) 手动/自动切换时冲击小,便于实现无扰动切换。此外,当计算机发生故障时,由于输出通道或执行装置具有信号的锁存作用,故能保持原值。

(3) 算式中不需要累加。控制增量△u(k)的确定仅与最近k次的采样值有关,所以较容易通过加权处理而获得比较好的控制效果。但增量式PID也有其不足之处:积分截断效应大,有静态误差;溢出的影响大。使用时,常选择带死区、积分分离等改进PID控制算法。

4.4.4 PID参数整定

  运用PID控制的关键是调整KP、KI、KD三个参数,即参数整定。PID参数的整定方法有两大类:一是理论计算整定法。它主要是依据系统的数学模型,经过理论计算确定控制器参数;二是工程整定方法,它主要依赖工程经验,直接在控制系统的试验中进行,且方法简单、易于掌握,在工程实际中被广泛采用。由于智能车系统是机电高耦合的分布式系统,并且要考虑赛道的具体环境,要建立精确的智能车运动控制数学模型有一定难度,而且我们对车身机械结构经常进行修正,模型参数变化较为频繁,理论计算整定法可操作性不强,最终我们采用了工程整定方法。此外,我们先后实验了几种动态改变PID参数的控制方法。

4.4.5 模糊控制

  一般控制系统包含了五个主要部分,即:定义变量、模糊化、知识库、逻辑判断及反模糊化,底下将就每一部分做简单的说明:

  • 定义变量:也就是决定程序被观察的状况及考虑控制的动作,例如在一般控制问题上,输入变量有输出误差E与输出误差之变化率CE,而控制变量则为下一个状态之输入U。其中E、CE、U统称为模糊变量。
  • 模糊化(Fuzzify):将输入值以适当的比例转换到论域的数值,利用口语化变量来描述测量物理量的过程,依适合的语言值(Linguisitcvalue)求该值相对之隶属度,此口语化变量我们称之为模糊子集合(Fuzzysubsets)。
  • 知识库:包括数据库(Database)与规则库(Rulebase)两部分,其中数据库是提供处理模糊数据之相关定义;而规则库则藉由一群语言控制规则描述控制目标和策略。
  • 逻辑判断:模仿人类下判断时的模糊概念,运用模糊逻辑和模糊推论法进行推论,而得到模糊控制讯号。此部分是模糊控制器的精髓所在。
  • 解模糊化(Defuzzify):将推论所得到的模糊值转换为明确的控制讯号,做为系统的输入值。

  模糊算法可以解决一些非线性问题,将赛道分为直线、入大小弯、出大小弯、蛇形弯道,对应的直线加速、入大弯减速转方向、入小弯制动转方向、出弯加速、蛇形弯道直接通过。要达到这种控制要通过实际检测,分析大量赛道磁场信息,找出它们的特征。

  虽然模糊控制可以较好解决一些非线性问题,但控制复杂,实际调试中较PID控制无明显优势。方向环采用位置式PD,虽然存在稳态误差,但可以快速响应;速度环控制为增量式PID,由于给定速度频繁变化,采用微分先行PID,使电机能够快速响应。

 

第五章 统开发工具


  发工具使用的是IAR Embedded Workbench IDE。它能够为i.MX RT1064单片机提供与之配套的应用程序开发模块。在目标程序的下载方面,通过J-Link与单片机之间的连接下载程序。IAR功能强大,界面简洁严整,内置的C编译器编译产生的代码优化度高,执行效率也高。同时IAR具有强大的在线调试功能,可以充分满足智能车软件系统开发的需要。其开发界面如图5.1所示。

▲ 图5.1 IAR开发界面

▲ 图5.1 IAR开发界面

 

第六章 模主要参数


  模主要参数名称 参数

  • 车模类型 C车模
  • 车模长度 33cm
  • 车模宽度 22cm
  • 车模高度 30cm
  • 微控制器型号 NXP i.MX RT1064
  • 传感器的种类及个数 总钻风摄像头MT9V034 * 1
  • OpenART * 4
  • 10mH电感 * 5
  • 陀螺仪ICM20602 * 1
  • 逐飞1024线光电编码器 * 2
  • 转向舵机型号 S3010
  • 车模后轮驱动电机型号 C车模RS380电机

 

第七章 模花费


7.1 车模整体花费清单(不含耗损)

  表7.1 车模整体花费清单(不含损耗)

  物品名称 数量 总价

  • C车模(含电机、舵机) 1 565.00
  • 1024线带方向光电编码器 2 396.00
  • RT1064核心板 1 199.00
  • ICM20602陀螺仪 1 32.00
  • 2S锂电池 1 78.00
  • 锂电池充电器 1 35.00
  • 总钻风MT9V034灰度摄像头130度 1 279.00
  • 130度摄像头偏振镜 1 14.99
  • OpenMVRT(120度含32G内存卡) 1 399.00
  • OpenART mini(90度含32G内存卡) 1 403.00
  • OpenART mini(110度含32G内存卡) 2 846.00
  • KST DS215MG舵机 2 360.00
  • 激光发射模块 2 14.40
  • 400mm空心碳素杆 1 7.90
  • 195mm空心碳素杆 3 14.70
  • 摄像头三通连接件 7 69.30
  • 摄像头铝制固定底座 4 39.60
  • 光电传感器 1 18.00
  • DAP下载器 1 78.00
  • 1.8寸TFT显示屏 1 34.90
  • 无线串口(USB端+串口端) 1 79.00
  • 裁判系统 4 1190.00
  • 主板 1 150.00
  • 云台舵机固定板 1 0.00
  • XH2.54排线6P10cm 1 0.78
  • XH2.54排线8P10cm 1 1.04
  • XH2.54排线3P10cm 1 0.39
  • XH2.54排线4P20cm 4 2.24
  • 总价 5307.24

7.2 耗损清单

  表7.2 损耗清单

  • 物品名称 数量 总价
  • 2S锂电池 3 234.00
  • 锂电池充电器 1 35.00
  • 摄像头FPC软排线300mm 5 1.70
  • XH2.54排线6P10cm 5 3.90
  • XH2.54排线8P10cm 5 5.20
  • XH2.54排线3P10cm 5 1.95
  • XH2.54排线4P20cm 10 5.60
  • C车轮胎 4 40.00
  • 齿轮油 1 4.50
  • 轴承润滑油 1 8.50
  • 轮胎软化剂 1 25.00
  • 标靶(动物+水果+数字) 1 875.00
  • RT1064核心板 1 199.00
  • S3010舵机 1 135.00
  • 主板 1 250.00
  • 电磁板 1 100.00
  • 云台舵机固定板 1 0.00
  • 总价 1924.35

 

第八章 内人员分工


  • 石钰莹

  1)硬件电路设计与绘制
  2)车模机械结构设计与安装

  • 武锦辉

  1)赛道元素识别提取
  2)车模运动PID调参
  3)AI任务控制部署

  • 龙俊旺

  1)搭建AI神经网络
  2)建立数据库
  3)配置AI神经网络模型

 

考文献


[1] 邵贝贝.单片机嵌入式应用的在线开发方法[M].北京:清华大学出版社.2004.
[2] 余志生.汽车理论.北京:机械工业出版社.2012.
[3] 卓晴,黄开胜,邵贝贝.学做智能车:挑战“飞思卡尔”杯.北京:北京航空航天大学出版社,2007.
[4] 童诗白,华成英.模拟电子技术基础[M].北京:高等教育出版社,2001.
[5] 阎石.数字电子技术基础[M].北京:高等教育出版社,2000.
[6] 谭浩强.C程序设计.北京:清华大学出版社,2003.
[7] 尹勇.Protel DXP电路设计入门与进阶[M].北京:科学出版社,2004.
[8] 尹怡欣,陶永华.新型PID控制及其应用.北京:机械工业出版社,1998.
[9] 李太福,基于在线参数自整定的模糊PID伺服控制系统[J].交流伺服系统,2005.4:203~215.
[10] 卢京潮.自动控制原理[M].北京:清华大学出版社,2013:1-211.
[11] 陈启军,余有灵,张伟,潘登,周伟.嵌入式系统及其应用[M].上海:同济大学出版社,2015:30-80.
[12] 刘建昌,关守平,周玮等.计算机控制系统[M].北京:科学出版社,2019:1-40.

■ 附录A:电路原理图

■ 附录B:程序源代码

01	#include "headfile.h"
02	#include "All_def.h"
03	
04	//主函数
05	int main(void)
06	{
07	    All_init();
09	    while (1)
10	    {
11	        //此处编写需要循环执行的代码
12	      if(mt9v03x_csi_finish_flag)
13	      {
14	        mt9v03x_csi_finish_flag = 0;
15	        In_Camera();
16	        In_Key();
17	        In_Ele();
18	        GetLine();
19	
20	        In_AI();
21	        Control();
22	        Out_Servo();
23	        Out_Motor();
24	        Out_Wireless();
25	        if(sw1_flag == 1)
27	          Out_TFT();
29	      }
30	    }
31	}
44	/*****电机Out_Motor.c*****/
45	#include "headfile.h"
46	#include "All_def.h"
47	
48	int motor1,motor2;
49	
50	int Limit_motot(int PWM, int MAX, int MIN)
51	{
52	  if(PWM>MAX)
53	          PWM = MAX;
54	  if(PWM<MIN)
55	          PWM = MIN;
56	  return PWM;
57	}
58	
59	void motor_ctr()
60	{
61	    if(motor1>0)
62	    {
63	      pwm_duty(MOTOR1_A_PIN, motor1);
64	      pwm_duty(MOTOR1_B_PIN, 0);
65	    }
66	    else
67	    {
68	      pwm_duty(MOTOR1_A_PIN, 0);
69	      pwm_duty(MOTOR1_B_PIN, -motor1);
70	    }
71	    
72	    if(motor2>0)
73	    {
74	      pwm_duty(MOTOR2_A_PIN, motor2);
75	      pwm_duty(MOTOR2_B_PIN, 0);
76	    }
77	    else
78	    {
79	      pwm_duty(MOTOR2_A_PIN, 0);
80	      pwm_duty(MOTOR2_B_PIN, -motor2);
81	    }
82	}
83	
84	void Out_Motor()
85	{
86	    motor1 = Limit_motot(voltageL,50000,-50000);
87	    motor2 = Limit_motot(voltageR,50000,-50000); 
88	    motor_ctr();
89	}
90	#include "headfile.h"
91	#include "All_def.h"
92	
93	int motor1,motor2;
94	
95	int Limit_motot(int PWM, int MAX, int MIN)
96	{
97	  if(PWM>MAX)
98	          PWM = MAX;
99	  if(PWM<MIN)
100	          PWM = MIN;
101	  return PWM;
102	}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87


● 相关图表链接:

文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。

原文链接:zhuoqing.blog.csdn.net/article/details/120104919

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。