无人驾驶作为一项新兴技术,落地为产品需要大量算法、工程、产品贯通的AI全栈人才。笔者在最近一年招聘中发现,许多技术方向的同学对人工智能既爱又畏惧,一方面觉得这是未来,另一方面又觉得很难而不敢触碰。懂工程的同学做算法时有很大的畏惧感,而专注算法的同学又常常容易陷入某个算法而缺乏工程落地能力。
这次笔者以一个从业者角度来与大家聊一下如何入门无人驾驶/机器人行业,也希望大家多了解和加入PerceptIn,在实战中成长为算法,工程,产品贯通的AI全栈人才。
首先我们探讨下无人驾驶能如何提高人类社会的效率。第一是无人驾驶对环境的影响:每辆传统车每年平均排放5吨的二氧化碳,以美国为例有2.5亿台车,每年二氧化碳排放就有12.5亿吨。而如果使用中央调度的无人新能源车,那么总排放量可以被降低到0.6亿吨,效果十分惊人。
然后我们看看无人驾驶对安全的影响:人类驾驶员每驾驶100万英里的里程,平均会发生4.2次意外,全球每年会产生大约1300万次事故。如果我们能把无人驾驶每100万英里的事故率控制在1次以内,那么总事故数会被控制在300万左右。现在每年全球车祸死亡人数超过百万,所以无人驾驶的普及可以每年在全球挽救几十万甚至上百万的生命。
最后我们了解下无人驾驶对经济的影响:由于减少碳排放,无人驾驶普及每年可减少3000亿美金的经济损失。另外,每次车祸带来的经济损失平均为3000美金,那么如果通过无人驾驶实现每100万英里的车祸率在1次以内的安全目标,每年也可以减少3000亿美金的经济损失。两者相加,无人驾驶普及后每年至少可以减少6000亿美金的经济损失,这基本相当于瑞士的GDP,如果按全球国家GDP排行榜可以排进前20左右。
假设你是一位ANDROID手机开发者,想投身无人驾驶行业,你需要的最重要的条件不是熟悉某个技术点,而是要有足够的好奇心去探索了解新的技术与克服困难的勇气。 一年前我们探索过一个好玩的课题,如果用一个手机平台,是否可以支撑起无人驾驶的作业?于是我们使用了ANDROID手机平台,实现了一些比较简单的无人驾驶功能,主要是用视觉来做。
下图显示了一个面向基于视觉的无人驾驶的移动SoC系统组成。在这个移动SoC实现中,我们利用DSP处理传感器数据,如特征提取和光流;我们使用GPU完成深度学习任务,如目标识别;采用两个CPU线程完成定位任务以实现车辆实时定位;我们使用一个CPU线程实现实时路径规划;使用另一个CPU线程进行避障操作。如果CPU尚未被全占有,多个CPU线程则可以在同一CPU核心上运行。
令人惊讶的是,实验数据证明,无人驾驶系统在ARM SOC上运行的性能并不差。定位流水线每秒可处理25帧图像,图像生成速度为每秒30帧图像,这说明产生的图像大部分可以得到及时处理,不会产生大规模的丢帧。深度学习流水线每秒能够执行2到3个目标识别任务。规划和控制流水线目标是在6 MS内完成路径规划。当使用ARM移动端 SOC进行无人驾驶时,我们能够以5英里/小时的速度行驶车辆,并且不损失任何定位信息;同时,整个SOC平均功耗为11瓦。移动SoC的硬件资源有限,能够支持有限范围内的无人驾驶系统确实是非常令人惊喜的发现。这说明如果增加更多的计算资源,硬件平台就能够处理更多的数据,并支持车辆以更快的速度行驶,最终满足产品级无人驾驶系统的需要。
然后我们深入聊下无人驾驶的技术,无人驾驶并不是单点的技术,而是多个技术的整合。 无人驾驶的整体技术架构,大概可以分为三大模块:算法、系统以及云平台。
在车辆端,上层是算法模块,包括传感(如何更好的获取环境数据)、感知(如何更好的理解车辆周围环境,包括定位,物体识别,物体追踪)以及决策(在了解环境后如何更好的做出决策,包括路径规划,行为预测和障碍物躲避等)三个部分;下层则是操作系统和硬件平台。而在云端,则有一个无人驾驶的云平台,其上囊括了高精地图、模型训练、模拟计算以及数据存储等几块内容。
无人驾驶汽车行驶过程中最重要的是要知道自身处在什么位置上,只有这样才知道要怎么去往目的地。接下来将主要阐述目前应用比较多的定位技术。
我们平常用的是多星GPS,可以接收伽利略或北斗的信号,做一个综合,然后得出一个相对精准的位置。但是多星GPS的定位精度大约能做到1-2米,这满足不了无人驾驶车道级定位的要求。所以,后续,业内又开发出一种被称为RTK(Real-Time-Kinematic)的GPS,主要是依靠在地面布置基站,通过基站的信号去纠正卫星的信号,精度可以达到分米级别甚至更低。但缺点是需要布置基站,成本很高,还需要人维护。接下来,又出现一种称为PPP(精密单点定位)的GPS技术,基于全球卫星的联网系统,通过互联网发布卫星的纠正信号,这项技术大概在2018年会在全球进行部署。其好处在于不需要布置基站,无论在哪,都能得到一个比较精准的位置。
GPS是一个比较好的定位导航工具,但是其更新率低是最大的问题。有的是1帧/秒的更新,有的是10帧/秒的更新,车辆高速行驶的状况下,这显然不够用。所以,一般情况下,我们会把GPS和IMU惯导系统结合起来。惯导系统能提供快速更新——1000帧/秒,这弥补了GPS的更新率低的问题;而惯性导航所存在的“累计误差”问题,也可以通过GPS来弥补。刚入门的同学可以使用手机平台提取基本的GPS轨迹数据去了解GPS的基本运作原理,然后再深入了解不同GPS的性能区别。
激光雷达的好处是有一定的射程,能触及100-200米的距离,能很精准的得到空间中的点(3D点云)。将激光雷达的数据和高精地图的数据做一个匹配,可以将车辆定位上升到厘米级别。
但是激光雷达的成本高,而且是转动的形式,容易磨损,耐用性很差。 激光雷达很依赖另一个传感器——高精地图(传统意义上也不能称其为传感器),二者配合使用才能达到一个很好的定位效果。
具体到高精地图的制作上。在高精地图的最底层,是一个网格地图,网格地图是使用激光雷达扫描回来的,精度可达5厘米;网格地图之上,我们会做道路的标签,也就是最底层的reference line;再加一些语义信息,精确到车道,标示出lanes;在车道之上,再做一些语义标签,比如限速、红绿灯这样的标志物。高精地图制作起来非常昂贵,因为需要激光雷达设备不断去扫描外部环境,从而得到相关的数据来支撑其制作。刚入门的同学可以使用商业地图平台,比如百度地图,去了解现有地图的精度。然后通过深入学习高精地图 。
传统的做法是用双目进行视觉导航,方法如下:左右两个图进来,首先做一个三角成像,就可以得出空间中深度点的信息,每一个特征点都有描述,然后再将前后两帧图像的特征点进行比对,得出其位移的信息,大概能定位到车辆移动的距离。后续技术的发展,实现了单目视觉进行导航的功能,但是图像信息更新率有限——30-60帧/秒之间。所以,为了更快速得到信息更新,还是要将IMU加上,就产生了Visual inertial odometry技术,可以得到很精准的位置更新。
这个就相对简单了,因为轮子周长固定,可以通过圈速来进行距离的测算,但是这个方式的累计误差会比较大,所以也存在很大的问题。
但在实际的实践中,只依赖一种定位技术或传感器,显然无法实现良好的效果。天气、光照、磁场等等,都会干扰这些定位传感器的正常使用。
通过IMU和轮速计,得到车辆初始的位置,而GPS则可以不断纠偏,把错误率控制在一定的范围,比如GPS是厘米级的,那么精度就能保证在厘米级别,同时再加上激光雷达和高精地图的匹配,得出一个最终的很精准的位置。本文下一章有一个小作业,可以帮助各位同学了解传感器融合的基本工作机制。
感知就是理解环境,要做感知,需要的是一个数据集。在无人驾驶行业,有一套通用的数据集——KITTI数据集,里面有不同的数据,包括双目视觉的数据、定位导航的数据等。
传统方法主要是针对固定物体的检测。一般的方法是HOG( 方向梯度直方图),然后再加一个SVM的分类器。而对于动态物体的检测,主要使用的是DPM模型的方法,先把手和脚识别出来,再进行组合。
人行道是一个场景,道路是一个场景,在场景中对不同的物体进行分类,是一个很重要的问题。传统的方法是采用CRF( 条件随机场),基本原理在于图像都是由像素点组成的,若两个像素点都比较像车,那就把二者连接起来,形成对车辆的识别。
另外,就是我们所说的光流(Optical Flow),光流是针对2D图像来说的,如果说一个图片流到另外一个图片,都是2D的物体移动,那就用光流来做。如果是3D的物体流动,那我们就用场景流(Scene Flow),场景流在传统的方法就是使用的是SGBM,利用的是双目成像的技术,把左图和右图合起来提取出空间的点,用光流在上面做,就能把场景的流动分析出来。
这也是无人驾驶中一个比较重要的技术。如何预测行人下一个动作、怎么去跟踪这个行人,也有一系列问题。里面用到的是马尔可夫链的解决方案,这个技术叫做MDP,跟踪一个人,随时跟踪其下一个动作,预测其下一个动作。以上其实都是一些传统的感知方法,而这些年随着深度学习的不断进步,应用也非常广泛。
一个是Faster R-CNN,它会将兴趣点框出来,然后再进行物体识别,找到是不是你想要识别的物体;另一个是更为快速的SSD,也是将图中的物体识别出来。
而在场景分类方面,运用深度学习的方法则使用的是另一种模型,被称为PSPnet(语义分割)。这是金字塔型的场景分解模型,将一个场景不断地压缩,把类似的物体聚类,然后再做判断。
光流也可以利用深度学习的模型来做,把左右两图用同样的模型来提取特征,经过计算就能得出一个深度的信息。但是这个方式的计算量非常大。对感知有兴趣的同学可以学习一下OPENCV以及基本的卷积网络识别例子,比如基于LENET的数字识别。
决策和控制(Planning and Control)
这是一个最基本的决策和控制的架构,但这个部分其实是无人驾驶中最难的部分。
最上方的感知系统可以感知行人的位置、速度及态势,然后将这些信息传送给预测模块,预测行人是往前还是往后,速度多快。而下方的定位数据流进来之后,全局的路径规划模块就会将这些路径传入到最核心的控制决策模块——其中包括行为决策、动作决策和反馈控制。最后,这些信号会传送给CAN-BUS,由车辆来执行。
交通预测其实可以分成两个问题:一个是分类问题,另一个是回归的问题。分类问题要了解的是行人到底是过马路还是不过马路,回归问题就更复杂一些,如果行人是过马路,那么针对其过马路的速度是多少,需要做一个预测。 路径规划也是比较有趣的,因为这对无人车来说是一个比较特殊的问题,因为对于普通的车辆来说,只要知道这是哪条路就行了,而不需要知道这是哪一条车道。
因为每条路都有不同的车道,那我们把车道标出不同的节点,不同的节点连接在一起,就变成了一条车道。通过某种方式(Dijkstra和A*)找到最短车道,就能得到最优解。
有了全局的路径规划以后,我们就需要进行行为决策。因为道路场景非常复杂,可以分成几十个不同的场景——左右车道、丁字路口等等,需要做场景组合决策。
然后是动作的规划,包括加速、减速、转向等等,速度规划主要使用了ST-graph工具来做,路径规划主要是动态编程来实现。
而最后的反馈控制则是由车厂来做,而且很多车厂采取的方案是不一样的。实现反馈控制的一般有双轮模型和PID控制模型,后者实现起来比较顺畅。
对决策感兴趣的同学可以学习一下基础的A* 算法实现。
端系统(Client System)
任何一个复杂的系统都需要一个操作系统来辅助它实现功能,这样才不至于混乱。
如上图所示,在处理器中,其实运行了上文所述的各类算法,包括感知、定位、全局路径规划等算法。然后再实现对车辆本身的控制,包括动作控制、方向控制。
首先我们需要一个操作系统来管理这么多复杂的工作,现在大部分厂家用的都是ROS——机器人操作系统,当然都做了一些个性化设计。这是一个信息传递的系统,可以通过点对点的传输形式或是广播的形式来做信号传输的动作。
单一主节点,很容易整体崩溃。(解决方案:可以用Zookeeper机制来做,设置多个主节点。)
通信非常低效。(解决方案:可以用共享内存的方法来做。)
不是很安全,比如开一个恶意节点不断去损耗资源,很容易造成整体系统的崩溃。(解决方案:这个问题可以使用Linux Container的技术来解决。)
硬件平台当然也是不可或缺的。其前端有很多传感器,信号传输进来后,有一个计算平台进行接收,处理完成后再通过CAN-BUS,把控制信号传给车辆控制系统。
以往很多时候,无人驾驶汽车上都放了两台计算机进行数据处理。这样带来的问题是功耗高,散热问题非常难以处理。未来,计算单元小型化会是很大的挑战。
云平台(Cloud Infrastructure)
如今,很多人都关注无人驾驶的终端,而对于云平台没有给予足够的重视,实际上这块内容是非常重要的。无人驾驶车辆每秒最多可以产生2GB的裸数据,怎样利用这大量的数据去帮助无人驾驶做得更好,怎么样去搭建一个云平台去更好地服务无人驾驶的作业,这是个很大的挑战。
云平台底层就是存储和计算。我们有一个开源的项目叫做Alluxio,基本上就把磁盘存储给管理起来了,这是一个分布式的存储管理器;在其上,我们运用了异构计算,不同的作业依赖的处理器也不一样,所以会有GPU、CPU和FPGA;当然,为一个处理器写一套单独的程序,太复杂了,所以在其上统一搭载了OpenCL,对程序进行统一管理;分布式计算也需要一个管理平台,我们采用了Spark平台——比较通用、功能很多。再在这个平台上搭建高精地图、模拟计算和模型计算等作业。
在计算层面,我们运用了Apache Yarn这个分布式系统管理器通过Spark把作业分发下去,每个Spark的节点都有多个容器(Container),容器上会跑一些 OpenCL 的 Kernel,OpenCL 可以跑在 GPU 上,也可以跑在FPGA上。这个平台的可扩展性非常强,模型训练所需的时间会随着GPU数量的增加而线性减少。
首先是模拟计算。比如你新开发了一个程序,想要试试新的算法是不是好用,但是不可能每次都实车验证,因为成本高,而且覆盖的场景很少。所以一般采用的是模拟计算的方式:游戏平台和真实数据回放,更多是采用后者的形式。这里有一个问题,单机回放必须要回放实际的数据,比如谷歌无人车累计有8年的数据,如果单机计算需要很长时间,这显然不可取。所以这里采用了Spark Driver的系统,可以并行处理,把作业分发下去,通过Linux pipe把每一个ROS Node节点打出来做一个回放,数据再回收到Spark Driver里去。只要给的节点够多,几十分钟就可以验证一套算法。
第二个是高精地图的制作。这是个很复杂的工作,首先是裸数据,然后从裸数据得出一个点云的数据,点云和点云之间要做一个对齐,对齐之后要把反射率的数据填到里面,然后再加一些语义的信息等。用分布式平台来做高精地图的生产,最大的计算量部分集中在点云的生产和对齐上,用异构计算可以很好地完成这些作业。
如开篇时说的,许多技术方向的同学对人工智能既爱又畏惧,一方面觉得这是未来,另一方面又觉得很难而不敢触碰。本章我们探讨一下如何为投身无人驾驶行业做好准备。
当前的人工智能热潮是一次大的技术革命,对广大技术人员来说是个特别好的机会,但是如果只掌握一个技术点是不足够的。根据过去几年的经验,在技术行业隔行如隔山,比如做算法的对软件设计未必熟悉,专注做软件的很少懂系统,而懂系统的了解硬件的也不多。反过来也一样,让一个硬件工程师去写软件,他可能会觉得很难而不敢触碰。但是如果他能静下心来花点时间去学一下,其实这并没有想象中那么难。我在工作以及创业的过程中,发现能跨跃几个细分行业(比如软件、系统、硬件)的工程师非常难得也非常有价值。通常可以跨跃几个细分行业的人都比较有好奇心,也有勇气去尝试新的东西。所以我觉得入门最重要的条件不是熟悉某个技术点,而是要有足够的好奇心与克服困难的勇气。
今年初,大家都觉得无人驾驶技术很神秘,于是我与几位无人驾驶行业的朋友一起写了《第一本无人驾驶技术书》。之所以是第一本,是因为这是一本入门级别的介绍书,让对无人驾驶行业有兴趣的同学对这个行业所涉及的技术点可以有快速的全面的了解。无人驾驶是一个复杂的系统,涉及的技术点种类多且跨度大,入门者常常不知从何入手。本书首先宏观地呈现了无人驾驶的整体技术架构,概述了无人驾驶中涉及的各个技术点。在读者对无人驾驶技术有了宏观认识后,本书讲解了无人驾驶定位导航、感知、决策与控制等算法,深度学习在无人驾驶中的应用,无人驾驶系统软件和硬件平台,无人驾驶安全及无人驾驶云平台等多个主要技术点。
在有了入门的知识并完成入门小作业后,大家会对整个无人驾驶的技术框架比较了解,这个时候就需要更深入的了解每个技术点。为了让读者更深入了解无人驾驶技术,我们花了很多时间梳理了当前无人驾驶使用到的技术点,在美国出版了《Creating Autonomous Vehicle Systems》,这本书被IEEE推荐为无人驾驶教材,已经被美国多个大学的图书馆收录。这本书与《第一本无人驾驶技术书》最大的不同是每个技术点我们会比较深入的去解释,还会提供许多论文的引用,当读者对某个技术点特别感兴趣时,有足够的文献让读者去深入研究。
如果同学需要了解不同GPS技术的细节,本书深入讲解了为什么我们常用的GPS会有比较大的误差,以及RTK GPS以及PPP GPS技术如何去降低误差。如果同学需要了解不同视觉感知的技术,本书也深入讲解了SSD以及PSPNET等的网络实现。
关于这本书说涉及的技术点的视频讲解可见下面的链接:
https://www.youtube.com/watch?v=B8A6BiRkNUw&t=26s
https://www.youtube.com/watch?v=4M2m9Wm3Roo&t=418s
https://www.youtube.com/watch?v=KzPFJ-GE8uM&t=138s
https://www.youtube.com/watch?v=5hWNP-8V22c&t=240s
https://www.youtube.com/watch?v=GhkfLXfAVNo&t=50s
https://www.youtube.com/watch?v=yDrbJ7CC20I&t=59s
https://www.youtube.com/watch?v=VrZ_uGESviM
https://www.youtube.com/watch?v=qVX2mSvKHR8&t=3s
光说不练是不行的,在掌握了入门的技术框架后,希望大家完成一个小作业,测试下自己对无人驾驶技术的了解与兴趣。
时间同步
GPS定位
IMU位置跟踪
特征点提取
立体视觉
第一步取原数据:写一个ANDROID程序实时获取当前GPS数据,IMU数据,以及图片数据,在每个数据上打精准时间戳 (入门难度)。
第二步在根据原数据推算出每个图片的位置信息(中等难度)。
第三步在把每个图片的特征点提取出来,估算出每个特征点的粗略位置(进阶难度)。