Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions selfdrive/test/process_replay/card_diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
import argparse
import pickle
import sys
from collections import Counter, defaultdict
from pathlib import Path

from openpilot.tools.lib.logreader import LogReader
from openpilot.selfdrive.test.process_replay.process_replay import (
replay_process, get_process_config, check_openpilot_enabled,
)
from openpilot.selfdrive.test.process_replay.compare_logs import (
compare_logs, format_process_diff,
)
from opendbc.car.tests.car_diff import dict_diff, format_diff, IGNORE_FIELDS, TOLERANCE

CARD_CFG = get_process_config("card")


def run_card(route):
lr = list(LogReader(route))
if not check_openpilot_enabled(lr):
print(f"Warning: {route} never engaged")
return replay_process(CARD_CFG, lr)


def main():
parser = argparse.ArgumentParser()
parser.add_argument("route")
parser.add_argument("--ref", help="Reference route or .pkl file")
parser.add_argument("--save", help="Save to .pkl")
args = parser.parse_args()

print(f"Replaying: {args.route}")
new = run_card(args.route)
print(f"Got {len(new)} msgs: {dict(Counter(m.which() for m in new))}")

if args.save:
Path(args.save).write_bytes(pickle.dumps(new))
print(f"Saved: {args.save}")
return 0

if not args.ref:
print("Use --ref to compare or --save to save")
return 0

ref = pickle.loads(Path(args.ref).read_bytes()) if args.ref.endswith(".pkl") else run_card(args.ref)

diffs = compare_logs(ref, new, ignore_fields=CARD_CFG.ignore, tolerance=CARD_CFG.tolerance)

if not diffs:
print("PASS: no diffs")
return 0

diff, _ = format_process_diff(diffs)
print(f"\n{len(diffs)} diffs:")
print(diff)

ref_states = [(m.logMonoTime, m.carState) for m in ref if m.which() == "carState"]
new_states = [m.carState for m in new if m.which() == "carState"]

by_field = defaultdict(list)
for i, ((ts, r), n) in enumerate(zip(ref_states, new_states)):
for d in dict_diff(r.to_dict(), n.to_dict(), ignore=IGNORE_FIELDS, tolerance=TOLERANCE):
by_field[d[1]].append((d[1], i, d[2], ts))

for field, fd in sorted(by_field.items()):
print(f" {field} ({len(fd)} diffs)")
for line in format_diff(fd, ref_states, new_states, field):
print(line)

return 1


if __name__ == "__main__":
sys.exit(main())
Loading