【UG Graduation Design】Urban Traffic Simulation System Based on the Autonomous Technique

该文章是本人的本科毕业设计,题目为《基于自动驾驶技术的城市交通虚拟仿真系统》。题目的要求有:①构建出基本的城市交通环境;② 单个车辆具有自主决策能力(可通过强化学习进行训练)

2021-01-15

演示视频:

制作工具:

unity 2018.4.15.c1 + ml-agents toolkit + visualstudio2019

制作流程:

1. 软件系统环境的搭建

本系统采用Unity3D 4.18c1 + Python3.6 + Tesorflow + Ml-Agents 12.1 共同构成仿真环境。

Unity是由Unity科技公司开发的跨平台游戏引擎,该引擎于2005年6月在苹果公司全球开发者大会上首次发布,并作为Mac OS X专有游戏引擎发布。该引擎可用于创建三维二维,虚拟现实和增强现实游戏,以及模拟和其他体验。该引擎已被视频游戏以外的行业所采用,例如电影汽车建筑工程建筑[7]。Unity内置了英伟达的Physx物理引擎,因其强大的物理特性所以被广泛应用于虚拟仿真模拟。

Python + Tensorflow + Ml-Agents构成机器学习训练环境。配置步骤如下:

 (1)通过Anaconda安裝Python,下载并安装Anaconda。这是一个很好的管理环境的软件(Container),可以随时切换环境,这里必须下载Python3.6以上的版本,因为Unity Ml-Agents不支持其他版本。

 (2)然后开启命令行工具(Window+R+CMD)输入

  conda create –n ml-agents python=3.6

一直按Y执行下一步,完成时候就会常建一个在Anaconda里独立的Python

环境,为了能够稳定调试各功能,用Unity Ml-Agents较为稳定的版本会比较好。完成之后会出现:

 #

# To activate this environment, use:

# > activate ml-agents

#

# To deactivate an active environment, use:

# > deactivate

#

# * for power-users using bash, you must source

#

接着输入:

  activate ml-agents

就会在当下环境切换成Ml-Agents环境,所有的训练命令就是在这个环境中执行的。

  (3)安装Tensorflow,这里分为两个部分,一个是有GPU的,一个是无GPU的。这里选用有GPU的,输入命令:

  pip3 install tensorflow-gpu==1.7.1

  (4)下载Untiy Ml-Agents Toolkit工具包。因为已装有Git工具,这里直接输入命令:

  git clone https://github.com/Unity-Technologies/ml-agents.git

然后下载好之后进入到这个目录,目录里还有一个ml-agents文件夹

  cd ml-agents/ml-agents 

  (5)安装工具包,进入到上述的文件夹之后,输入命令:

  pip install -e

 这里环境全部搭建完成,可以验证是否配置成功,配置成功之后效果下图:

  (6)打开Unity,导入ml-agents文件夹中的SDK文件包,点击Edit>Project Setting。点开左边菜单的Player,然后点击Other Settings会显示一堆选项,拉到下面找到Scripting Define Symbols的选项,在空格里输入ENABLE_TENSORLOW。输入完成后会自动存储,在Configuration选项中有个Scripting Runtime Version和Api Compatibility Level,都在复选框里选择.NET 4.X。在Package Manager窗口中下载Barracuda,下载完成之后就可以开始训练自己的项目了。

2. 仿真城市交通环境的搭建

2.1  搭建虚拟城市

   城市模型使用Unity 资源市场(AssetStore)里的Urban City Pack,该资源包括的模型有各类楼房(Buildings)、街道道具(Street Props)、树木(Trees)、马路(Roads)、路灯(Street Lights)和交通信号灯(Traffic Lights),搭建完成效果如下图所示。 

 Azure[Sky] Dynamic SkyBox插件可以营造一种较为真实的天气系统,支持经纬度调整,天气调整以及24h昼夜天空盒动态变化,效果如下图所示。插件功能包括模块包括时间控制器、引用控制器、事件系统以及自定义模式。本系统通过此插件构造较为真实的天气环境,通过该插件TimeController类里的timeline函数获取本地时间,用来控制路灯和车灯的打开与关闭。

2.2  搭建交通环境

  Urban Traffic System(UTS)插件可以快速的绘制车辆行驶路线,可以轻松调整车流密度,每个车辆预制体可以简单地检测前方车辆并且做出相应的减速和加速行为,但不具有智能,所以可以用来作为陪训车辆。交通信号灯机制效果如下图1。为了简化过程,这里并没有通过图像识别信号灯颜色,而是简化为通过添加多个碰撞器(Box Collider)来阻碍一方车流行驶,将图像识别信号灯机制转换为简单的碰撞器检测信号机制。其运行原理的工作流大致如下图2:


下图为交通信号灯机制功能部分代码。

