百度最近发布了最新的Apollo3.0,以及和Udacity一起开发的一个系列简单的自动驾驶入门教程,教程的内容不深,但对于想入门自动驾驶的人来说是不错的学习资料。在接下来的一段时间,我会慢慢把自己的学习笔记以博客的形式记录下来。
首先简单介了自动驾驶的基础,感知,定位,规划,控制,这个在后续的课程里还会继续深入。
然后是百度自己无人车的软硬件平台。
计算中心:就是整套系统大脑了,使用的是Neousys Nuvo-6108GC,这是一款性能强大的X86解构工业控制计算机,强大到什么程度呢?支持至强E3和I7,支持GTX1080显卡,玩游戏的朋友都知道这款显卡,强大的性能我就不多说了,所以比较适合用来做自动驾驶。
CAN通讯卡,用来和汽车进行通讯以控制汽车的加速、制动、档位、方向等信号,使用的是ESD CAN-PCIe/402-B4,CAN卡直接插在主机内。
GPS和IMU:定位系统和惯性制导,当然就是用来进行GPS定位和惯性定位,使用的是NovAtel SPAN-IGM-A1或者NovAtel SPAN® ProPak6™ and NovAtel IMU-IGM-A1,通过串口连接主机。
激光雷达:扫描距离达到120米,水平360度扫描,垂直FOV26.9度,型号为Velodyne HDL-64E S3,通过以太网连接计算中心。
摄像头:用于视觉,Leopard Imaging LI-USB30-AR023ZWDR with USB 3.0 case,通过USB连接主机。
毫米波雷达:用于探测前方,安装在车辆前端,为大陆集团的ARS408-21,连接至CAN卡。
除去以上这些,还需要鼠标键盘显示器,当然就是平常用的那种。
Apollo 的 Open Software Platform 分三个部分 RTOS,Runtime Framework 及各个功能模块 Modules。
Apollo RTOS的主体部分是为 Ubuntu 14.04 + ApolloAuto/apollo-kernel 的组合。 Apollo 安装指南上推荐的在工控机上安装的软件及版本如下表所示。
IPC 安装的软件
Apollo-kerne 的存在是因为 Ubuntu 并不是一个实时系统。
实时系统的定义如下:
实时操作系统(RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,调度一切可利用的资源完成实时任务,并控制所有实时任务协调一致运行的操作系统。提供及时响应和高可靠性是其主要特点。[ 实时操作系统_百度百科]
百度自动驾驶资深架构师何玮之前做过一个演讲,https://mp.weixin.qq.com/s/nYVuqYvUBdBJ84EdNaF1dQ, 详细的阐述了 Apollo 对 ROS 的做的改动。
自动驾驶系统非常复杂,包含感知、障碍物检测、决策、车辆控制等模块,把这么多功能各异的模块集成在一起,组成一个完整的系统并完成自动驾驶的任务,这是一个非常大挑战。
通信性能优化
问题:自动驾驶大量使用传感器引发很大的传输带宽需求,单路传感器消息有多个消费者时负载成倍增长
自动驾驶系统为了能够感知复杂的道路情况,需要多种传感器协同工作才能覆盖不同的场景、不同路况需求。多传感器共同使用会对车载系统造成很大压力。
解决优化:共享内存能减少传输中的数据拷贝,显著提升传输效率,共享内存可以有效满足一对多的传输场景
共享内存本身的特性能够支持一次写入、多次读取功能。对于一对多传输场景,不同的使用者就可以同时读取,实现一次写入,多次读取的功能,成倍提升传输效率。
去中心化的网络拓扑
ROS特点:ROS以Master为中心构建hybridp2p拓扑网络, 以Master为中心构建Hybrid p2p拓扑网络,带来了比较强的容错性,当某个算法出现异常导致崩溃的时候,不会引起整个的异常,为局部异常处理提供便利。
整个系统非常依赖Master这个单点,一旦Master异常,所有节点都不能发现其他节点,这样整个系统就不能正常工作。
在ROS中添加基于RTPS服务协议功能,网络构建不会以Master作为中心,而是通过域概念作为划分,所有节点加入域中,会通过RTPS协议相互广播通知其他节点,然后节点间会建立点对点连接,来发布订阅消息,以替代Master作为中央信息交换的功能。
数据兼容性扩展
Message是ROS中描述接口的一种语言,当两个节点之间需要建立连接的时候,通常需要满足两个条件。一是接收和发送的Topic属于同一个话题,二是两个模块定义的模式要完全一致。
ROS怎么定义message?ROS使用msg文件对数据接口进行抽象化的描述,并可以生成不同语言的接口实现,以满足不同语言的通信交流需求。但问题是接口升级后,不同版本的模块难以兼容。兼容性的问题,当项目规模比较小时,影响不大;但是对于无人自动驾驶比较庞大的项目时,影响就很大。当某一个模块接口升级了,需要把所有相关模块升级到最新版本之后,才能在一起进行基础功能的连调。同时对于线下仿真调试的时候,有时需要把某一个模块回到历史版本验证或定位某一个问题,这时候若接口之间出现升级,就会出现不兼容问题,导致系统运行障碍。
接口兼容性问题会对历史数据使用造成更大影响,自动驾驶汽车系统中历史数据是非常宝贵和重要资源,对于这种问题有一些解决方式,一是通过离线数据批量转换和在线方式,二是转换成新数据。
使用protobuf来替代ROSmessage,最大好处是可以完全覆盖message中本身包含的类型,有利于把既有的ROSmessage迁移到protobuf格式下。此外protobuf有非常好的版本兼容性。在Apollo ROS中,做了一整套对protobuf的支持, 在工程中可以不需要做protobuf和ROS message的转换,直接publish protobuf格式的消息,调试工具也能够非常正确的解析出来正确的protobuf消息。这样既能够很好解决兼容性问题,也不会产生额外的学习成本和使用成本。
模块
各个功能模块的实现是 Apollo 代码的一个重点。
模块的详细介绍,参考了https://zhuanlan.zhihu.com/p/32511462和https://zhuanlan.zhihu.com/p/29723447
所有核心模块的源码都集中在modules目录中,打开modules目录,有以下17个模块
- common:公共源码模块如日志,工厂模式的实现,日志系统,监控模块,数学算法等。
- drivers:GNSS设备驱动,包括NovAtel, Applanix, u-blox.激光雷达velodyne驱动,用来读取传感器内容并输出对应的消息。
- calibration: 传感器标定文件及标定数椐检测脚本,目前只看到激光雷达想着的标定文件
- control:控制模块,基于决策规划的输出路径及车身的状态使用不同的控制算法来输出控制命令,如转向刹车,控制等。
- canbus: 接收控制指令,同时给控制模块control发送车身状态信息。
- planning:决策规划模块,apollo1.0中决策各规划是分开的模块decision和planning模块,现在decision模块合并在planning里了。
- routing:全局导航模块,输入包括地图信息各起点终点地址,输出一个全局的导航信息。
- prediction:预测模块,输出感知的障碍物信息及自定位信息输出障碍物未来的轨迹。
- localization:定位模块,输入GPS和IMU信息输出自车定位信息。
- map:高精地图模块,输出结构化地图信息,如车道线,十字路口等。
- perception:感知模块,输入激光点云,高精地图,变换坐标,输出3D障碍物包括速度大小和方向。
- hmi:人机交互模块,http服务利用浏览器可查看及更改一些配置及启动某些节点。
- dreamview:可视化模块,查看规划的轨迹及实时的转向刹车油门信息。
- monitor:监控模块,监控硬件状态,同时把状态发给hmi
- tools:工具模块,包括一些可视化的工具,bag包录制及回放脚本
- e2e:端到端模块,Apollo1.5新增模块,完全独立的模块,运行在ubuntu16.04及ros kinetic上,用catkin_make编译。
- elo:利用高精地图的自定位模块,Apollo1.5新增模块,完全独立的模块,无源码只有.so文件,单独的运行环境,固定在运行在NVIDIA Drive PX2 (PDK 4.1.4.0)Ubuntu16上.利用训练好的caffe模型来检测车道线和有精确坐标的高精地图匹配从而实现定位,依赖一个粗精度低成本的gps及摄像头这两个传感器。
根据这些模块,可以大概看出整体流程了:
首先,用户输入目的地,routing模块就可以根据终点位置计算出具体的导航信息。激光雷达、毫米波雷达和摄像头拍摄到的数据配合高精度地图由percepting模块计算出3D的障碍物信息并识别交通标志及交通信号,这些数据进入perdiction模块,计算出障碍物的可能轨迹,如此就可以结合以上信息并根据车辆定位模块localizationg提供的车辆位置由planning模块得到车辆应该走的具体车道。
得到车道后车辆control模块结合车辆的当前状态计算加速、刹车和方向的操作信号,此信号进入CAN卡后输出到车内,如此实现了车辆的自动驾驶。
在整个流程中,monitor模块会及时监测硬件及系统的健康状况,出现问题肯定就会中止驾驶过程。对于驾驶中的信息,用户可以通过web应用dreamview来查看,下图就是实际驾驶过程中的dreamview界面。
最后是百度的云端服务