Openpilot技术解析:架构、数据结构与核心模块详解
Openpilot技术解析:架构、数据结构与核心模块详解
Openpilot是一个基于Python语言编写的自动驾驶开源项目,其主要通过ZMQ进行进程间通信,采用订阅者和发布者模式。该项目可以分为定位、决策、控制等几个模块,主要支持车道保持、ACC巡航、自动辅助变道等功能。本文将详细介绍openpilot的整体架构、数据结构以及其核心模块的工作原理。
0. Openpilot是什么
首先我们需要对Openpilot有一个清楚的认知。Openpilot主要基于Python语言编写,进程之间通过ZMQ进行通信,使用订阅者和发布者模式。进程订阅其他进程的信息,进行一系列处理后,将得到的结果发布出去,让其他进程获取其处理结果。
整个Openpilot项目可以分为以下几个模块:定位、决策、控制等部分。Openpilot的实现原理类似于特斯拉的纯视觉解决方案,但由于只有两颗摄像头(一颗用于拍摄路况,另一颗用于监控驾驶员),因此功能相对有限,主要支持车道保持、ACC巡航、自动辅助变道等三个功能。
如果要在汽车上使用,需要使用EON、Harness等官方设备进行对接安装。但Openpilot作为一个开源项目,我们可以轻松学习其中的操作和算法。即使没有特殊硬件或汽车,Openpilot的所有服务也可以在PC上正常运行。官方推荐使用Carla Simulator在模拟环境中运行Openpilot,使其能在Ubuntu机器上运行虚拟数据。
1. 数据结构
官方的代码结构比较清晰,我们先来看Openpilot的整体目录:
.
├── cereal # 用于所有日志的消息规范和LIB
├── common # Openpilot中开发的类库功能
├── docs # 文档
├── opendbc # 显示如何解释汽车数据的文件,并以人类可读的方式对理解车辆CAN总线流量所需的信息进行编码。
├── panda # CAN通信的代码
├── third_party # 扩展第三方文件包
├── pyextra # 扩展第三方Python文件包
└── selfdrive # 驾驶汽车所需的代码
├── assets # 用于用户界面的字体、图像和声音
├── athena # 允许与应用程序App实现通信
├── boardd # 守护进程与面板的通信
├── camerad # 通过驱动程序从摄像头传感器捕获图像
├── car # 用于读取状态和控制执行器的车辆特定代码
├── common # 用于守护程序的共享C/C++代码
├── controls # 规划和控制
├── debug # 帮助调试和执行汽车端口的工具
├── locationd # 精确定位与车辆参数估计
├── logcatd # Android logcat作为服务
├── loggerd # 汽车数据记录器和上传器
├── modeld # 驾驶和监控模型
├── proclogd # 从proc记录信息
├── sensord # IMU接口代码
├── test # 单元测试、系统测试和汽车模拟器
└── ui # 用户界面
从这里我们可以发现,基本上所有的核心操作都在selfdrive
内部,包括最核心的定位部分和规控部分。
上面的这些是Openpilot的目录结构,核心的部分就是controls
和locationd
两个部分,与上文对应的是下图Openpilot总体的架构图。首先作为输入部分深度学习模型位于modeld/models/supercombo.onnx
文件中,该模型拥有非常鲁邦的输入输出模型。网络backbone部分,采用了Google团队的Efficientnet-B2结构。该结构采用复合缩放策略,主要特点是效果好,速度快。卷积部分下采样5次,为了减少参数量,有几个conv是采用group conv,激活函数函数采用Elu。
输入数据:
image stream
:以20 Hz频率记录的连续图像帧(256x128 RGB)wide image stream
:以20 Hz频率记录的连续图像帧(256x128 RGB)desire
:命令模型发送one-hot encoded向量以执行某些操作:8traffic convention
:使用one-hot encoded向量告诉模型是右车道还是左车道:2recurrent state
:反馈到GRU中用于时间上下文的循环状态向量:512输出数据:
plan
:5条预计规划线在33个时间步的预测平均值和标准偏差:4955 = 5 * 2 * 33 * 15(x,y,z位置;x,y,z速度;x,y,z加速度;r,p,y角度;r,p,y角速度)lanelines
:4条Laneline(左外、左外、右外和右外)在33个时间步长下的预测平均值和标准偏差: 528 = 4 * 2 * 33 * 2laneline probabilties
:4条直线中的每一条都存在的概率:8=4*2road-edges
:2条道路边缘(左侧和右侧)在33个时间步长下的预测平均值和标准偏差:264=2 * 2 * 33 * 2leads
:潜在2个引导车的假设在0,2,4,6,8,10s时的预测平均值和标准偏差:102=2*(264+3)lead probabilities
:从现在起,在0、2、4s时刻有一辆领先车的概率:3=1*3desire state
:模型认为自己正在执行8个潜在期望动作中的每一个的概率:8meta
:关于场景的各种元数据:80=1+35+12+3pose
:当前平移和旋转速率的预测平均值和标准偏差:12=2*6recurrent state
:反馈到GRU中用于时间上下文的循环状态向量:512