2.3  添加车辆控制器

  Unity自带的车轮碰撞器(Wheel Collider)是一种针对地面载具的特殊碰撞器。 它内置了碰撞侦测、车轮物理学和基于滑动的轮胎摩擦模型。它也可以用于车轮以外的物体,但专门还是为有轮子的车辆设计的。

 (1)首先,添加一个游戏对象作为车辆的根对象。为此请点击游戏对象 > 创建空对象(Empty)。将游戏物体的名称更改为CarAgent。

 (2)给CarAgent添加物理刚体。对于默认的悬挂设置,1kg质量太轻,将其更改为1500kg使车辆稍微重一些。

 (3)接下来,创建车身碰撞器Mesh Collider。

 (4)创建四个车轮,其名称分别改为FrontWheel和RearWheel。在其上重置“变换”。此对象不是强制性的,但对以后的调试和调试很有用。

 (5)给四个车轮添加WheelCollider,通过视窗来调整碰撞器到合适位置和大小,并调整其他参数如下图3.7所示。  

 (6)刚体、碰撞器都已具备,车辆的所以组件都已组装完毕。效果如下图所示

添加所需的组件后,可以编写脚本来驱动车辆了。Unity为车轮碰撞器提供了专用的函数来驱动车辆,部分代码如下:

2.4  绘制高精地图 

本系统为了简化训练模型传入的参数,这里只将高精地图进行了点到点的绘制,没有进行道路片段划分和添加道路参数(坡度、弯度)。本系统使用AssetStore的免费插件Graphway绘制带权有向图。效果如有图所示,其中包括三车道的直行车道、左转车道、右转车道、掉头车道和单车道。 

   Graphway插件:Graphway 是Unity的一款免费路径查找图形创建工具。该工具使用简单并且可拓展,能够处理包含是个、数百个甚至数千个节点的图。

2.5  添加射线传感器

传统无人驾驶大多使用摄像头传感和激光雷达传感。这里为简化训练模型,使用Unity Ml-Agents工具包自带的传感器组件RayPeceptionSensorComponent3D,传感器可检测标签包含道路标签、其他车辆标签以及行人标签。这里通过简化成传感器标签识别从而代替图像识别分类技术, 效果如下图所示

2.6  设置训练代理

l 在Unity项目中使用Ml-Agents工具包涉及以下基本步骤:

 (1)创建一个供代理居住的环境。环境的范围可以从包含几个对象的简单物理模拟到整个游戏或生态系统。

 (2)实现代理子类。Agent子类定义了Agent用于观察其环境,执行分配的动作以及计算用于强化训练的报酬的代码。也可以实现可选方法,以在代理完成或失败任务后重置代理。

 (3)将Agent子类添加到适当的GameObject,通常是场景中代表模拟中Agent的对象。

l 接下来创建代理:

 (1)选择RollerAgent GameObject以在“检查器”窗口中查看它。

 (2)单击添加组件。

 (3)单击组件列表中的“ 新建脚本 ”(在底部)。

 (4)将脚本命名为“ CarAgent”。

 (5)点击创建并添加。

l 然后编辑新的CarAgent脚本:

 (1)在Unity项目窗口中,双击RollerAgent脚本以在代码编辑器中将其打开。

 (2)在编辑器中,添加using Unity.MLAgents;和 using Unity.MLAgents.Sensors语句,然后将基类从更改 MonoBehaviour为Agent。

 (3)删除该Update()方法,但是我们将使用该Start()函数,因此暂时不要使用它。

到目前为止,这些是将Ml-Agents添加到任何Unity项目中的基本步骤。接下来,我们将添加逻辑,该逻辑将使我们的Agent使用强化学习来学习滚动到多维数据集。更具体地说,我们将需要从Agent基类扩展三个方法:

² InitializeAgent()

² CollectObservations(VectorSensor sensor)

² AgentAction(float[] vectorAction)

接下来详细叙述一下三个方法:

l 初始化和重置代理

  Ml-Agents工具包中的培训过程涉及运行情节,其中代理(无人小车)尝试解决任务。每个情节一直持续到代理解决任务(即到达多维数据集),失败(碰撞或违规)或超时(花费太长时间才能解决任务或失败)为止。在每个情节开始时,都会InitializeAgent()调用该方法来设置新情节的环境。通常,场景以随机方式初始化,以使代理能够学习在各种条件下解决任务的能力。  

  在此项目中,每次代理到达其目的地时,情节结束,该方法将重新选取一个新的初始位置。此外,如果代理发生碰撞或违规,则AgentReset()方法会将其放初始位置。

要移动小车(多维数据集),我们需要继承之前写好的车辆控制器(internal RCC_Cartroller carController)。在初始化函数中引用小车的控制器组件GameObject.GetComponent<RCC_ContorllerV3>(),同时还要获取刚体组件RigidBody。最后的代码大概如下:

