diff --git a/tools/longitudinal_maneuvers/generate_report.py b/tools/longitudinal_maneuvers/generate_report.py
old mode 100644
new mode 100755
index 354d3bab34..9873a899b1
--- a/tools/longitudinal_maneuvers/generate_report.py
+++ b/tools/longitudinal_maneuvers/generate_report.py
@@ -1,48 +1,60 @@
+#!/usr/bin/env python3
+import argparse
+import base64
import io
import os
+import json
import time
-import base64
-import argparse
-import numpy as np
-import matplotlib.pyplot as plt
from collections import defaultdict
-from dataclasses import dataclass, asdict
from pathlib import Path
+import matplotlib.pyplot as plt
+from openpilot.tools.lib.logreader import LogReader
-def report(args, logs, fp):
+
+# TODO any import for this?
+REALDATA = Path('/home/batman/.comma/media/0/realdata')
+
+
+def report(platform, maneuvers):
output_path = Path(__file__).resolve().parent / "longitudinal_reports"
- output_fn = args.output or output_path / f"{fp}_{time.strftime('%Y%m%d-%H_%M_%S')}.html"
+ output_fn = output_path / f"{platform}_{time.strftime('%Y%m%d-%H_%M_%S')}.html"
output_path.mkdir(exist_ok=True)
with open(output_fn, "w") as f:
f.write("
Longitudinal maneuver report
\n")
- f.write(f"{fp}
\n")
- if args.desc:
- f.write(f"{args.desc}
")
- for description, runs in logs.items():
+ f.write(f"{platform}
\n")
+ # if args.desc:
+ # f.write(f"{args.desc}
")
+ for description, runs in maneuvers:
+ print('using description:', description)
f.write("\n")
f.write(f"{description}
\n")
- for run, log in runs.items():
+ for run, msgs in enumerate(runs):
+ t_carControl, carControl = zip(*[(m.logMonoTime, m.carControl) for m in msgs if m.which() == 'carControl'])
+ t_carState, carState = zip(*[(m.logMonoTime, m.carState) for m in msgs if m.which() == 'carState'])
+ t_longitudinalPlan, longitudinalPlan = zip(*[(m.logMonoTime, m.longitudinalPlan) for m in msgs if m.which() == 'longitudinalPlan'])
+
f.write(f"Run #{int(run)+1}
\n")
plt.rcParams['font.size'] = 40
fig = plt.figure(figsize=(30, 25))
ax = fig.subplots(4, 1, sharex=True, gridspec_kw={'hspace': 0, 'height_ratios': [5, 3, 1, 1]})
ax[0].grid(linewidth=4)
- ax[0].plot(log["t"], log["carControl.actuators.accel"], label='accel command', linewidth=6)
- ax[0].plot(log["t"], log["carState.aEgo"], label='aEgo', linewidth=6)
+ ax[0].plot(t_carControl, [m.actuators.accel for m in carControl], label='accel command', linewidth=6)
+ ax[0].plot(t_longitudinalPlan, [m.aTarget for m in longitudinalPlan], label='accel target', linewidth=6)
+ ax[0].plot(t_carState, [m.aEgo for m in carState], label='aEgo', linewidth=6)
ax[0].set_ylabel('Acceleration (m/s^2)')
#ax[0].set_ylim(-6.5, 6.5)
ax[0].legend()
ax[1].grid(linewidth=4)
- ax[1].plot(log["t"], log["carState.vEgo"], 'g', label='vEgo', linewidth=6)
+ ax[1].plot(t_carState, [m.vEgo for m in carState], 'g', label='vEgo', linewidth=6)
ax[1].set_ylabel('Velocity (m/s)')
ax[1].legend()
- ax[2].plot(log["t"], log["carControl.enabled"], label='enabled', linewidth=6)
- ax[3].plot(log["t"], log["carState.gasPressed"], label='gasPressed', linewidth=6)
- ax[3].plot(log["t"], log["carState.brakePressed"], label='brakePressed', linewidth=6)
+ ax[2].plot(t_carControl, [m.enabled for m in carControl], label='enabled', linewidth=6)
+ ax[3].plot(t_carState, [m.gasPressed for m in carState], label='gasPressed', linewidth=6)
+ ax[3].plot(t_carState, [m.brakePressed for m in carState], label='brakePressed', linewidth=6)
for i in (2, 3):
ax[i].set_yticks([0, 1], minor=False)
ax[i].set_ylim(-1, 2)
@@ -56,6 +68,51 @@ def report(args, logs, fp):
buffer.seek(0)
f.write(f"
\n")
- import json
- f.write(f"{json.dumps(logs)}
")
+ # f.write(f"{json.dumps(logs)}
")
print(f"\nReport written to {output_fn}\n")
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Generate longitudinal maneuver report from route')
+ parser.add_argument('route', type=str, help='Route name (e.g. 00000000--5f742174be)')
+
+ args = parser.parse_args()
+
+ logs = defaultdict(dict)
+
+ segs = []
+ for seg in os.listdir(REALDATA):
+ if args.route == seg[:20]:
+ print(seg)
+ segs.append(seg)
+
+ lr = LogReader([str(REALDATA / seg / 'rlog') for seg in segs])
+
+ CP = lr.first('carParams')
+ platform = CP.carFingerprint
+ print('got platform', platform)
+
+ maneuvers: list[tuple[str, list[list]]] = []
+ active_prev = False
+ description_prev = None
+
+ for msg in lr:
+ if msg.which() == 'alertDebug':
+ active = 'Maneuver Active' in msg.alertDebug.alertText1
+ if active and not active_prev:
+ if msg.alertDebug.alertText2 == description_prev:
+ maneuvers[-1][1].append([])
+ else:
+ maneuvers.append((msg.alertDebug.alertText2, [[]]))
+ description_prev = maneuvers[-1][0]
+ active_prev = active
+ # print((msg.alertDebug.alertText1, msg.alertDebug.alertText2))
+
+ if active_prev:
+ maneuvers[-1][1][-1].append(msg)
+
+ # print(len(list(lr)))
+ for desc, msgs in maneuvers:
+ print(desc, len(msgs))
+
+ report(platform, maneuvers)
diff --git a/tools/sim/launch_openpilot.sh b/tools/sim/launch_openpilot.sh
index fa5ac731bd..ecbf1509eb 100755
--- a/tools/sim/launch_openpilot.sh
+++ b/tools/sim/launch_openpilot.sh
@@ -6,7 +6,7 @@ export SIMULATION="1"
export SKIP_FW_QUERY="1"
export FINGERPRINT="HONDA_CIVIC_2022"
-export BLOCK="${BLOCK},camerad,loggerd,encoderd,micd,logmessaged"
+export BLOCK="${BLOCK},camerad,encoderd,micd,logmessaged"
if [[ "$CI" ]]; then
# TODO: offscreen UI should work
export BLOCK="${BLOCK},ui"