本文档介绍用于读取、分析和可视化 openpilot 系统日志数据的工具和方法。openpilot 框架在行驶过程中会生成详细的日志,这些日志可用于调试、分析和开发目的。有关日志生成和存储方式的信息,请参阅系统日志记录文档。
Openpilot 将行驶数据存储在按路线和片段组织的结构化日志文件中。这些日志包含 Cap'n Proto 格式的时间戳消息,可实现高效存储和数据访问。
来源:tools/lib/route.py1-296 tools/lib/logreader.py1-340
Openpilot 日志分为两种主要类型:
这两种日志类型都包含 cereal schema 中定义的消息,大多数消息包含带时间戳的传感器读数、车辆状态、控制命令和内部处理结果。
LogReader 类是访问和处理 openpilot 日志的主要工具。它提供了一个简洁的接口,用于从本地和远程源读取、过滤和分析日志数据。
来源:tools/lib/logreader.py31-146 tools/lib/logreader.py257-329
LogReader 可以通过路线名称、片段编号或直接文件路径进行初始化。
来源:tools/lib/README.md1-60 tools/lib/logreader.py257-272
LogReader 支持以下关键操作来处理日志:
迭代消息:
按消息类型过滤:
获取消息类型的第一个出现:
跨片段并行处理:
来源:tools/lib/logreader.py277-328 tools/lib/README.md1-60
LogReader 支持强大的片段范围语法来指定要加载的片段。
| 语法 | 描述 |
|---|---|
/4 | 仅片段 4 |
/4:6 | 片段 4 和 5 |
/-1 | 最后一个片段 |
/1: | 除第一个片段外的所有片段 |
/:5 | 前 5 个片段 |
/0:10:2 | 片段 0, 2, 4, 6, 8 (步长=2) |
来源:tools/lib/logreader.py239-256 tools/lib/README.md34-61
PlotJuggler 是一个强大的工具,可通过交互式界面可视化 openpilot 日志。openpilot 项目包含一个自定义包装器(juggle.py),该包装器简化了 PlotJuggler 与 openpilot 日志的使用。
来源:tools/plotjuggler/juggle.py1-140 tools/plotjuggler/README.md1-75
要将 PlotJuggler 与 openpilot 日志一起使用,
来源:tools/plotjuggler/README.md1-75 tools/plotjuggler/juggle.py59-103
PlotJuggler 还可以可视化运行中的 openpilot 系统的实时数据。
来源:tools/plotjuggler/README.md47-55 tools/plotjuggler/juggle.py136
可以使用 replay 工具结合可视化功能,使用录制的数据模拟行驶过程。这对于调试和开发很有用。
来源:tools/replay/README.md1-149 tools/plotjuggler/README.md46-56
要将 replay 与 PlotJuggler 一起使用
这将允许 PlotJuggler 实时接收和可视化 replay 中的消息。
来源:tools/replay/README.md101-106
max_lat_accel.py 工具使用 LogReader 分析行车过程中的侧向加速度事件。
这利用了 LogReader 的并行处理能力,可以高效地在多个片段中查找事件,并创建侧向加速度与速度的图表。
来源:selfdrive/debug/max_lat_accel.py1-132
paramsd 模块在内部使用 LogReader 从日志中加载先前的校准值。
来源:selfdrive/locationd/paramsd.py222-260
LogReader 提供了一个 time_series 属性,该属性将日志消息转换为适合分析的时间格式。
来源:tools/lib/logreader.py326-328
对于更复杂的分析,您可以定义自定义处理函数以跨片段运行。
来源:tools/lib/logreader.py300-309
| 问题 | 解决方案 |
|---|---|
| 日志文件丢失 | 使用 ReadMode.AUTO 自动回退到可用的日志。 |
| 日志损坏 | LogReader 将跳过损坏的消息并发出警告。 |
| 处理大型日志 | 使用 run_across_segments() 和多进程以提高效率。 |
| 内存问题 | 一次处理一个片段,或使用 only_union_types=True 来过滤消息。 |
来源:tools/lib/logreader.py113-145 tools/lib/logreader.py72-79
处理大型日志文件时
run_across_segments() 进行并行处理only_union_types=True 来过滤掉非联合类型消息sort_by_time=True,因为它会增加开销来源: tools/lib/logreader.py300-309 tools/lib/tests/test_logreader.py221-228