百度-Apollo自动驾驶入门课程 课后笔记
本文是对百度 Apollo 自动驾驶入门课程的的脉络整理笔记,仅用于个人学习记录。
新人之旅
自动驾驶关键技术(Key technique in self-driving)
- 环境感知 (perception)
- 精确定位 (localization)
- 决策规划 (prediction&planning)
- 线控执行 (wireness control)
- 智能交互 (human machine interface)
- C-V2X (cellular vehicle to everything)
自动驾驶所需人才(Talent)
专业领域+跨界复合型人才
(1) 人工智能算法:感知,定位,决策规划等算法工程师
(2) 软件工程技术架构(及时可靠的系统框架+研发云平台):C++ 车端工程、仿真云服务工程师、上机仿真工程师,实车试验工程师,数据工程师
(3) 硬件车辆:域控制工程师、结构设计工程师、硬件设计工程师
Apollo 开源平台
学习路线
- 上机学习
- 实时框架 CyberRT
- 掌握 CyberRT 开发工具,使用其 API 进行 Apollo 开发
- 通过 CyberRT 了解分布式系统开发的模式,了解 CyberRT 的 Talker/Listener、Service/Client、Parameter Service 三种通信模式
- 掌握 Cyber Monitor、Cyber Visializer 等工具
- 决策与规划 Dremview/Dreamland
- 了解 Apollo 决策规划流程和算法
- 使用 Dreamview 进行控制在环的规划调试
- 基于 Apollo 开发新的规划场景和算法
- 使用 Dreamland 进行控制在环的规划仿真评测
- 感知 Dremview/Visualizer
- 通过 Apollo 的传感器原始数据集了解传感器特性
- 通过源码和文档了解 Apollo 感知流程及算法
- 使用 Dremview/Perception Visualizer 进行开发调试
- 通过模型部署想到扩展部署新的感知模型
- 通过模型验证工具链扩展训练新的感知模型并验证
- 实时框架 CyberRT
- 上车实践:解决车辆闭环和集成验证问题
- 线控协议-车辆适配工具链
- 了解 Apollo 线控标准
- 开发符合 Apollo 要求的线控车辆和 DBC
- 开发与车辆通信的 canbus 驱动
- 使用 teleop 开环验证车辆
- 集成-Fuel云服务/D-KIT
- 学习传感器布置与链接
- 了解车辆标定与传感器标定
- 了解循迹原理
- 通过循迹实现控制与线控实车闭环验证
- 决策与规划-Dreamview/D-KIT
- 了解车辆安全操作
- 了解基础测试流程和实车数据录制
- 了解实车控制调参
- 了解实车定位调试
- 线控协议-车辆适配工具链
Apollo 概览
Apollo 技术框架
Apollo 技术框架由四个层面组成,参考车辆平台、参考硬件平台、开源软件平台、云服务平台,其中主要模块包括高精度地图、定位、感知、预测、规划、控制等模块。
- 高精地图:几乎支持着软件栈的所有其他模块,尤其是定位、感知、规划和决策。
- 定位:车辆如何确认所在位置。车辆利用激光和雷达数据,将这些传感器感知内容与高分辨率地图进行对比,这种对比使车辆能够以个位数厘米级精度进行自定位。
- 感知:无人驾驶车如何感知这个世界,深度学习是一个重要且强有力的感知工具,卷积神经网络构成深度学习分支,对感知任务至关重要,如分类、检测和分割。
- 预测:预测其他车辆或行人可能如何移动。一种方法称为递归神经网络,可对其他物体随时间的运动进行跟踪,并使用该时间序列数据预测未来。
- 规划:结合预测与路线生成车辆轨迹,是构建无人驾驶车最困难的部分之一。
- 控制:通过转向、油门和制动来执行规划轨迹。不同的控制器从简单到复杂,其性能却从弱到强。
为什么需要无人驾驶?
- 安全。全球每年有超 100 万人死于车祸 。
- 可靠。无人驾驶车不会向人类一样分心、疲惫以及犯一些其他不必要的错误。
- 学习能力极强。无人驾驶车可以向路上行驶的其他无人驾驶车学习,也可以从自身的经验中学习,“富有经验”的驾驶员。
- 没有停车麻烦。
无人驾驶分级
- L0:驾驶员完全控制
- L1:驾驶员辅助(Driver Assistance),需要驾驶员充分参与,但可放弃自治系统的控制;
- L2:部分自动化(Partial Automation),自动控制巡航以及保持车道,但是驾驶员仍然必须执行自治系统处理的任何功能。
- L3:有条件的自动化(Conditional Automation),车辆自主驾驶,但驾驶员必须准备在必要的时候随时接管。
- L4:高度自动化(No Human Interference),车辆不期望驾驶员介入,可能没有控制装置,但是车辆可能被限制在某些区域,通常这被称为“地理围栏”,车辆可以在特定的地理围栏内完全自主的运行,但是在地理围栏之外,车辆不能自主操作,或者根本无法操作。
- L5:完全自动化(Full Automation),车辆可以在人类可以驾驶的任何地方完全自主地运行,在所有情况下应与人类驾驶员的水平一样高或比其更高。
无人驾驶车核心部件
无人驾驶车包括 5 个核心部件,计算机视觉、传感器融合、定位、路径规划、控制。本质上来讲,其他一切无人车都是这些核心功能更复杂的实现。
- 计算机视觉:通过摄像头图像捕获周围世界的信息。
- 传感器融合:合并来自其他传感器的数据(如激光、雷达)从而更加深入了解周围环境。
- 定位:通过对环境的了解精确地确定车辆所处位置。
- 路径规划是绘制车辆所在位置与目标地点的行驶路线。
- 控制是使汽车保持在规划的轨道上行驶。
参考车辆和硬件平台
- 参考车辆平台
- 线控驾驶车辆:一款可通过电子控制的基础车辆,不仅是通过实体方向盘、油门踏板和刹车踏板来控制
- 硬件平台
- 控制区域网络(CAN):车辆的内部通信网络,计算机系统通过CAN卡连接汽车内部网络发动加速、制动和转向信号
- 全球定位系统(GPS):通过绕地卫星接收信号,这些信号帮助确定位置
- 惯性测量装置(IMU):测量车辆的运动、位置,通过跟踪位置、速度和加速度等其他因素
- 激光雷达(LiDAR):由一组脉冲激光器组成,Apollo使用激光雷达可360度扫描车辆周围,通过激光束的反射形成软件可用于了解环境的点云
- 摄像头:捕获图像信息,可以使用计算机视觉来提取这些图像的内容并了解周围环境,例如,摄像头可以感知颜色,用于检测和了解交通灯
- 雷达:用于检测障碍物,雷达分辨率低,难以检测障碍物类别,但雷达的优势在于经济实惠,适用于各种天气和照明条件,雷达擅长测量其他车辆的速度
开源软件架构
开源软件架构 分为三个子层 :实时操作系统、运行时框架和应用程序模块层。
- 实时操作系统(RTOS)可确保在给定时间内完成特定任务,
- “实时”是指无人驾驶车的操作系统能够及时进行计算、分析并执行相应操作,这些使在汽车传感器收集到外界数据后的短时间内完成的。实时性能是确保系统稳定性和驾驶安全性的重要要求。
- Apollo RTOS 是 Ubuntu Linux 操作系统与 Apollo 内核相互结合的成果。
- 运行时框架 是 Apollo 的操作环境,是 ROS 的定制版,即机器人操作系统,实际上是一个在Apollo RTOS上运行的软件框架。ROS 根据功能将自治系统划分为多个模块,每个模块负责接收、处理和发布自己的消息,这些模块相互独立,只能通过运行时框架进行通信,因此调整任一单一框架都很容易。为使 ROS 适应无人驾驶车,Apollo 团队改进了共享内存的功能和性能、去中心化和数据兼容性。
- 共享内存:降低了需要访问不同模块时的数据复制需求。对于一对多的传输方案,共享内存支持“一次写入,多次读取”模式,这样可以加快通信速度。例如,收到一次点云,可以同时进行障碍物检测、定位和GUI工具。
- 去中心化:解决了单点故障问题。现成的 ROS 由许多节点组成,每个节点有其对应的功能,所有节点都需要由单个 ROS 主节点来控制,主节点故障,则整个系统失效。为了避免这一问题,Apollo 将所有节点放在一个公共域中,域中的每个节点都有关于域中其他节点的信息。通过这种去中心化的方案,公共域取代了原来的 ROS 主节点,因此消除了单点故障风险。
- 数据兼容性:无人驾驶车本身的项目规模很大,不同的 ROS 节点通过名为 ROS 信息的接口语言相互通信,ROS 信息需要使用通用接口语言,使每个节点都可以解读来自其他节点的消息数据,如果消息文件格式与节点所期望的格式稍有不同,通信会失败,导致严重的兼容性问题。为了解决这一问题,Apollo 团队使用 protobuf 接口语言来代替原生 ROS 信息。Protobuf是一种结构化数据序列化方法,这对开发用于通过电线通信或用于存储数据的程序非常有用,可以将新字段添加到信息格式中而不破坏后向兼容性,新的二进制文件可以在解析过程中接收旧的消息格式。
- 应用程序模块:Apollo软件平台有各种模块,包括 MAP 引擎、定位、感知、规划、控制、端到端驾驶以及人机接口(HMI),每个模块有自己的算法库,模块之间的关系很复杂。
仿真环境平台
仿真环境平台 是Apollo开放软件栈的重要工具,该平台允许每个人出于自身需要来构建仿真环境,该平台还聚合了大量驾驶数据,使开发人员能够检验和验证无人驾驶软件系统。
- 允许开发人员配置不同的驾驶场景。比如障碍物、路线和交通灯状态。
- 执行模式为开发人员提供了一个在多个场景中运转的完整模式。在执行模式中,开发人员可以在Apollo环境中上传和验证模块。
- 自动评分系统,从几个指标对场景进行评估,其中包括:碰撞检测、交通灯识别、速度限制、障碍物检测和路线逻辑。
- 三维可视化描述了实时路况,在显示无人驾驶车状态的同时,使模块输出可视化。
- 无人驾驶数据可能来自模拟场景或道路测试,Apollo为这些类别提供了各种各样的数据。仿真场景数据有两个不同的来源:记录场景和虚拟场景。可以使用记录场景重放在实际道路测试中已经观察到的传感器数据,可以借助虚拟场景使用编辑器创建新的驾驶场景,这有助于快速检验与验证算法。
高精地图
高精度地图与传统地图的区别
- 传统地图:车载地图、手机地图,输入某个目的地它可以帮助你找到正确的路径,引导你走向目的地,其精度在米级。
- 高精度地图:机器人环境中的地图,可以准确记住每一个车道、标志,同时为无人驾驶车提供精确的定位,包含大量的驾驶辅助信息,如道路网的精确三维表征、交叉路口标志等,其精度可达到厘米级。
地图与定位、感知和规划的关系
- 定位:无人驾驶首先要找到的就是自己在这个环境中所处的位置,这是一个识别与匹配对比的过程。无人驾驶车辆在地图中的某个点,使用摄像机、激光雷达等设备可以感知周围环境,形成图像与点云数据,经过处理后可形成一个具有该位置某些特征(如地表建筑)的地图块,然后将该地图块与高精度地图进行对比匹配,即可确定车辆具体在哪个地点。
- 感知:无人驾驶车辆使用摄像机、激光雷达、雷达等传感器在探测物体时都有距离限制,尤其是在夜间或恶劣天气条件下,传感器的检测能力会受到进一步的限制。在传感器检测到障碍物时,车辆无法直到障碍物之后的具体情况,这个时候高精度地图则可以将如交通信号灯、道路标识等传感器当前无法探知的道路信息传送给系统,帮助做下一个决策。此外,高精度地图可以帮助传感器缩小检测范围,比如当我们想停车时,高精度地图可以先将可停车的区域信息传送过来,车辆则只需要在那一部分区域内进行寻找,提高了检测的准确度和效率也节省了计算资源。
- 规划:高精度地图本身包含如限速、变道等行车信息,可以帮助车辆找到合适的行车空间,快速的为车辆找到最合适的行车路线。
高精度地图构建
高精度地图构建主要有5个过程:数据收集、数据处理、对象检测、手动验证、地图发布。
- 数据收集:无人驾驶地图需要时刻保持更新,Apollo地图主要是通过将所有无人车辆通过摄像机、IMU、GPS等传感器收集的地图信息进行汇总处理以保持地图的实时更新。
- 数据处理:主要是对收集到的数据进行处理、分类、清洗以获得准确的图像或点云数据。
- 对象检测:使用人工智能对处理后的数据进行静态检测并分类,如识别车道线、信号标志等
- 手动验证:主要是及时发现自动地图创建过程中可能产生的问题。
- 地图发布:经过上述步骤后,地图则可发布。
定位
GNSS RTK
三角测量:自身所处的位置可以通过自身与不在同一条直线上的3个静态参考物的相对距离确定。
GPS的工作原理:只是以卫星为参考系,三颗卫星和另一颗定位高度的卫星,4颗卫星就可以自定位。这类系统的通用名称是全球导航卫星系统或 GNSS,GPS 是使用最广泛的 GNSS 系统。
GPS 接收器实际上并不直接探测自身与卫星之间的距离,它首先测量信号的飞行时间即信号从卫星传播到GPS接收器所需的时间,通过将光速乘以这个飞行时间来计算离卫星的距离。由于光速的值很大,即使是少量的时间误差也会在距离计算中造成巨大的误差。因此每颗卫星都配备了高精度原子钟。
实时运动定位(RTK):RTK 涉及在地面上建立几个基站,每个基站都知道自己精确的“地面实况”位置,并且每个基站也通过 GPS 测量自己的位置。已知的“地面实况”位置与通过 GPS 测量的位置之间的偏差,为 GPS 测量结果中的误差。然后将这个误差传递给其他 GPS 接收器以供其调整自身的位置计算。在 RTK 的帮助下,GPS 可以将定位误差限制在 10 厘米以内。
GPS 存在的缺点:(1) 高楼或其他障碍物可能遮挡GPS信号;(2) GPS的更新频率很低,大约为10Hz。而无人驾驶车处于快速移动时,需要更频繁地更新位置。
惯性导航
已知汽车的初速度、加速度、行驶时间、初始位置,就可以通过计算得到任意时刻后汽车的速度和位置。
三轴加速计提供瞬时加速度,三轴加速计有三种不同类型,采用的方法也不同。加速度计提供的不仅是加速度,还测量了重力加速度,所以用的时候需要先把重力加速度剔除掉。加速度计根据车辆的坐标系记录测量结果,还需要陀螺仪传感器将测量值转换为全局坐标系测量值。
三轴陀螺仪提供瞬时角速度,三个外部平衡环一直在旋转,但三轴陀螺仪中的旋转轴始终固定在世界坐标系中。在坐标系中的位置是通过测量旋转轴和三个外部平衡环的相对位置来计算的。
IMU 的工作过程:加速度计和陀螺仪是惯性测量单元(IMU)的主要组件。首先是角速度通过积分后得到一个姿态,并把它应用到加速度上,对加速度积分得到速度,再得到最后的位置。
- 优点:
- (1) 可以得到 6 自由度信息;
- (2) 短时精度高;
- (3) 十来万级别的设备,可以坚持五六百毫秒。
- (4) 输出频率高、无延迟;
- (5) 可以以高频率更新,基本上都是200 HZ以上,可以提供接近实时的位置信息。因为它有精准的时间戳,它检测的数据传输过来之后可以精准知道它的时间戳,有精准的时间戳就可以给出精准的位姿,即它在全局坐标系下有自己的位置。
- (6) 无外部依赖;
- 缺点
- 运动误差随时间增加而增加,所以只能依靠惯性测量单元在很短的时间范围内进行定位。
如果结合 GPS 和 IMU 来定位汽车,一方面 IMU 弥补了 GPS 更新频率较低的缺陷,另一方面 GPS 纠正了 IMU 的运动误差。但是 GPS 和 IMU 系统的结合也不能完全解决定位问题,如果车辆在山间行驶或城市峡谷中或在地下隧道中行驶,可能长时间没有 GPS 更新,使得定位失败。
Lidar 激光雷达定位
利用激光雷达,可以通过点云匹配来对汽车进行定位。该方法将来自激光雷达传感器的检测数据与预先存在的高精度地图连续匹配,通过这种比较可获知汽车在高精度地图上的全球位置和行驶方向。
匹配点云的方法
- 迭代最近点(ICP):对于第一次扫描中的每个点,需要找到另一次扫描中最接近的匹配点,最终会收到许多匹配点对, 把每个点的距离误差相加,然后计算平均距离误差。当对两次点云扫描进行匹配,目标是通过点云旋转和平移来最大限度地降低这一平均距离误差,就可以在传感器扫描和地图之间找到匹配,将通过传感器扫描到的车辆位置转换为全球地图上的位置并计算出在地图上的精确位置。
- 直方图滤波算法(误差平方和算法 SSD):将通过传感器扫描的点云滑过地图上的每个位置,在每个位置上计算扫描的点与高精度地图上的对应点之间的误差或距离,然后对误差的平方求和,求得的和越小扫描结果与地图之间的匹配越好。
- 卡尔曼滤波:根据过去的状态和新的传感器测量结果预测当前的状态。卡尔曼滤波使用了预测更新周期,首先根据之前的状态以及对移动距离和方向的来估计新位置。运动估计并不完美,所以需要通过使用传感器测量位置并加以纠正。一旦传感器测量了新位置,便可以使用概率规则将不完美的测量结果与现有位置匹配起来。只要需要对车辆进行定位,先预测新位置,然后用传感器测量位置,将会永远遵循这个预测更新周期。
LiDAR定位的主要优势在于稳健性,只要从高精地图开始并且存在有效的传感器,就始终能够进行定位。主要缺点在于难以构建高精地图并使其保持最新,事实上几乎不可能让地图完全保持最新,因为几乎每个地图均包含瞬态元素,汽车、行人、停放的汽车、垃圾等。
视觉定位
图像是要收集的最简单的数据类型,摄像头便宜且种类繁多、易于使用。
通过图像实现精确定位却非常困难,实际上摄像头图像通常与来自其他传感器的数据相结合以准确定位车辆,将摄像头数据与地图和 GPS 数据相结合,比单独使用摄像头图像进行定位的效果更好。
假设一辆车正在路上行驶,感知到右边有树,但是地图显示道路右侧有几棵树有很多不同的点位置,但这样可以排除右边没有树的点。继续前进发现右边又出现一棵树,这样就可以排除右边只有一颗树的点。继续这个过程,通过观察结果、概率和地图来确定最可能的位置,这个过程称为粒子滤波,即用粒子或点来估计最可能的位置。
Apollo定位
Apollo使用基于GPS、IMU、激光雷达的多传感器融合定位系统,这种方法利用了不同传感器的互补优势,也提高了稳定性和准确性。
Apollo定位模块依赖于IMU、GPS、激光雷达、雷达、高精地图,这些传感器同时支持 GNSS 定位和 LiDAR 定位,GNSS 定位输出位置和速度信息,LiDAR 定位输出位置和行进方向信息。
融合框架通过卡尔曼滤波将这些输出结合在一起。卡尔曼滤波建立在两步预测测量周期之上,在Apollo中,惯性导航解决方案用于卡尔曼滤波的预测步骤,GNSS 和 LiDAR 定位用于卡尔曼滤波的测量结果更新步骤。
Apollo 定位
感知
无人驾驶车有四个感知世界的核心任务:
- 检测 Detection——指找出物体在环境中的位置;
- 分类 Classification——指明确对象是什么;
- 跟踪 Tracking——指随时间的推移观察移动物体;
- 语义分割 Segmentation——将图像中的每个像素与语义类别进行匹配,如道路、汽车、天空。
分类器步骤:
- 首先计算机接收类似摄像头等成像设备的输入。
- 通过预处理发送每个图像,预处理对每个图像进行了标准化处理,常见的预处理包括调整图像大小、旋转图像、将图像从一个色彩空间转换为另一个色彩空间,比如从全彩到灰度,处理可帮助我们的模型更快地处理和学习图像。
- 提取特征,特征有助于计算机理解图像,例如将汽车与自行车区分开来的一些显著特征。
- 这些特征被输入到分类模型中。此步骤使用特征来选择图像类别,例如分类器可以确定图像是否包含汽车、自行车、行人、不包含这样的对象。
图像数据
- 摄像头图像:最常见的计算机视觉数据
- 数字图像全部由像素组成,其中包含非常小的颜色或强度单位,每个像素都是一个数值。
- 彩色图像被构建为值的三维立方体,每个立方体都有高度、宽度和深度,深度为颜色通道数量。
- 大多数彩色图像以三种颜色组合表示红色、绿色、蓝色,称为 RGB 图像。RGB 图像的深度值是 3。
- LiDAR 图像:环境的点云表征
- 激光雷达传感器使用光线尤其是激光来测量与环境中反射该光线的物体之间的距离,激光雷达发射激光脉冲并测量物体,通过计算将每个激光脉冲反射回传感器所花费的时间获得距离。
- 激光雷达提供了难以通过摄像头图像获得的信息如距离和高度。
机器学习与深度学习
机器学习涉及使用数据和相关的真值标记来进行模型训练。
- 当提供数据和对应的标签给计算机进行学习,为监督式学习 Supervised Learning;
- 只提供数据,不提供真值标记,让计算机自行学习分类数据,为无监督学习 Unsupervised Learning;
- 将监督学习和无监督学习的特点结合在一起,使用少量的标记数据和大量的未标记数据来训练模型,为半监督学习;
- 强化学习 Reinforcement Learning 涉及允许模型通过尝试许多不同的方法来解决问题,然后衡量哪种方法最为成功
人工神经网络:通过数据来学习复杂模式的工具。
- 神经网络由大量的神经元组成,人工神经元负责传递和处理信息,也可以对这些神经元进行训练。
- 人工神经网络通过密集训练,计算机可以辨别汽车、行人、交通信号灯、电线杆。
- 神经网络从图像中提取许多特征,但这些特征可能是人类无法描述或甚至无法理解的特征,计算机将调整这些特征的权重,以完成神经网络的最终任务。
训练由三步循环组成:
- 前馈:随机分配初始权重即人工神经元的值,通过神经网络来馈送每个图像产生输出值;
- 误差测定:误差是真值标记与与前馈过程所产生输出之间的偏差。
- 反向传播:通过神经网络反向发送误差,此过程类似前馈过程,只是以相反方向进行。
CNN 卷积神经网络
- 如果使用标准神经网络对图像进行分类,标准做法是通过将图像矩阵重塑为一个矢量,这种方法打破了图像中所嵌入的空间信息。
- CNN通过维持输入像素之间的空间关系来解决这个问题,CNN通过将过滤器连续滑过图像来收集信息,每次收集信息时,只对整个图像的一小部分区域进行分析,称为卷积。
- 当在整个输入图像上对一个过滤器进行卷积时,将该信息与下一个卷积层相关联。例如 CNN 识别第一个卷积层中的基本边缘和颜色信息,然后通过在第一层上卷积新过滤器,CNN 使用边缘和颜色信息来归纳更复杂的结构如车轮、车门、挡风玻璃;而另一个卷积可使用车轮、车门、挡风玻璃识别整个车辆;最后神经网络可使用这一高阶信息对车辆进行分类。
检测和分类
感知任务中,首先是障碍物检测和分类。在驾驶过程中会遇到许多障碍物,静态障碍物或者动态障碍物。
计算机首先需要知道障碍物的位置,然后进行分类。在路中行驶的无人驾驶车可能会探测到许多不同的物体,汽车根据所感知的物体类型来确定路径和速度。如果感知到前方有一辆自行车,汽车可能会决定减速和变道,以便安全驶过自行车。但是如果感知到前方有另一辆车,并预测到前方车辆也将以接近限速的速度行驶,可能会保持其速度和车道。
另一个示例为交通信号灯检测分类,首先将使用计算机视觉对图像中的交通信号灯进行定位,然后根据灯光显示颜色对交通信号灯进行分类。
无人驾驶中,使用 CNN 对障碍物进行检测和分类。可以先使用检测 CNN 来查找图像中的对象的位置,在对图像中的对象进行定位后,可以将图像发送给另一个 CNN 进行分类,也可以使用单一 CNN 体系结构对对象进行检测和分类,一种通常的做法为在单个网络体系结构的末端附加几个不同的“头”,一个头可能执行检测,另一个则可能执行分类。经典体系结构为 R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD 等,YOLO 和 SSD 是具有类似形式的不同体系结构。
跟踪
对象跟踪的意义:
- 检测失败的情况下,追踪至关重要
- 追踪可以保留身份,障碍物检测的输出为包含对象的边界框,但是对象没有与任何身份关联,单独使用对象检测时,计算机不知道一个帧中的哪些对象与下一帧中的哪些对象相对应。
对象跟踪的步骤
- 确认身份,通过查找特征相似度最高的对象,将在之前的帧中检测到的所有对象与在当前的帧中检测到的对象进行匹配。
- 对象具有各种特征,可能基于颜色、基于形状,计算机视觉算法可以计算出复杂的图像特征,如局部二值模式和方向梯度直方图。
- 当然也需要考虑连续视频帧中,两个障碍物之间的位置和速度,由于两帧之间的对象位置和速度没有太大变化,该信息也可以帮助快速找到匹配的对象。
- 在确定身份后,可以使用对象的位置并结合预测算法以估计在下一个时间步的速度和位置,该预测可帮助识别下一帧中的相应对象。
分割
语义分割涉及对图像的每个像素进行分类,用于尽可能详细地了解环境并确定车辆可驾驶区域。
语义分割依赖于一种特殊类型的 CNN,被称为全卷积网络 FCN。FCN 用卷积层来替代传统 CNN 体系结构末端的平坦层,网络中的每一层都是卷积层,因此名称为“全卷积网络”。
FCN 提供了可在原始输入图像之上叠加的逐像素输出,通过编码器-解码器网络结构使得输出尺寸与原始图像的尺寸相匹配。网络的前半部分通常被称为编码器,因为这部分网络对输入图像的特征进行了提取和编码。网络的后半部分通常被称为解码器,因为它对这些特征进行了解码并将其应用于输出。
Apollo 感知模块
Apollo 开放式软件栈可感知障碍物、交通信号灯、车道。
可感知障碍物的检测步骤:
- 对于三维对象检测,Apollo 在高精度地图上使用感兴趣区域 ROI 来重点关注相关对象。Apollo 将 ROI 过滤器应用于点云和图像数据,以缩小搜索范围并加快感知。
- 然后通过检测网络馈送已过滤的点云,输出用于构建围绕对象的三维边界框。
- 最后使用被称为检测跟踪关联的算法来跨时间步识别单个对象,该算法先保留在每个时间步要跟踪的对象列表,然后在下一个时间步中找到每个对象的最佳匹配。
交通信号灯的分类:
- 先使用高精度地图来确定前方是否存在交通信号灯。
- 如果前方有交通信号灯,则高精度地图会返回灯的位置。后续根据位置,摄像头搜索范围。
- 在摄像头捕获到交通信号灯图像后,Apollo使用检测网络对图像中的灯进行定位,然后从较大的图像中提取交通信号灯。
- 将裁剪的交通灯图像提供给分类网络以确定灯颜色,如果有许多灯则系统需要选择哪些灯与其车道相关。
车道线和动态物体检测:
- Apollo使用 YOLO 网络来检测车道线、动态物体其中包括车辆、卡车、骑自行车的人、行人。
- 在经过 YOLO 网络检测后,在线检测模块会并入来自其他传感器的数据对车道线预测进行调整,车道线最终被并入名为“虚拟车道”的单一数据结构中。
- 同样也通过其他传感器的数据对 YOLO 网络所检测到的动态对象进行调整,以获得每个对象的类型、位置、速度、前进方向。
- 虚拟通道和动态对象均被传递到规划与控制模块。
传感器数据比较
- 摄像头非常适用于分类,在 Apollo 中摄像头主要用于交通信号灯分类、车道检测;
- 激光雷达的优势在于障碍物检测,即使在夜间仍能准确地检测障碍物;
- 雷达在探测范围和应对恶劣天气方面占优势。
雷达传感器:
- 雷达已经在汽车上使用很多年,在各种系统中都需要雷达,如自适应巡航控制、盲点警告、碰撞警告和碰撞预防系统等。
- 其他传感器测量速度的方法是计算两次读数之间的差距,而雷达则通过多普勒效应来直接测量速度。
- 多普勒效应根据对象在远离还是接近你,测量出雷达的频率变化。
- 多普勒效应对传感器融合至关重要。因为它可以把速度作为独立的测量参数,从而提升了融合算法的收敛速度。
- 雷达还可以生成环境的雷达地图,进而实现定位。因为雷达波在坚硬表面会回弹。因此,它可以直接测量对象距离,无需在视线范围内也可以。
- 雷达可以看到其他车辆底部,并发现可能会被阻挡的建筑物和对象。
- 在车上的所有传感器中,雷达是不容易受雨雾影响的。而且视野宽阔,可达150度,距离可达200多米。
- 与激光雷达和摄像头相比,雷达分辨率较低,尤其是在垂直方向,分辨率非常有限。分辨率低意味着来自静态物体的反射可能产生问题。例如,街道上检修孔盖或汽水罐,可能产生很高的雷达反射率,我们将其称为雷达杂波。因此,当前的车载雷达通常会忽视静态物体。
激光雷达传感器:
- 激光雷达是激光探测与测量的简称,而雷达则是无线电探测与测量的简称。
- 雷达使用无线电波,而激光雷达则使用红激光束来确定传感器和附近对象的距离。
- 目前的激光雷达大多使用 900nm 光波长度的光源。但部分激光雷达使用的光波长度更长,在雨雾中性能更好。当前的激光雷达使用旋转座架发射激光,扫描周边环境。激光室脉冲式的,脉冲被对象反射,然后返回一个点云来代表这些物体。
- 激光雷达的空间分辨率远远高于雷达。因为激光束越聚焦,垂直方向的扫描层数量就越多,因此每层的激光雷达的密度也越高。
- 目前,激光雷达还不能直接测量对象的速度,必须使用两次或多次扫描之间的位置差来确定。
- 激光雷达受天气和传感器清洁程度影响也很大,因此需要保持清洁。
- 它们块头也比其他传感器更大,因此也很难安装,除非你只想在车顶安装一个大的激光扫描器。
感知融合策略
Apollo使用激光雷达和雷达来检测障碍物,用于融合输出的主要算法为卡尔曼滤波。
卡尔曼滤波有两个步骤:第一步为预测状态,第二步是更新测量结果。设想正在跟踪一名行人,这里的状态表示行人的位置和速度,从已经掌握的行人状态开始,使用这些信息来执行卡尔曼滤波的第一步,即预测行人在将来的状态;下一步为误差结果更新,使用新的传感器来更新所认为的行人状态,卡尔曼滤波算法是预测和更新步骤的无限循环。
有两种测量结果更新步骤:同步和异步。同步融合同时更新来自不同传感器的测量结果,而异步融合则逐个更新所收到的传感器测量结果。
传感器融合可提高感知性能,因为各传感器相辅相成,融合也可以减少跟踪误差。
预测
无人车需要预测周围移动物体的行为,确保做出最佳决策。通过生成预测路径预测其他物体的行为,在每一个时间段内会为每一辆汽车重新计算预测他们新生成的路径,这些预测路径为无人车在规划阶段做出决策提供了必要信息。
预测路径要求:
- 实时性,算法的延迟越短越好。
- 准确性,做出的预测需要尽可能保持准确,这样才能使无人车做出很好的决策。
- 能够学习新的行为,当路上有很多车辆,情况将变得复杂。预测模块能够学习新的行为,通过使用多源的数据进行训练,使算法随着时间的推移而提升预测能力。
预测方式
基于模型预测
对于当前物体可能的运行状态分别建立预测模型,继续观察物体的运动,与预测模型进行匹配,更匹配的模型将更倾向是物体将来的运动状态。
e.g 对 T 型路口的白色汽车进行预测。用基于模型的方法可以为此场景构建了两个候选的预测模型。一个模型描述了进行右转弯,用绿色轨迹表示,另一个模型描述了继续直行,用蓝色轨道表示。认为任意一种模式发生的概率都是相同的。继续观察移动车的运动,看它与哪一条轨迹更加匹配,如果看到车辆开始向左改变车道,则更加确信车辆最终会直行;另一方面如果看到车在右转弯车道保持前行,则更加倾向于预测对车辆右转。
基于模型的方法的优点在于它的直观,并且结合了现有的物理知识以及交通法规还有人类行为多方面知识。
数据驱动预测
数据驱动预测使用机器学习算法,通过观察结果来训练模型,可以在现实世界中利用此模型去做出预测。
数据驱动方法的优点是训练数据越多,模型效果越好。
基于车道序列的检测(Apollo)
为了建立车道序列,首先将道路分成多个部分,每一部分都覆盖了一个易于描述车辆运动的区域。
如图是一个部分区域的十字路口。为了预测,我们更关心车辆如何在这些区域内转换,而不是在某个区域内的具体行为。可以将车辆的行为划分为一组有限的模式组合并将这些模式组合描述为车道序列,例如直行汽车的运动可以描述为车道序列是 0-1-3-7。
使用车道序列框架的目标是为道路上的物体生成轨迹。从预测车道线段之间的过渡开始,汽车可能会在车道段 0 然后右转,或者转向 1 车道后直行,从而将预测问题简化为选择问题。
障碍物状态
- 无人驾驶汽车观察物体的状态,除了位置、速度、朝向、加速度之外,还需考虑车道段内物体的位置。
- 例如预测模块会考虑从物体到车道线段边界的纵向和横向距离,还包含之前时间间隔的状态信息以便做出更准确的预测。
预测目标车道:接下来选择车辆最有可能采取的车道顺序,可以通过计算每个车道序列的概率来进行选择。
- 将车辆状态和车道段作为输入,该模型用于提供车辆可能采用每个车道序列的概率,希望模型能够学习新的行为因此应该使用观测数据对模型进行经验性训练。
- 在训练中将真实的车辆行为提供给模型,不仅包括车道段和对象的状态,还包括对象最终选择哪条车道序列。
- 记录随着时间增加,模型可以自我迭代更新,精确度不断提升。
- 每个记录将由观察对象跟随的车道段序列和对象的相关状态组成,在每个时间点,对象占用一段并具有特定的状态,整个记录由一系列车道段和对象的相关状态组成。
递归神经网络 RNN 和目标车道检测
Apollo 使用 RNN 建立一个模型来预测车辆的目标车道,为车道序列提供一个 RNN 模型,为相关对象状态提供另一个 RNN 模型。连接这两个 RNN 的输出并将它们馈送到另一个神经网络,该神经网络会估计每个车道序列的概率,具有最高概率的车道序列是我们预测目标车辆将遵循的序列。
为了训练这个网络,使用现有的记录,每条记录都包含一个车道序列、相关的对象状态、一个标签,用于指示对象是否遵循此特定车道序列。在训练中,比较网络输出和真值标记并使用反向传播来训练网络。
预测轨迹生成
轨迹生成是预测的最后一步,预测物体的车道序列后就可以预测物体的轨迹。
在任何两点 A 和 B 之间,物体的行进轨迹有无限的可能。可以先通过设置约束条件来去除大部分无法实际执行的候选轨迹,例如考虑车辆当前的速度和加速度。
在数学理论上来实现列出物体所有可能的轨迹,注意车辆在两点的位置和方位,这两个姿势表示运动模型的初始状态和最终状态,可以使用这两个条件来拟合一个多项式模型,在大多数情况下这种多项式足以进行预测。
规划
- 路线规划,目标是找到从地图上的 A 前往 B 的最佳路径,侧重于研究如何从地图上的 A 点前往 B 点。在路线导航时,将地图数据作为输入,并输出可行驶路径。手机导航系统是路线导航的一个示例。在Apollo中,可以通过路线规划模块处理该任务。
- 轨迹规划,目标是找到避免碰撞和保持舒适度的可执行轨迹。建出高水平的路线,就可以放大至轨迹规划。该轨迹由一系列点定义,每个点都有一个关联速度和一个指示何时应抵达那个点的时间戳。通过轨迹规划,做出微妙的决策,以避开障碍物,并为乘客创造平稳的乘车体验。在Apollo中,通过规划模块处理该任务。
A* 搜索算法
在进行智能搜索算法以前,我们需要将地图数据重新格式化为“图”的数据结构。图由“节点”(node)和“边缘”(edge)组成,节点代表路段,边缘代表这些路段之间的连接。对一个节点移动到另一个节点所需的成本进行建模,这些成本又称为“代价”。
A* 是经典的路径查找处理算法。成本 f=g+h
,g 值为开始节点前往候选节点的成本,h 值为候选节点前往目的地的估计成本或启发式成本。根据具体情况,可以自定义成本估算方式。例如,交通堵塞会增加前往目的地的成本,所以交通繁忙的路径具有更高的成本。
最佳候选节点是 f 值最小的节点。每当我们抵达新节点时,我们通过重复此过程来选择下一个候选节点,而且总是选择我们尚未访问过且具有最小 f 值的节点。
轨迹生成
高等级地图路线只是规划过程中的一部分,仍需要构建沿这条路线前进的低等级轨迹。这意味着要处理一些不属于地图的物体:如其他车辆、自行车或行人。例如,需要与试图前面掉头的汽车互动,或者希望超过一辆在公路上行驶的慢车。这些场景需要更低级别、更高精确度的规划,称为轨迹生成。
3D轨迹
轨迹生成的目标是生成一系列路径点所定义的轨迹。每个路径点都分配了一个时间戳和速度,由于移动的障碍物可能会暂时阻挡部分路段,轨迹中的每个路径点都有时间戳,将时间戳与预测模块的输出相结合,以确保计划通过时,轨迹上的每个路径点均未被占用。这些时间戳和空间上的两个维度(2D position)共同创建了一个三维轨迹(3D Trajectory)。每个路径点都指定了一个速度,用于确保车辆按时到达每个路径点。
轨迹评估
现实世界中的规划面临多种约束:
- 轨迹应能免于碰撞,这意味着必须没有障碍物。
- 要让乘客感到舒适,所以路径点之间的过渡以及速度的任何变化都必须平滑。
- 路径点对车辆应实际可行,不能构建包含不可行机动的轨迹。
- 轨迹应合法。这就需要了解每个路径点的交通法律,并确保轨迹遵守这些法律法规。
在道路的任何两点,可能会有多个不会发生碰撞、行驶舒适、可行且合法的轨迹,使用成本函数可以选择最佳轨迹。轨迹成本由各种犯规处罚组成,例如:偏离道路中心,有可能产生碰撞,速度限制,轨迹的曲率和加速度让乘客感到不舒服等。
Frenet 坐标:笛卡尔坐标系的替代解决方案
Frenet 坐标系描述了汽车相对于道路的位置。在 Frenet 框架中,s 代表沿道路的距离,也被称为纵坐标。d 表示与纵向线的位移,也被称为横坐标。在道路的每个点上,横轴和纵轴都是垂直的。纵坐标表示道路中的行驶距离,横坐标表示汽车偏离中心线的距离。
路径-速度解耦规划
路径-速度解耦规划将轨迹规划分为两步:路径规划、速度规划。
- 路径规划生成候选曲线,是车辆可行驶的路径。使用成本函数对每条路径进行评估,该函数包含平滑度、安全性、与车道中心的偏离以及开发者想要考虑的其他任何因素。然后按成本对路径进行排名并选择成本最低的路径。
- 速度规划,需要选择的是与路径点相关的一系列速度,而不是单个速度,将该序列称作“速度曲线”。使用优化功能为路径选择受到各种限制的良好速度曲线。
- 通过将路径和速度曲线相结合可构建车辆行驶轨迹。
路径生成与选择
- 为了在路径-速度解耦规划中生成候选路径,首先将路段分割成单元格,对这些单元格中的点进行随机采样。
- 从每个单元格中取一个点并将点连接创建候选路径,重复此过程构建多个候选路径。
- 使用成本函数对这些路径进行评估并选择成本最低的路径,成本函数可能考虑以下因素:与车道中心的偏离、与障碍物的距离、速度和曲率的变化、对车辆的压力、或希望列入的任何其他因素。
ST 图
选择路径后就可以选择与该路径关联的速度曲线,“ST 图”能够帮助设计和选择速度曲线。
在 ST 图中,“s”表示车辆的纵向位移,“t”表示时间。ST 图上的曲线是对车辆运动的描述,因为它说明了车辆在不同时间的位置。由于速度是位置变化的速率,所以可以通过查看曲线的斜率从 ST 图上推断速度。斜坡越陡则表示在更短的时间段内有更大的移动,对应更快的速度。
速度规划
- 为了构建最佳速度曲线,需要将 ST 图离散为多个单元格。单元格之间的速度有所变化,但在每个单元格内速度保持不变。
- ST 图中可以将障碍物绘制为在特定时间段内阻挡道路的某些部分的矩形。
- 假设预测模块预测车辆将在 t0 到 t1 的时间段占据位置 s0 到 s1,在 ST 图上绘制了一个矩形,它将在时间段 t0 到 t1 期间阻挡位置 s0 到 s1。
- 为避免碰撞,速度曲线不得与此矩形相交。
- 然后就可以使用优化引擎为该图选择最佳的速度曲线。
- 优化算法通过复杂的数学运算来搜索受到各种限制的低成本解决方案。这些限制可能包括:法律限制,如速度限制;距离限制,如与障碍物的距离;汽车的物理限制,如加速度限制。
二次规划
路径选择涉及将道路划分为单元格,速度曲线构建涉及将 ST 图划分为单元格。尽管离散化使这些问题更容易解决,但该解决方案生成的轨迹并不平滑。
为了将离散解决方案转换为平滑轨迹,可使用“二次规划”技术(Quadratic Programming)。二次规划将平滑的非线性曲线与这些分段式线性段拟合。一种由 Apollo 推出的运行方案来生成平滑的轨迹,一旦路径和速度曲线就绪,便可以用其构建三维轨迹。
端到端路径-速度解耦规划
- 感知系统观察到一辆缓慢行驶的车辆正在接近。
- 在这辆车的周围生成多条候选路线,使用成本函数对这些候选路径进行评估并选择成本最低的路径。
- 使用 ST 图来进行速度规划,根据其他车辆随时间变化的位置阻挡了 ST 图的部分区域。优化引擎可帮助确定该图的最佳速度曲线,该曲线受制于约束和成本函数。
- 使用二次规划让路径和速度曲线变平滑。
- 最后,将路径和速度曲线合并构建轨迹。这里的轨迹在速度较快时为红色,在速度较慢时为蓝色。使用该轨迹来安全地绕开其他车辆并继续前进。
Lattice规划
Lattice 规划通过使用 Frenet 坐标可以将环境投射到纵轴和横轴上,目标是生成三维轨迹:纵向维度、横向维度、时间维度。
可以将三维问题分解成两个单独的二维问题,这是通过分离轨迹的纵向和横向分量来解决的。其中一个二维轨迹是具有时间戳的纵向轨迹称之为 ST 轨迹,另一个二维轨迹是相对于纵向轨迹的横向偏移称之为 SL 轨迹。
ST轨迹的终止状态
将状态分成 3 组:巡航 、跟随、停止:
- 巡航 Cruising 意味着车辆将在完成规划步骤后定速行驶,实际上在对图上的点进行采样。对于这种模式,所有最终状态的加速度均为零。
- 跟随 Following 在这种情况下要对位置和时间状态进行采样,并尝试在时间 t 出现在某辆车后面,在跟随车辆时,需要与前方的车保持安全距离,这时速度和加速度将取决于要跟随的车辆,这意味着在这种模式下,速度和加速度都会进行修正。
- 停止 Stopping 只需对汽车何时何地停止进行抽样,这里速度和加速度会被修正为 0 。
SL轨迹的终止状态
SL 规划的假设:无论车辆进入怎样的终止状态,车辆都应该稳定地与车道中心线对齐。所以只需要在道路上相邻车道中心线周围的位置对横向终止位置进行采样。为了确保稳定性,汽车驶向的终止状态应该与车道中心一致。
当用横向位置与纵向位置作图时,想要的候选轨迹应该以车辆与车道对齐并直线行驶而结束。为了达到这种终止状态,车的朝向和位置的一阶和二阶导数都应该为 0。一阶导数为 0 意味着车辆不是横向移动,二阶导数为 0 意味着车辆不是横向加速,一阶导数和二阶导数都为 0 意味着车辆正沿着车道直行。
Lattice规划的轨迹生成
- 分别建立 ST 和 SL 轨迹
- 将它们重新转换为笛卡尔坐标系,由于两个轨迹都有纵坐标 S,所以可以通过将其 S 值进行匹配来合并轨迹。
控制
控制是驱使车辆前行的策略。对于汽车而言,最基本的控制输入为转向、加速和制动。通常,控制器使用一系列路径点来接收轨迹。控制器的任务是使用控制输入让车辆通过这些路径点。
控制策略的评估标准
- 控制器必须准确,避免偏离目标轨迹。这对于安全来说尤为重要,即使路面潮湿或者道路比较陡峭,控制器仍然需要准确地执行轨迹。
- 控制策略对汽车应该具备可行性。
- 平稳度。舒适的驾驶非常重要,要使控制顺利进行,驱动必须是连续的,应避免突然转向、加速或制动。
控制流程
- 两种输入:目标轨迹与车辆状态。通过使用这两个输入来计算目标轨迹与实际行进轨迹之间的偏差。
- 目标轨迹来自规划模块,在每个轨迹点,规划模块指定一个位置和参考速度,在每个时间戳都对轨迹进行更新。
- 车辆状态包括:通过本地化模块计算的车辆位置、从车辆内部传感器获取的数据(如速度、转向和加速度)。
- 输出是控制输入(转向、加速和制动)的值。当偏离目标轨迹时,应该采取行动来纠正偏差。将使用方向盘控制行驶方向(即转向)、使用油门加速、使用刹车减速(即制动)这三个值传递给车辆。
目前有三种可用于实现这些目标的控制策略:(1) PID: 比例积分微分控制;(2) LQR: 线性二次调节器;(3) MPC:模型预测控制。
PID 控制
- P 代表“比例”(Proportional)。P 控制器在车辆开始偏离时立即将其拉回目标轨迹。比例控制意味着,车辆偏离越远,控制器越难将其拉回目标轨迹。
- D 代表“微分”(Derivative)。D 控制器致力于使运动处于稳定状态。实践中 P 控制器容易超出参考轨迹,当车辆越接近目标轨迹时,需要控制器更加稳定。PD控制器类似于增加了一个阻尼项的 P 控制器,可最大限度地减少控制器输出的变化速度。
- I 代表“积分”(Integral)。I 控制器负责纠正车辆的任何系统性偏差。例如,转向可能失准,这可能造成恒定的转向偏移,这就需要稍微向一侧转向以保持直行。为解决这一问题,控制器会对系统的累积误差进行惩罚。
PID 控制器的优缺点
- 简单,很多情况下的效果很好。
- 对于 PID 控制器,只需要知道车辆与目标轨迹之间的偏差。
- PID 控制器只是一种线性算法,难以适用于非常复杂的系统。例如,为控制具有多个关节的四轴飞行器或机器人,需要建立机器人的物理模型。对无人驾驶而言,需要应用不同的 PID 控制器来控制转向和加速,这意味着很难将横向和纵向控制结合起来。
- PID 控制器依赖于实时误差测量,这意味着受到测量延迟限制时可能会失效。
线性二次调节器 (Linear Quadratic Regulator, LQR)
线性二次调节器是基于模型的控制器,它使用车辆的状态来使误差最小化。
Apollo 使用 LQR 进行横向控制。横向控制包含四个组件:横向误差、横向误差的变化率、朝向误差和朝向误差的变化率。这四个组件的集合为 X,这个集合 X 捕获车辆的状态。除了状态之外,该车有三个控制输入:转向、加速和制动,这个控制输入集合称为 U。
模型预测控制 MPC
模型预测控制依赖于数学优化,基本上可以归结为三个步骤:
- 建立车辆模型,以估计控制输入对车辆的影响,并决定预测未来的深度。预测时间越长,控制器越精确,但需要更长时间来获取结果。
- 使用优化引擎计算有限时间范围内的最佳控制输入。优化引擎依赖于车辆模型的约束条件和成本函数,以间接评估控制输入并寻找最佳解决方案。
- 执行第一组控制输入并重复上述步骤。由于近似测量和计算的原因,每个时间步都需要重新评估控制输入的最优序列。
MPC 的优缺点
- 考虑了车辆模型,因此比 PID 控制更精确
- 适用于不同的成本函数,所以可以在不同情况下优化不同的成本。
- MPC 比 PID 相对更复杂、更缓慢、更难以实现。
- 在实践中,无人驾驶车的控制可扩展性的重要程度意味着值得为 MPC 投入实现成本,所以 MPC 是一个很重要的无人驾驶车控制器。
Reference
- Apollo自动驾驶入门课程-CSDN博客
- 自动驾驶新人之旅_Apollo精品课
- Apollo自动驾驶入门课程_Apollo精品课
- Udacity:Apollo起步学习笔记 | Howie’s Notes
- Apollo自动驾驶入门课(1)——无人驾驶概览_月光下的丁香的博客-CSDN博客
- Apollo自动驾驶入门课(2)——高精度地图_apollo 室内地图_月光下的丁香的博客-CSDN博客
- Apollo自动驾驶入门课(3)——定位_陀螺仪传感器坐标系转换到自车坐标系_月光下的丁香的博客-CSDN博客
- Apollo自动驾驶入门课(4)——感知_月光下的丁香的博客-CSDN博客
- Apollo自动驾驶入门课(5)——预测_月光下的丁香的博客-CSDN博客
- Apollo自动驾驶入门课(6)——规划_月光下的丁香的博客-CSDN博客
- Apollo自动驾驶入门课(7)——控制_月光下的丁香的博客-CSDN博客
- 学习心得:Apollo无人驾驶汽车入门课程——第一课:无人驾驶概览 - CodeAntenna