rerun.io proof of concept (#32416)

* Adding demo version for acceleration only

* Adding, plot any event

* Adding dynamic blueprint creation and menu to choose what to plot

* Adding, pool of processes for faster data visualization

* Adding, install rerun if not present

* Adding. thumbnail support

* Refactoring, minor cleanup

* -Use rerun pre-release
-Remove json as a middle format
-Replace recursion with stack-based approach

* Refactoring, using services from cereal instead of hardcoding them

* Use of lr.run_across_segments instead of pool,
Use of python dict instead of capnp objs - better performance
Use LogReader syntax

* Enable logging of liveTracks, pandaStates

* Use of plotjuggler user experience

* Fixing bug in log_msg function

* cleanup

---------

Co-authored-by: savojovic <jovo.savic00@gmail.com>
Co-authored-by: savojovic <74861870+savojovic@users.noreply.github.com>
This commit is contained in:
Adeeb Shihadeh 2024-05-13 15:04:37 -07:00 committed by GitHub
parent 9287a69624
commit 1c481c5ad3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 104 additions and 0 deletions

104
tools/rerun/run.py Executable file
View File

@ -0,0 +1,104 @@
#!/usr/bin/env python3
import subprocess
import sys
import argparse
import multiprocessing
from functools import partial
from openpilot.tools.lib.logreader import LogReader
from cereal.services import SERVICE_LIST
NUM_CPUS = multiprocessing.cpu_count()
DEMO_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19"
WHEEL_URL = "https://build.rerun.io/commit/660463d/wheels"
def install():
# currently requires a preview release build
subprocess.run([sys.executable, "-m", "pip", "install", "--pre", "-f", WHEEL_URL, "--upgrade", "rerun-sdk"], check=True)
print("Rerun installed")
def log_msg(msg, parent_key=''):
stack = [(msg, parent_key)]
while stack:
current_msg, current_parent_key = stack.pop()
if isinstance(current_msg, list):
for index, item in enumerate(current_msg):
new_key = f"{current_parent_key}/{index}"
if isinstance(item, (int, float)):
rr.log(str(new_key), rr.Scalar(item))
elif isinstance(item, dict):
stack.append((item, new_key))
elif isinstance(current_msg, dict):
for key, value in current_msg.items():
new_key = f"{current_parent_key}/{key}"
if isinstance(value, (int, float)):
rr.log(str(new_key), rr.Scalar(value))
elif isinstance(value, dict):
stack.append((value, new_key))
elif isinstance(value, list):
for index, item in enumerate(value):
if isinstance(item, (int, float)):
rr.log(f"{new_key}/{index}", rr.Scalar(item))
else:
pass # Not a plottable value
def createBlueprint():
timeSeriesViews = []
for topic in sorted(SERVICE_LIST.keys()):
timeSeriesViews.append(rrb.TimeSeriesView(name=topic, origin=f"/{topic}/", visible=False))
rr.log(topic, rr.SeriesLine(name=topic), timeless=True)
blueprint = rrb.Blueprint(rrb.Grid(rrb.Vertical(*timeSeriesViews,rrb.SelectionPanel(expanded=False),rrb.TimePanel(expanded=False)),
rrb.Spatial2DView(name="thumbnail", origin="/thumbnail")))
return blueprint
def log_thumbnail(thumbnailMsg):
bytesImgData = thumbnailMsg.get('thumbnail')
rr.log("/thumbnail", rr.ImageEncoded(contents=bytesImgData))
def process(blueprint, lr):
ret = []
rr.init("rerun_test", spawn=True, default_blueprint=blueprint)
for msg in lr:
ret.append(msg)
rr.set_time_nanos("TIMELINE", msg.logMonoTime)
if msg.which() != "thumbnail":
log_msg(msg.to_dict()[msg.which()], msg.which())
else:
log_thumbnail(msg.to_dict()[msg.which()])
return ret
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="A helper to run rerun on openpilot routes",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--demo", action="store_true", help="Use the demo route instead of providing one")
parser.add_argument("--install", action="store_true", help="Install or update rerun")
parser.add_argument("route_or_segment_name", nargs='?', help="The route or segment name to plot")
if len(sys.argv) == 1:
parser.print_help()
sys.exit()
args = parser.parse_args()
if args.install:
install()
sys.exit()
try:
import rerun as rr
import rerun.blueprint as rrb
except ImportError:
print("Rerun is not installed, run with --install first")
sys.exit()
route_or_segment_name = DEMO_ROUTE if args.demo else args.route_or_segment_name.strip()
blueprint = createBlueprint()
print("Getting route log paths")
lr = LogReader(route_or_segment_name)
lr.run_across_segments(NUM_CPUS, partial(process, blueprint))