diff --git a/selfdrive/debug/can_print_changes.py b/selfdrive/debug/can_print_changes.py index 2f31118e4..b883fbc23 100755 --- a/selfdrive/debug/can_print_changes.py +++ b/selfdrive/debug/can_print_changes.py @@ -5,6 +5,7 @@ import time from collections import defaultdict import cereal.messaging as messaging +from selfdrive.debug.can_table import can_table from tools.lib.logreader import logreader_from_route_or_segment RED = '\033[91m' @@ -36,7 +37,7 @@ def update(msgs, bus, dat, low_to_high, high_to_low, quiet=False): print(f"{time.monotonic():.2f}\t{hex(y.address)} ({y.address})\t{change}{binascii.hexlify(y.dat)}") -def can_printer(bus=0, init_msgs=None, new_msgs=None): +def can_printer(bus=0, init_msgs=None, new_msgs=None, table=False): logcan = messaging.sub_sock('can', timeout=10) dat = defaultdict(int) @@ -62,6 +63,7 @@ def can_printer(bus=0, init_msgs=None, new_msgs=None): pass print("\n\n") + tables = "" for addr in sorted(dat.keys()): init = low_to_high_init[addr] & high_to_low_init[addr] now = low_to_high[addr] & high_to_low[addr] @@ -69,9 +71,15 @@ def can_printer(bus=0, init_msgs=None, new_msgs=None): if d == 0: continue b = d.to_bytes(len(dat[addr]), byteorder='big') - byts = ''.join([(c if c == '0' else f'{RED}{c}{CLEAR}') for c in str(binascii.hexlify(b))[2:-1]]) - print(f"{hex(addr).ljust(6)}({str(addr).ljust(4)})", byts) + byts = ''.join([(c if c == '0' else f'{RED}{c}{CLEAR}') for c in str(binascii.hexlify(b))[2:-1]]) + header = f"{hex(addr).ljust(6)}({str(addr).ljust(4)})" + print(header, byts) + tables += f"{header}\n" + tables += can_table(b) + "\n\n" + + if table: + print(tables) if __name__ == "__main__": desc = """Collects messages and prints when a new bit transition is observed. @@ -80,6 +88,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description=desc, formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--bus", type=int, help="CAN bus to print out", default=0) + parser.add_argument("--table", action="store_true", help="Print a cabana-like table") parser.add_argument("init", type=str, nargs='?', help="Route or segment to initialize with") parser.add_argument("comp", type=str, nargs='?', help="Route or segment to compare against init") @@ -91,4 +100,4 @@ if __name__ == "__main__": if args.comp: new_lr = logreader_from_route_or_segment(args.comp) - can_printer(args.bus, init_msgs=init_lr, new_msgs=new_lr) + can_printer(args.bus, init_msgs=init_lr, new_msgs=new_lr, table=args.table) diff --git a/selfdrive/debug/can_table.py b/selfdrive/debug/can_table.py index b4d7cbbc1..e8cd084a3 100755 --- a/selfdrive/debug/can_table.py +++ b/selfdrive/debug/can_table.py @@ -5,6 +5,19 @@ import pandas as pd # pylint: disable=import-error import cereal.messaging as messaging +def can_table(dat): + rows = [] + for b in dat: + r = list(bin(b).lstrip('0b').zfill(8)) + r += [hex(b)] + rows.append(r) + + df = pd.DataFrame(data=rows) + df.columns = [str(n) for n in range(7, -1, -1)] + [' '] + table = df.to_markdown(tablefmt='grid') + return table + + if __name__ == "__main__": parser = argparse.ArgumentParser(description="Cabana-like table of bits for your terminal", formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -28,13 +41,5 @@ if __name__ == "__main__": if latest is None: continue - rows = [] - for b in latest.dat: - r = list(bin(b).lstrip('0b').zfill(8)) - r += [hex(b)] - rows.append(r) - - df = pd.DataFrame(data=rows) - df.columns = [str(n) for n in range(7, -1, -1)] + [' '] - table = df.to_markdown(tablefmt='grid') + table = can_table(latest.dat) print(f"\n\n{hex(addr)} ({addr}) on bus {args.bus}\n{table}")