You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
1.9 KiB
71 lines
1.9 KiB
#!/usr/bin/env python3
|
|
import os
|
|
import sys
|
|
import bz2
|
|
import urllib.parse
|
|
import capnp
|
|
import warnings
|
|
|
|
from typing import Iterable, Iterator
|
|
|
|
from cereal import log as capnp_log
|
|
from openpilot.tools.lib.filereader import FileReader
|
|
|
|
LogIterable = Iterable[capnp._DynamicStructReader]
|
|
|
|
|
|
class LogReader:
|
|
def __init__(self, fn, canonicalize=True, only_union_types=False, sort_by_time=False, dat=None):
|
|
self.data_version = None
|
|
self._only_union_types = only_union_types
|
|
|
|
ext = None
|
|
if not dat:
|
|
_, ext = os.path.splitext(urllib.parse.urlparse(fn).path)
|
|
if ext not in ('', '.bz2'):
|
|
# old rlogs weren't bz2 compressed
|
|
raise Exception(f"unknown extension {ext}")
|
|
|
|
with FileReader(fn) as f:
|
|
dat = f.read()
|
|
|
|
if ext == ".bz2" or dat.startswith(b'BZh9'):
|
|
dat = bz2.decompress(dat)
|
|
|
|
ents = capnp_log.Event.read_multiple_bytes(dat)
|
|
|
|
_ents = []
|
|
try:
|
|
for e in ents:
|
|
_ents.append(e)
|
|
except capnp.KjException:
|
|
warnings.warn("Corrupted events detected", RuntimeWarning, stacklevel=1)
|
|
|
|
self._ents = list(sorted(_ents, key=lambda x: x.logMonoTime) if sort_by_time else _ents)
|
|
self._ts = [x.logMonoTime for x in self._ents]
|
|
|
|
@classmethod
|
|
def from_bytes(cls, dat):
|
|
return cls("", dat=dat)
|
|
|
|
def __iter__(self) -> Iterator[capnp._DynamicStructReader]:
|
|
for ent in self._ents:
|
|
if self._only_union_types:
|
|
try:
|
|
ent.which()
|
|
yield ent
|
|
except capnp.lib.capnp.KjException:
|
|
pass
|
|
else:
|
|
yield ent
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import codecs
|
|
# capnproto <= 0.8.0 throws errors converting byte data to string
|
|
# below line catches those errors and replaces the bytes with \x__
|
|
codecs.register_error("strict", codecs.backslashreplace_errors)
|
|
log_path = sys.argv[1]
|
|
lr = LogReader(log_path, sort_by_time=True)
|
|
for msg in lr:
|
|
print(msg)
|
|
|