0 参考资料
0.1 Apollo各模块系列笔记记录
0.2 Apollo优秀教程合集
1 什么是Apollo
参考文章 |
---|
百度Apoll无人驾驶高精度地图的制作和opendrive格式详细讲解 - 知乎 (zhihu.com) |
apollo高精地图的数据元素分类以及阿波罗地图规范和opendrive规范的区别 - 知乎 (zhihu.com) |
社群分享内容 Apollo相对地图:基于人工驾驶路径的实时地图生成 (qq.com) |
1.1 简介
Apollo是百度的自动驾驶开源框架,根据自动驾驶的功能划分为不同的模块。
- 定位 - 比如GPS,但是GPS的精度只有米级别。有几个场景会不太合适,比如你在桥洞里,GPS信号不好的情况,另外还有一种情况是,停车的时候,你要知道前后车的距离,另外比如在雪天或者路况复杂的情况,这些情况下,仅有的GPS信号可能不能满足我们的要求,因此无人车又增加了激光雷达来测量周围环境的距离,而且可以精确到厘米。 因此产生了高精地图的需求,高精地图可以把周围的3D环境都记录下来,这样我们就可以通过3D图像来匹配周围的场景,来找到自己的位置,而且高精地图还可以记录比地图多的多的东西,比如红绿灯的位置,交通标志,左转还是右转道.通过高精地图我们不仅可以知道道路情况,还可以知道车辆需要获取的一些其他信息,让车辆知道自己的实时位置。
- 感知 - 我们总是希望车辆行驶在马路中间,这样更加安全,这就需要追踪到道路的路牙线,而道路随时会出现拐弯,那么追踪路牙线就用到了图像处理技术,另外还要感知到什么是车辆,什么是行人,主要涉及到图像的语义分割,感知是自动驾驶中最难,而且最具有挑战性的一块,因为只有感知到周围的行人,车辆,以及突发状况,才能为后面规划线路。
- 规划 - 目前已经知道当前道路情况,而且也已经感知到前面的车辆或者行人,如何去规划我们的行驶线路呢,这里需要解决的就是2个点之间的线路,而且行驶中途可能会出现新的情况,又需要重新规划线路,还有一种情况是,通过高精地图,我们已经知道前面需要转弯了,我们可以提前调整线路来适应这种需求。
控制 - 现在已经规划出了一条线路,剩下的就是控制汽车,按照已经规划好的线路行驶,而且如果遇到突发状况,需要立即停车,而且控制汽车能够按照预定的线路不会出现很大的偏离,这就是控制要做的事情。
1.2 结构目录
|-cyber 消息中间件,替换ros作为消息层
|-docker 容器相关
|-docs 文档相关
|-modules 自动驾驶模块,主要的定位,预测,感知,规划都在这里
|-calibration 校准,主要用于传感器坐标的校准,用于感知模块做传感器融合
|-canbus 通讯总线,工业领域的标准总线,CanBus 是将控制命令传递给车辆硬件的接口。它还将机箱信息传递给软件系统。
|-common 本模块中的代码不是针对某一模块的,各个模块得一些共性方法吧
|-contrib
|-control 控制模块,根据planning生成的路径对车辆轨迹进行控制,再底层就是发送命令到can总线,实现车辆的控制。控制模块通过产生油门、刹车和转向等控制命令来执行计划的时空轨迹。
|-data 地图等生成好的数据放在这里
|-dreamview 仿真,能够对自动驾驶过程中的数据进行回放
|-drivers 雷达,lidar,GPS, canbus,camera等驱动
|-guardian 新的安全模块,用于干预监控检测到的失败和action center相应的功能。 执行操作中心功能并进行干预的新安全模块应监控检测故障。
|-localization 定位,获取汽车的当前位置
|-map 地图模块
| -HD-Map 模块类似于库。它不是发布和订阅消息,而是经常用作查询引擎支持,以提供关于道路的特定结构化信息。
定位——定位模块利用各种信息源(如 GPS、LiDAR 和 IMU)来估计自动驾驶汽车的位置。
|-monitor 监控模块,主要是监控汽车状态,并且记录,用于故障定位,健康检查等
|-perception 感知,获取汽车当前的环境,行人,车辆,红绿灯等,给planning模块规划线路,感知模块识别自动驾驶汽车周围的环境。感知模块内部包含两个重要的子模块:障碍物检测和交通灯检测。
|-planning 规划,针对感知到的情况,对路径做规划,短期规划,只规划100-200M的距离,生成好的路径给control模块,规划模块规划自动驾驶汽车要采取的时空轨迹。
|-prediction 预测,属于感知模块,对运动物体的轨迹做预测,预测模块用来预测与感知障碍物未来的运动轨迹。
|-routing 导航线路,就是百度地图上查询2点之间的线路,生成的线路短期规划还是planning模块,路由模块告诉自动驾驶汽车通过全局路径到达目的地。
|-third_party_perception 第三方感知模块
|-tools 工具
|-transform 坐标转换,不同坐标系的坐标转换
|-v2x 顾名思义就vehicle-to-everything,其希望实现车辆与一切可能影响车辆的实体实现信息交互,
目的是减少事故发生,减缓交通拥堵,降低环境污染以及提供其他信息服务。车路协同技术
|-scripts 脚本
|-third_party 第三方库
|-tools 工具目录1.3 各模块架构
Apollo 无人驾驶平台是以高精地图和定位模块作为核心。其他的模块都是以这两个模块为基础。
1.3.1 定位
https://github.com/ApolloAuto/apollo/blob/master/modules/localization/README_cn.md
一种是结合GPS和IMU信息的RTK(Real Time Kinematic实时运动)方法,另一种是融合GPS、IMU和激光雷达信息的多传感器融合方法。
1.3.2 感知
apollo/modules/perception at master · ApolloAuto/apollo (github.com)
1.3.3 预测
https://github.com/ApolloAuto/apollo/blob/master/modules/prediction/README_cn.md
预测模块从感知模块接收障碍物,其基本感知信息包括位置、方向、速度、加速度,并生成不同概率的预测轨迹。
1.3.4 路由
路由模块依赖于路由拓扑文件,通常称为Apollo中的routing_map.*。路由地图可以通过命令来生成。
1.3.5 规划
https://github.com/ApolloAuto/apollo/blob/master/modules/planning/README_cn.md
1.3.6 控制
https://github.com/ApolloAuto/apollo/blob/master/modules/control/README_cn.md
- 本模块基于规划和当前的汽车状态,使用不同的控制算法来生成舒适的驾驶体验。控制模块可以在正常模式和导航模式下工作。
- 输出:给底盘的控制指令(转向,节流,刹车)。
1.4 编译
apollo采用的是bazel来进行编译。2 Cyber
| 参考文章 | | —- | | apollo介绍之cyber设计(五) - 知乎 (zhihu.com) | | apollo介绍之Cyber框架(十) - 知乎 (zhihu.com) | | apollo介绍之Cyber框架(十一) - 知乎 (zhihu.com) | | apollo介绍之Cyber定时器(十二) - 知乎 (zhihu.com) | | apollo介绍之Cyber Component(十三) - 知乎 (zhihu.com) | | apollo介绍之Cyber Data(十四) - 知乎 (zhihu.com) | | apollo介绍之Cyber Scheduler调度(十五) - 知乎 (zhihu.com) | | apollo介绍之Cyber Async异步调用(十六) - 知乎 (zhihu.com) | | apollo介绍之cyber启动(十九) - 知乎 (zhihu.com) |
Cyber是百度Apollo推出的替代Ros的消息中间件,自动驾驶中的各个模块通过Cyber进行消息订阅和发布,同时Cyber还提供了任务调度、录制Bag包等功能。
2.1 Cyber实现的功能
cyber提供的功能概括起来包括2方面:
- 消息队列 - 主要作用是接收和发送各个节点的消息,涉及到消息的发布、订阅以及消息的buffer缓存等。
- 实时调度 - 主要作用是调度处理上述消息的算法模块,保证算法模块能够实时调度处理消息。
除了这2方面的工作,cyber还需要提供以下2部分的工作:
- 用户接口 - 提供灵活的用户接口
- 工具 - 提供一系列的工具,例如bag包播放,点云可视化,消息监控等
总结起来就是,cyber是一个分布式收发消息,和调度框架,同时对外提供一系列的工具和接口来辅助开发和定位问题。其中cyber对比ROS来说有很多优势,唯一的劣势是cyber相对ROS没有丰富的算法库支持。
3 Audio
audio模块是Apollo 6.0新增加的模块,主要的用途是通过声音来识别紧急车辆(警车,救护车,消防车)。目前的功能还相对比较简单,只能识别单个紧急车辆,同时需要环境风速低于20mph。
4 Canbus
4.1 Canbus模块介绍
控制器局域网 (Controller Area Network,简称CAN或者CAN bus) 是一种车用总线标准。被设计用于在不需要主机(Host)的情况下,允许网络上的节点相互通信。采用广播机制,并利用标识符来定义内容和消息的优先顺序,使得canbus的扩展性良好,同时不基于特殊类型(Host)的节点,增加了升级网络的便利性。 这里的Canbus模块其实可以称为Chassis模块,主要的作用是反馈车当前的状态(航向,角度,速度等信息),并且发送控制命令到车线控底盘,可以说Canbus模块是车和自动驾驶软件之间的桥梁。由于这个模块和”drivers/canbus”的联系紧密,因此也一起在这里介绍。 Canbus模块是车和自动驾驶软件之间的桥梁,通过canbus驱动(drivers/canbus)来实现将车身信息发送给apollo上层软件,同时接收控制命令,发送给汽车线控底盘实现对汽车的控制。
那么canbus模块的输入是什么?输出是什么呢?
可以看到canbus模块:
- 输入 - 1. ControlCommand(控制命令)
- 输出 - 1. Chassis(汽车底盘信息), 2. ChassisDetail(汽车底盘信息详细信息)
Canbus模块的输入是control模块发送的控制命令,输出汽车底盘信息,这里apollo的上层模块被当做一个can_client来处理,实现接收和发送canbus上的消息。
Canbus模块的目录结构如下:
├── BUILD // bazel编译文件
├── canbus_component.cc // canbus主入口
├── canbus_component.h
├── canbus_test.cc // canbus测试
├── common // gflag配置
├── conf // 配置文件
├── dag // dag依赖
├── launch // launch加载
├── proto // protobuf文件
├── testdata // 测试数据
├── tools // 遥控汽车和测试canbus总线工具
└── vehicle //
5 Control
5.1 Control模块简介
Apollo控制模块的逻辑相对比较简单,控制模块的作用是根据规划(planning模块)生成的轨迹,计算出汽车的油门,刹车和方向盘信号,控制汽车按照规定的轨迹行驶。采用的方法是根据汽车动力和运动学的知识,对汽车进行建模,实现对汽车的控制。目前apollo主要用到了2种控制方式:PID控制和模型控制。
首先我们需要搞清楚control模块的输入是什么,输出是什么?
可以看到control模块:
- 输入 - Chassis(车辆状态信息), LocalizationEstimate(位置信息), ADCTrajectory(planning模块规划的轨迹)
- 输出 - ControlCommand(油门,刹车,方向盘)
Control模块的目录结构如下:
├── BUILD // bazel编译文件
├── common // PID和控制器的具体实现 —- 算法具体实现
├── conf // 配置文件 —- 配置文件
├── control_component.cc // 模块入口
├── control_component.h
├── control_component_test.cc
├── controller // 控制器 —- 具体的控制器实现
├── dag // dag依赖
├── integration_tests // 测试
├── launch // launch加载
├── proto // protobuf文件,主要是各个控制器的配置数据结构
├── testdata // 测试数据
└── tools // 工具类
6 Guardian
6.1 简介
Guardian模块的主要作用是监控自动驾驶系统状态,当出现模块为失败状态的时候,会主动切断控制命令输出,并且刹车。
7 Localization
7.1 Localization模块简介
localization模块主要实现了以下2个功能:
- 输出车辆的位置信息(planning模块使用)
- 输出车辆的姿态,速度信息(control模块使用)
其中apollo代码中分别实现了3种定位方法:
- GNSS + IMU定位
- NDT定位(点云定位)
- MSF(融合定位)
MSF方法参考论文”Robust and Precise Vehicle Localization Based on Multi-Sensor Fusion in Diverse City Scenes”
7.2 代码目录
下面是localization的目录结构,在查看具体的代码之前最好看下定位模块的readme文件:
├── common // 声明配置(flags),从conf目录中读取相应的值
├── conf // 配置文件存放目录
├── dag // cyber DAG流
├── launch // cyber的配置文件,依赖DAG图(这2个和cyber有关的后面再分析)
├── msf // 融合定位(gnss,点云,IMU融合定位)
│ ├── common
│ │ ├── io
│ │ ├── test_data
│ │ └── util
│ ├── local_integ
│ ├── local_map
│ │ ├── base_map
│ │ ├── lossless_map
│ │ ├── lossy_map
│ │ ├── ndt_map
│ │ └── test_data
│ ├── local_tool
│ │ ├── data_extraction
│ │ ├── local_visualization
│ │ └── map_creation
│ └── params
│ ├── gnss_params
│ ├── vehicle_params
│ └── velodyne_params
├── ndt // ndt定位
│ ├── map_creation
│ ├── ndt_locator
│ └── test_data
│ ├── ndt_map
│ └── pcds
├── proto // 消息格式
├── rtk // rtk定位
└── testdata // imu和gps的测试数据
通过上述目录可以知道,定位模块主要实现了rtk,ndt,msf这3个定位方法,分别对应不同的目录。proto文件夹定义了消息的格式,common和conf主要是存放一些配置和消息TOPIC。
8 Map
8.1 Map模块简介
其实我们只需要知道map模块的主要功能是“加载openstreet格式的地图,并且提供一系列的API给其他模块使用”。
8.2 Map目录结构
本章主要介绍下apollo代码的map模块,map的代码目录结构如下:
├── data // 生成好的地图
│ └── demo
├── hdmap // 高精度地图
│ ├── adapter // 从xml文件读取地图(openstreet保存格式为xml)
│ │ └── xml_parser
│ └── test-data
├── pnc_map // 给规划控制模块用的地图
│ └── testdata
├── proto // 地图各元素的消息格式(人行横道,车道线等)
├── relative_map // 相对地图
│ ├── common
│ ├── conf
│ ├── dag
│ ├── launch
│ ├── proto
│ ├── testdata
│ │ └── multi_lane_map
│ └── tools
├── testdata // 测试数据?
│ └── navigation_dummy
└── tools // 工具
apollo的高精度地图采用了opendrive格式,opendrive是一个统一的地图标准,这样保证了地图的通用性。其中map模块主要提供的功能是读取高精度地图,并且转换成apollo程序中的Map对象。直白一点就是说把xml格式的opendrive高精度地图,读取为程序能够识别的格式。 map模块没有实现的功能是高精度地图的制作。
8.3 HD-Map
由于apollo的hd map制作没有开放,所以目前hd map的生成是需要向百度提需求的。 如果想自己制作的话,apollo有提供建议如下:
- 原始数据采集(视觉、激光雷达、GPS等)以及处理。
- 地图数据生成。从步骤一生成的数据通过算法或者人工的方式获取地图数据。
- 地图格式组织。将地图数据转换为Apollo的高精度地图格式(可以参照base_map.xml格式,其他的地图都可以从base_map.xml生成)。
- 注意:这三个步骤的工具均需要自己开发,如果只是小规模的简单测试,也可以参照base_map.xml格式手工组织数据。
- 将HD map加入apollo1.5:
有两个方法,一个是通过添加一个新的目录,使用apollo系统;一个是替换原有目录下的地图文件。
- 新加一个hd map:
- 在/apollo/modules/map/data目录下,创建一个目录new_map。
- 将生成的hd map放入new_map中,如有配置文件,可以参考sunnyvale_office目录下的配置文件。
- 编译,执行bash apollo.sh build。
- 然后执行bash scripts/hmi.sh。
- 打开ip:8887,在选择地图的下拉框中就可以看到新加入的hd map了。
- 直接copy new_garage 重命名为new_garage_2测试的,测试通过。
- 注1:编译的时候,应该相当于将/apollo/modules/map/data/new_map注册到系统中去,以便启动hmi时,前端网页可以定位到/apollo/modules/map/data/new_map目录,进而加载其中的文件。也因此,可以有第二个方法加入hd map。
- 利用现有的地图目录,加入地图:
- 假设apollo1.5中,已经添加了new_map,此时只需要替换目录下的hd map所有的文件,这样不需要编译,即可使用新的hd map。
9 Monitor
9.1 简介
monitor模块主要是监控硬件和软件状态,当出现故障的时候,显示故障原因,并且输出状态给guardian模块进行紧急处理。10 Perception
| 参考文章 | | —- | | Apollo学习笔记7-感知融合hello1268的博客-CSDN博客感知融合 |
10.1 Perception模块简介
主要用到的传感器类型包括相机、激光雷达和毫米波雷达,相机和激光雷达的目标检测部分都是利用深度学习网络完成,然后都进行了目标跟踪,最后设计了一个融合模块,用来融合三种传感器跟踪后的目标序列,获得更加稳定可靠的感知结果。
首先简单看下perception的目录结构:
.
├── BUILD
├── Perception_README_3_5.md
├── README.md
├── base // 基础类
├── camera // 相机相关,相机检测 —- 子模块流程
├── common // 公共目录
├── data // 相机的内参和外参
├── fusion // 传感器融合
├── inference // 深度学习推理模块
├── lib // 一些基础的库,包括线程、时间等
├── lidar // 激光雷达相关 —- 子模块流程
├── map // 高精度地图
├── model // 深度学习模型
├── onboard // 各个子模块的入口,组件文件结构和组件类的实现 —- 子模块入口
├── production // 感知模块入口(深度学习模型也存放在这里)—- 通过cyber启动子模块
├── proto // 数据格式,protobuf
├── radar // 毫米波 —- 子模块流程
├── testdata // 上述几个模块的测试数据
└── tool // 离线测试工具
下面介绍几个重要的目录结构:
- production目录 - 感知模块的入口在production目录,通过lanuch加载对应的dag,启动感知模块,感知模块包括多个子模块,在onboard目录中定义。
- onboard目录 - 定义了多个子模块,分别用来处理不同的传感器信息(Lidar,Radar,Camera)。各个子模块的入口在onboard目录中,每个传感器的流程大概相似,可以分为预处理,物体识别,感兴趣区域过滤以及追踪。
- inference目录 - 深度学习推理模块,我们知道深度学习模型训练好了之后需要部署,而推理则是深度学习部署的过程,实际上部署的过程会对模型做加速,主要实现了caffe,TensorRT和paddlepaddle3种模型部署。训练好的深度模型放在”modules\perception\production\data”目录中,然后通过推理模块进行加载部署和在线计算。
- camera目录 - 主要实现车道线识别,红绿灯检测,以及障碍物识别和追踪。
- radar目录 - 主要实现障碍物识别和追踪(由于毫米波雷达上报的就是障碍物信息,这里主要是对障碍物做追踪)。
- lidar目录 - 主要实现障碍物识别和追踪(对点云做分割,分类,识别等)。
- fusion目录 - 对上述传感器的感知结果做融合。
整个模块的流程如图: 可以看到感知模块由production模块开始,由fusion模块结束。
10.2 融合流程
11 Planning
11.1 Planning模块简介
规划(planning)模块的作用是根据感知预测的结果,当前的车辆信息和路况规划出一条车辆能够行驶的轨迹,这个轨迹会交给控制(control)模块,控制模块通过油门,刹车和方向盘使得车辆按照规划的轨迹运行。 规划模块的轨迹是短期轨迹,即车辆短期内行驶的轨迹,长期的轨迹是routing模块规划出的导航轨迹,即起点到目的地的轨迹,规划模块会先生成导航轨迹,然后根据导航轨迹和路况的情况,沿着短期轨迹行驶,直到目的地。这点也很好理解,我们开车之前先打开导航,然后根据导航行驶,如果前面有车就会减速或者变道,超车,避让行人等,这就是短期轨迹,结合上述的方式直到行驶到目的地。
11.2 routing与planning的关系
routing模块规划的路径是planning模块规划轨迹的输入信息 来源之一,能够协助planning规划出安全,可靠的行驶轨迹。
planning模块通常根据传感器输入(激光雷达、视觉摄像头等)规划出车辆当前时刻需要的一条行驶轨迹,但是一些特殊场景下,如大雾天气、夜晚、匝道进出口等,由于输入信息缺失,不能规划出安全行驶轨迹,此时可以根据routing规划导航路径,结合高精地图信息,能够得到一条满足行驶的轨迹。
11.3 planning 的输入输出
熟悉Apollo CyberRT框架的小伙伴都知道在该框架下,输入输出由Reader和Writer构成,并定义在每个模块的component文件中。除此之外,CyberRT框架定义了两种模式,分别为消息触发和时间触发,而planning中采用的为消息触发,因此必须接到特定的上游消息后,才会进入内部主逻辑,而消息触发的上游消息,定义为component中Process()函数的入参。
planning的上下游关系总结为下图:
这里再重复一下,planning的输入分为Reader和Process()入参的原因在于,planning依赖于Process()的三个上游输入,只有同时接到这三个输入,才会触发planning的主逻辑,即是planning正常启动的必要条件。而Reader则不是,其中部分上游还依赖于配置参数是否打开,具体可以查看Apollo的源码。
planning的输出就比较简单了,主要是给控制的ADCTrajectory数据,包含了一条带时间、速度的轨迹点集,具体的格式定义可以查看对应的proto文件。
12 Prediction
参考文章 |
---|
如何学习百度apollo无人驾驶预测模块? - 知乎 (zhihu.com) |
apollo预测模块分享(二十一) - 知乎 (zhihu.com) |
12.1 简介
预测模块是直接接收的感知模块给出的障碍物信息,这和CV领域的传统预测任务有区别,CV领域的预测任务不需要先识别物体,只需要根据物体的特征,对比前后2帧,然后得出物体的位置,也就说甚至不需要物体识别,业界之所以不这么做的原因是因为检测物体太耗时了。 当然也有先检测物体再做跟踪的,也就是说目前apollo中的物体检测实际上是采用的第二种方法,这也可以理解,反正感知模块一定会工作,而且一定要检测物体,所以何不把这个信息直接拿过来用呢?这和人类似,逐帧跟踪指定特征的对象,就是物体的轨迹,然后再根据现有的轨迹预测物体讲来的轨迹。 预测的轨迹和障碍物信息发送给规划(planning)模块使用。
12.2 整体框架
绿色表示预测模块所依赖的上游模块,包括了规划、定位、感知、Storytelling和高精度地图,下游是规划模块。
红色虚线框内是预测模块的整体逻辑,包含容器(Container),场景(Scenario)、评估器(Evaluator)和预测器(Predictor)。
12.2.1 容器 Container
输入上游的一系列信息,输出障碍物、主车和相关联车道信息。
容器存储来自订阅通道的输入数据。目前支持的输入是感知模块的障碍物,车辆定位和车辆规划。
12.2.2 场景 Scenario
输入障碍物车状态、主车状态及相关车道信息,输出场景相关联信息。其中interaction(交互标志位)是7.0中新增加的一部分。
6.0和7.0的区别
6.0 的思想是将车辆及人过去的状态和位置作为输入,放在神经网络中,得到一个未来的预测,实际上还是拟合函数的核心思想。
7.0中会先根据障碍车的位置判断是不是交互式的车辆(危险等级为ineraction及caution),然后针对交互式的车辆用交互式模型。
如果是其他类型的车辆(normal),使用巡航MLP评估器及路口MLP评估器,对于不在道路上的,使用卡尔曼滤波器。所以因此7.0更加细分了感知障碍物的类别判断,新增的一类使感知预测更加细致,提升点在于有针对性,预测效果也更好。
12.2.3 评估器 Evaluator
评估器对任何给定的障碍分别预测路径和速度。评估器通过使用存储在prediction/data/模型中的给定模型输出路径的概率来评估路径(车道序列)。
将提供三种类型的评估器,包括:
- 成本评估器:概率是由一组成本函数计算的。
- MLP评估器:用MLP模型计算概率
- RNN评估器:用RNN模型计算概率
输入障碍物的信息及场景信息,评估器为机器学习的模型,输出障碍物的轨迹或意图,其中障碍物意图是指障碍物在每个车道序列的概率。
障碍物主要分为四类:自行车、行人、车辆、未知障碍物(感知模块中未检测出的)。
在预测模块中,不同的障碍物类型对应不同的评估器和预测器。
12.2.4 预测器(predictor)
预测器生成障碍物的预测轨迹。当前支持的预测器包括:
- 空:障碍物没有预测的轨迹
- 单行道:在公路导航模式下障碍物沿着单条车道移动。不在车道上的障碍物将被忽略。
- 车道顺序:障碍物沿车道移动
- 移动序列:障碍物沿其运动模式沿车道移动
- 自由运动:障碍物自由移动
- 区域运动:障碍物在可能的区域中移动
13 Routing
| 参考文章 | | —- | | Apollo 导航模块记录(routing模块) - 知乎 (zhihu.com) |
13.1 Routing模块简介
Routing类似于现在开车时用到的导航模块,通常考虑的是起点到终点的最优路径(通常是最短路径),Routing考虑的是起点到终点的最短路径,而Planning则是行驶过程中,当前一小段时间如何行驶,需要考虑当前路况,是否有障碍物。Routing模块则不需要考虑这些信息,只需要做一个长期的规划路径即可,过程如下:
这也和我们开车类似,上车之后,首先搜索目的地,打开导航(Routing所做的事情),而开始驾车之后,则会根据当前路况,行人车辆信息来适当调整直到到达目的地(Planning所做的事情)。
- Routing - 主要关注起点到终点的长期路径,根据起点到终点之间的道路,选择一条最优路径。
- Planning - 主要关注几秒钟之内汽车的行驶路径,根据当前行驶过程中的交通规则,车辆行人等信息,规划一条短期路径。
13.2 实现
Apollo的routing模块读取高精地图原始信息,用于根据输入的RoutingRequest信息在base_map中选取匹配最近的点作为导航轨迹的起点和终点 ,读取依据base_map生成的routing_map作为生成topo_graph 的,然后通过AStart算法在拓扑图中搜索连接起始点的最优路径RoutingResponse,作为输出发送出去。13.2.1 输入信息
routing模块的信息输入包括两个固定信息:高精地图原始信息(base_map)和生成的拓扑图(routing_map),一个外部输入的起始点请求信息(RoutingRequest)。
base_map信息和routing_map信息的读取在http://routing.cc的Init()函数中完成代码如下:
RoutingRequest信息是其他模块发送的,RoutingComponent通过继承Component组件,实现Routing模块事件触发,代码如下:
13.2.2 处理输入信息
13.2.2.1 从地图中选取最佳匹配点
选择匹配点的函数在http://routing.cc的FillLaneInfoMissing()函数中,代码如下:
搜索过程中,存在因车道重叠而增加的lane信息,将该部分车道信息也增加如修正后的请求信息(fixed_requests)中,到此完成输入请求点信息的修正,用于后续进行路径搜索:
1.3.2.2 搜索导航路径信息
routing模块的路径搜索功是通过AStart算法完成的,在http://a_start_strategy.cc的Search函数中实现,输入修正后的起点、终点、读取的拓扑地图以及根据起点终点生成的子拓扑图,得到起点到达终点的点集:
完成从起点到达终点的路径搜索后,还需要从中规划出一条完整的轨迹,然后生成可通行区域和Road。
1)规划起始点到达终点路径
在Reconstruct()函数中,从终点到起点进行反向搜索,获取轨迹点:
2)提取基础可通行区域
将重组得到的一条完整轨迹按照是否需要换道,生成基础可通行区域:
红色的laneID为具有换道属性节点,依据这些特殊节点,将可通行路径进行划分,可通行路径的换道属性为图中标注的属性。
3) 对提取的可通行区域进行扩展
AStart算法搜索得到的是一条唯一可通行路径,路径上存在可以通过换道到达相同目的地的路径,因此需要对得到的路径进行向前、向后两个方向的扩展:
红色laneID为向前搜索新增的节点,橙色laneID为向后搜索新增的节点。13.2.3 生成RoadSegments
遍历扩展得到的可通行区域,依据是否可以通过换道到到达该节点,对扩展的可性行进行道路段构建:
生成的Response中,包含road,passage,segment信息,为一条指引从起点到达终点的行驶路径的节点索引,roadID为第一个节点对应的道路ID,不包含车道中心线每个位置点信息,所以不能直接用于Planning模块。
将生成的Rosponse信息发送出去,Planning模块接受导航信息,然后生成PNC_Map,指引生成参考线轨迹,用于规划控制。14 Transform
| 参考文章 | | —- | | 百度Apollo无人驾驶图解传感器地球之间的坐标关系以及如何转换 - 知乎 (zhihu.com) | | 百度Apollo智能驾驶进阶课程—第三章 百度Apollo定位技术 | | Apollo项目坐标系研究知行合一2018的博客-CSDN博客apollo 坐标系 | | 三、Apollo自定位技术详解(入门技术与基础知识)一只小麻团的博客-CSDN博客apollo定位 |
主要的用途是进行坐标转换。
百度Apollo项目用到了多种坐标系,其中帮助文档提及的坐标系包括:全球地理坐标系(The Global Geographic coordinate system )、局部坐标系—东-北-天坐标(The Local Frame– East-North-Up,ENU)、车身坐标系—右-前-天坐标(The Vehicle Frame —Right-Forward-Up,RFU)、车身坐标系—前-左-天坐标(The Vehicle Frame —Front-Left-Up,FLU)。还有一种Frenet坐标系(又称Frenet–Serret公式),Apollo项目文档未提及,但在Apollo项目的规划模块中得到广泛使用。
14.1 常用的坐标系
坐标系 | 简述 | 特点 | 图示 | 例子 |
---|---|---|---|---|
地心惯性坐标系—i系(ECI) | 原点:地球原点;Z轴:沿地轴方向指向北极;X轴、Y轴:位于赤道平面内,与Z轴满足右手法则,并且分别指向两个恒星 | X、Y轴指向两颗恒星;不随地球自转而转动;可以作为地球附近传感器输出的惯性坐标系 | 红色坐标系 | 在研究载体在地球表面附近的运动时,近似看作关性坐标系,如IMU |
地心地固坐标系—e系(ECEF) | 原点:地球原点;Z轴:沿地轴方向指向北极;X轴:赤道平面与格林威治子午面的交线上;Y轴:在赤道平面,与X轴、Z轴满足右手法则 | 与地球固定在一起,随地球旋转;假如起始时刻i系与e系重合,二者旋转关系只与时间相关。旋转图示角度,i系与e系重合;地球表面的任意一点可以使用确定的坐标系(x,y,z)表示 | 绿色坐标系 | 常用的如WGS84坐标系系统 |
当地水平坐标系—l系 | 原点:载体所在的地球表面;X、Y轴在当地水平面内分别指向东和北,Z轴垂直向上,与X、Y轴满足右手法则 | 与地球固连在一起,随地球转动;与e系的旋转关系只与载体所在精度、纬度有关 | 蓝色坐标系 | 机器人领域的世界坐标系(w系);导航坐标系(n系);“东-北-天(E-N-U)”坐标系 |
通用横轴墨卡托投影(UTM投影) | “等角横轴割圆投影” :椭圆柱割地球于南纬80度、北纬84度两条等高圈,投影后两条相割的经线上没有变形,而中央经线上长度比0.9996。按经度分为60个带,没带6度,从西经180度算起 | 坐标(x,y)加投影带号才能唯一表示地球表面一点;坐标与经纬度或者ECEF坐标系有确定的转换关系 | 平时定位所输出的坐标系 | |
车体坐标系—b系 | 原点:载体质量中心与载体固连,车体选取原点在后轴中心位置;X轴:沿载体轴向指向右;Y轴:指向前;Z轴:与X、Y轴满足右手法则指向天。(R-F-U右前上坐标系) | 与载体固连在一起,随载体一起转动;与n系的旋转关系可以表征载体的当前姿态信息 | / | |
IMU坐标系 | 原点:陀螺仪和加速计的坐标原点;X、Y、Z三轴方向分别与陀螺仪和加速计的对于轴向平行 | 与载体固连在一起,不考虑安装偏角,与载体坐标系重合;与n系的旋转关系可以表征载体的当前姿态信息 | / | |
相机坐标系 | 图中O点为摄像机光心(投影中心),Xc轴和Yc轴与成像平面坐标系的x轴和y轴平行;Zc轴为摄像机的光轴,和图像平面垂直 | 通常IMU坐标系的原点在世界坐标系的位置是已知的,通过IMU坐标系到相机坐标系的外参,以及IMU坐标系的姿态,可以得到相机坐标系到世界坐标系的转换 | / | |
激光雷达坐标系 | 原点:多线束中心旋转轴的交点处,z轴沿轴线向上;X、Y轴如俯视图所示 | 通过IMU坐标系到激光雷达坐标系的外参,以及IMU坐标系的姿态,可以得到激光雷达坐标系到世界坐标系的转换 | / |
15 V2X
16 DreamView
参考文章 |
---|
【Apollo 6.0项目实战】Dreamview的使用Travis.X的博客-CSDN博客apollo dreamview |
DreamView是一个web应用程序,提供如下的功能:
- 可视化显示当前自动驾驶车辆模块的输出信息,例如规划路径、车辆定位、车架信息等。
- 为使用者提供人机交互接口以监测车辆硬件状态,对模块进行开关操作,启动自动驾驶车辆等。
- 提供调试工具,例如PnC监视器可以高效的跟踪模块输出的问题
17 其他优秀内容
| 参考文章 | | —- | | vscode中Apollo代码调试方法hello1268的博客-CSDN博客apollo 调试 |