上图所示代码中,Grapway.FindPath()方法用于寻路,该方法会传参当前车辆坐标,目的地坐标给A*算法,并将结果路径通过数组传回。

l 观察环境

代理将我们收集到的信息发送给大脑,大脑使用该信息作出决策。训练代理(或使用训练的模型)时,数据将作为特征向量传入到神经网络中。为了时代里成功完成学习任务,需要给收集函数提供正确的信息。决定收集那些信息的一个好法则就是考虑计算该问题的分析解决方案所需的条件。

在本项目中,代理收集的信息除了传感器参数以外,还有自身的位置、车速、油门刹车阈值、转向阈值和距离下一个路点的距离。如下所示:

l 采取行动并分配奖励

动作:为了解决车辆移动任务,代理需要刹车油门和转向两个控制维度。因此需要向代理提供两个操作。第一个是油门刹车阈值,第二个是转向阈值。CarAgent 使用以下函数将action[ ]数组中的值应应用于其车辆控制器组件。代码如下图:

奖赏:强化学习需要奖励。在AgentAction()函数中分配奖励。学习算法使用在模拟和学习过程中分配给代理的经历来确定他是否正在为代理提供最佳行动。     

CarAgent 计算当前车辆与下一路点的距离。到达路点后,代码将调用Agent.AddReward()方法分配0.1f的小报酬(如下图)。

   在上图代码中,relativePosition 为车辆与路点之间相对距离(三维)。 通过relativeposition.magnitude转换浮点数。当该值小于2.0f时判断为已到达该路点。并前往下一个路点。

惩罚:当代理小车碰上其他陪训车辆、马路边缘,行人和交通信号碰撞器,通过碰撞检测函数进行侦测。如若发生碰撞,执行AddReward(-5f)来给予一个较大的惩罚。AgentAction()函数中,还需要加上时间惩罚。时间惩罚是根据此训练情景里Behavior Parameters里的的最大步数来折算。通过方法 AddReward(-1f / agentParmeters.maxStep) 实现。

l 最后编辑器的设置

现在所有游戏对象和Ml-Agents组件均已安装到位,是时候在Untiy编辑器中将所有东西连接起来了。这涉及更改某些代理组件的属性,以使其与我们的代理代码兼容。

(1) 选择代理小车的游戏对象,在检查器窗口中查看其属性。

(2) Behavior Parameters 使用代理小车检查器中的“添加组件”按钮来添加脚本。

(3) 修改代理的行为参数:

² Benhavior Name 改为SelfDriving,以便训练结束查看所属相关文件

² Vector Observation > Space Size = 7

² Vector Action > Space Type = Continuous

² Vector Actuon > Space Size = 2

(4) 添加CarAgent脚本到代理小车。

(5) 将Decision Interval(决策期)改为10。

(6) 将Use Child Sensors单选框打上勾。

(7) 添加组件Ray Perception Sensors。

(8) 修改传感器组件参数:

² 可检测标签包括:车辆,信号灯,马路,行人

² Ray Per Direction = 3

² Max Ray Degrees = 90

² Ray Length = 40

² Observation Stack = 1

现在已经准备好培训之前的测试环境。

l 测试环境

首先通过使用键盘控制代理测试是否已经配置完成。所以,需要适CarAgent类里的Heuristic()扩展方法。在此环境中,启发式方法将生成一个与“Horizontal”和“Vertical”输入轴(对应于键盘箭头键)的值相对应的动作:

  为了使代理启用启发式,需要设置Behavior Type,将Behavior Parameters 里的相应选项改成Heuristic Only。

  接下来按播放按钮测试代理,可以发现用键盘的箭头键已经可以控制小车的前进后退与转弯。

l 训练环境

用于训练的超参数在传递给mlagents -learn 程序的配置文件中指定。创建一个新的SelfDriving_conf-ig.yaml文件,并设置一下超参数里的max_steps、buffer_size和learning_rate至合适的参数。最后训练代理还要启动编辑器之前在控制台中执行如下命令开始训练:mlagents -learn config/SelfDriving_config.yaml -run -id = SelfDriving

  经过42小时的训练之后(效果如图3.16),将训练好的SelfDriving.nn文件赋给代理小车Behavior Parameters窗口里的Model。接下来运行编辑器,小车就可以通过训练好的模型进行自动驾驶了。因为训练的时间不是特别充足,目前代理小车对交通信号识别良好。但是因为其他陪训车辆车况较为复杂,和环境偶尔会因为加速而出现一线错误,导致训练表现出的效果并不是特别好,偶尔会发生碰撞的情况。那么截止目前,仿真环境基本已搭建完毕(效果如下图:

打赏 0

共有 0 条评论