new demo route (#37456)
This commit is contained in:
@@ -8,13 +8,14 @@ import numpy as np
|
||||
from openpilot.common.utils import tabulate
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
|
||||
DEMO_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19"
|
||||
DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496"
|
||||
MB = 1024 * 1024
|
||||
TABULATE_OPTS = dict(tablefmt="simple_grid", stralign="center", numalign="center")
|
||||
|
||||
|
||||
def _get_procs():
|
||||
from openpilot.selfdrive.test.test_onroad import PROCS
|
||||
|
||||
return PROCS
|
||||
|
||||
|
||||
@@ -137,9 +138,9 @@ def print_process_tables(op_procs, other_procs, total_mb, use_pss):
|
||||
|
||||
op_rows, op_total = process_table_rows(op_procs, total_mb, use_pss, show_detail)
|
||||
# filter other: >5MB avg and not bare interpreter paths (test infra noise)
|
||||
other_filtered = {n: v for n, v in other_procs.items()
|
||||
if np.mean(v['pss' if use_pss else 'rss']) > 5.0
|
||||
and os.path.basename(n.split()[0]) not in ('python', 'python3')}
|
||||
other_filtered = {
|
||||
n: v for n, v in other_procs.items() if np.mean(v['pss' if use_pss else 'rss']) > 5.0 and os.path.basename(n.split()[0]) not in ('python', 'python3')
|
||||
}
|
||||
other_rows, other_total = process_table_rows(other_filtered, total_mb, use_pss, show_detail)
|
||||
|
||||
rows = op_rows
|
||||
|
||||
@@ -24,7 +24,7 @@ from openpilot.common.utils import Timer
|
||||
from msgq.visionipc import VisionIpcServer, VisionStreamType
|
||||
|
||||
FRAMERATE = 20
|
||||
DEMO_ROUTE, DEMO_START, DEMO_END = 'a2a0ccea32023010/2023-07-27--13-01-19', 90, 105
|
||||
DEMO_ROUTE, DEMO_START, DEMO_END = '5beb9b58bd12b691/0000010a--a51155e496', 90, 105
|
||||
|
||||
logger = logging.getLogger('clip')
|
||||
|
||||
@@ -81,6 +81,7 @@ def _download_segment(path: str) -> bytes:
|
||||
def _parse_and_chunk_segment(args: tuple) -> list[dict]:
|
||||
raw_data, fps = args
|
||||
from openpilot.tools.lib.logreader import _LogFileReader
|
||||
|
||||
messages = migrate_all(list(_LogFileReader("", dat=raw_data, sort_by_time=True)))
|
||||
if not messages:
|
||||
return []
|
||||
@@ -122,6 +123,7 @@ def patch_submaster(message_chunks, ui_state):
|
||||
sm.data[svc] = getattr(msg.as_builder(), svc)
|
||||
sm.logMonoTime[svc], sm.recv_time[svc], sm.recv_frame[svc] = msg.logMonoTime, t, sm.frame
|
||||
sm.frame += 1
|
||||
|
||||
ui_state.sm.update = mock_update
|
||||
|
||||
|
||||
@@ -150,8 +152,7 @@ def iter_segment_frames(camera_paths, start_time, end_time, fps=20, use_qcam=Fal
|
||||
if use_qcam:
|
||||
w, h = frame_size or get_frame_dimensions(path)
|
||||
with FileReader(path) as f:
|
||||
result = subprocess.run(["ffmpeg", "-v", "quiet", "-i", "-", "-f", "rawvideo", "-pix_fmt", "nv12", "-"],
|
||||
input=f.read(), capture_output=True)
|
||||
result = subprocess.run(["ffmpeg", "-v", "quiet", "-i", "-", "-f", "rawvideo", "-pix_fmt", "nv12", "-"], input=f.read(), capture_output=True)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(f"ffmpeg failed: {result.stderr.decode()}")
|
||||
seg_frames = np.frombuffer(result.stdout, dtype=np.uint8).reshape(-1, w * h * 3 // 2)
|
||||
@@ -172,8 +173,7 @@ class FrameQueue:
|
||||
self.frame_w, self.frame_h = get_frame_dimensions(first_path)
|
||||
|
||||
self._queue, self._stop, self._error = queue.Queue(maxsize=prefetch_count), threading.Event(), None
|
||||
self._thread = threading.Thread(target=self._worker,
|
||||
args=(camera_paths, start_time, end_time, fps, use_qcam, (self.frame_w, self.frame_h)), daemon=True)
|
||||
self._thread = threading.Thread(target=self._worker, args=(camera_paths, start_time, end_time, fps, use_qcam, (self.frame_w, self.frame_h)), daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
def _worker(self, camera_paths, start_time, end_time, fps, use_qcam, frame_size):
|
||||
@@ -208,6 +208,7 @@ class FrameQueue:
|
||||
|
||||
def load_route_metadata(route):
|
||||
from openpilot.common.params import Params, UnknownKeyName
|
||||
|
||||
path = next((item for item in route.log_paths() if item), None)
|
||||
if not path:
|
||||
raise Exception('error getting route metadata: cannot find any uploaded logs')
|
||||
@@ -223,15 +224,20 @@ def load_route_metadata(route):
|
||||
|
||||
origin = init_data.gitRemote.split('/')[3] if len(init_data.gitRemote.split('/')) > 3 else 'unknown'
|
||||
return {
|
||||
'version': init_data.version, 'route': route.name.canonical_name,
|
||||
'car': car_params.carFingerprint if car_params else 'unknown', 'origin': origin,
|
||||
'branch': init_data.gitBranch, 'commit': init_data.gitCommit[:7], 'modified': str(init_data.dirty).lower(),
|
||||
'version': init_data.version,
|
||||
'route': route.name.canonical_name,
|
||||
'car': car_params.carFingerprint if car_params else 'unknown',
|
||||
'origin': origin,
|
||||
'branch': init_data.gitBranch,
|
||||
'commit': init_data.gitCommit[:7],
|
||||
'modified': str(init_data.dirty).lower(),
|
||||
}
|
||||
|
||||
|
||||
def draw_text_box(text, x, y, size, gui_app, font, color=None, center=False):
|
||||
import pyray as rl
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
|
||||
box_color, text_color = rl.Color(0, 0, 0, 85), color or rl.WHITE
|
||||
text_size = measure_text_cached(font, text, size)
|
||||
text_width, text_height = int(text_size.x), int(text_size.y)
|
||||
@@ -244,6 +250,7 @@ def draw_text_box(text, x, y, size, gui_app, font, color=None, center=False):
|
||||
def render_overlays(gui_app, font, big, metadata, title, start_time, frame_idx, show_metadata, show_time):
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.lib.wrap_text import wrap_text
|
||||
|
||||
metadata_size = 16 if big else 12
|
||||
title_size = 32 if big else 24
|
||||
time_size = 24 if big else 16
|
||||
@@ -259,8 +266,17 @@ def render_overlays(gui_app, font, big, metadata, title, start_time, frame_idx,
|
||||
# Metadata overlay (first 5 seconds)
|
||||
if show_metadata and metadata and frame_idx < FRAMERATE * 5:
|
||||
m = metadata
|
||||
text = ", ".join([f"openpilot v{m['version']}", f"route: {m['route']}", f"car: {m['car']}", f"origin: {m['origin']}",
|
||||
f"branch: {m['branch']}", f"commit: {m['commit']}", f"modified: {m['modified']}"])
|
||||
text = ", ".join(
|
||||
[
|
||||
f"openpilot v{m['version']}",
|
||||
f"route: {m['route']}",
|
||||
f"car: {m['car']}",
|
||||
f"origin: {m['origin']}",
|
||||
f"branch: {m['branch']}",
|
||||
f"commit: {m['commit']}",
|
||||
f"modified: {m['modified']}",
|
||||
]
|
||||
)
|
||||
# Wrap text if too wide (leave margin on each side)
|
||||
margin = 2 * (time_width + 10 if show_time else 20) # leave enough margin for time overlay
|
||||
max_width = gui_app.width - margin
|
||||
@@ -278,17 +294,29 @@ def render_overlays(gui_app, font, big, metadata, title, start_time, frame_idx,
|
||||
draw_text_box(title, 0, 60, title_size, gui_app, font, center=True)
|
||||
|
||||
|
||||
def clip(route: Route, output: str, start: int, end: int, headless: bool = True, big: bool = False,
|
||||
title: str | None = None, show_metadata: bool = True, show_time: bool = True, use_qcam: bool = False):
|
||||
def clip(
|
||||
route: Route,
|
||||
output: str,
|
||||
start: int,
|
||||
end: int,
|
||||
headless: bool = True,
|
||||
big: bool = False,
|
||||
title: str | None = None,
|
||||
show_metadata: bool = True,
|
||||
show_time: bool = True,
|
||||
use_qcam: bool = False,
|
||||
):
|
||||
timer, duration = Timer(), end - start
|
||||
|
||||
import pyray as rl
|
||||
|
||||
if big:
|
||||
from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView
|
||||
else:
|
||||
from openpilot.selfdrive.ui.mici.onroad.augmented_road_view import AugmentedRoadView
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import gui_app, FontWeight
|
||||
|
||||
timer.lap("import")
|
||||
|
||||
logger.info(f"Clipping {route.name.canonical_name}, {start}s-{end}s ({duration}s)")
|
||||
@@ -297,7 +325,7 @@ def clip(route: Route, output: str, start: int, end: int, headless: bool = True,
|
||||
timer.lap("logs")
|
||||
|
||||
frame_start = (start - seg_start * 60) * FRAMERATE
|
||||
message_chunks = all_chunks[frame_start:frame_start + duration * FRAMERATE]
|
||||
message_chunks = all_chunks[frame_start : frame_start + duration * FRAMERATE]
|
||||
if not message_chunks:
|
||||
logger.error("No messages to render")
|
||||
sys.exit(1)
|
||||
@@ -350,8 +378,18 @@ def main():
|
||||
args = parse_args()
|
||||
|
||||
setup_env(args.output, big=args.big, speed=args.speed, target_mb=args.file_size, duration=args.end - args.start)
|
||||
clip(Route(args.route, data_dir=args.data_dir), args.output, args.start, args.end, not args.windowed,
|
||||
args.big, args.title, not args.no_metadata, not args.no_time_overlay, args.qcam)
|
||||
clip(
|
||||
Route(args.route, data_dir=args.data_dir),
|
||||
args.output,
|
||||
args.start,
|
||||
args.end,
|
||||
not args.windowed,
|
||||
args.big,
|
||||
args.title,
|
||||
not args.no_metadata,
|
||||
not args.no_time_overlay,
|
||||
args.qcam,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -12,7 +12,7 @@ from openpilot.tools.jotpluggler.data import DataManager
|
||||
from openpilot.tools.jotpluggler.datatree import DataTree
|
||||
from openpilot.tools.jotpluggler.layout import LayoutManager
|
||||
|
||||
DEMO_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19"
|
||||
DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496"
|
||||
|
||||
|
||||
class WorkerManager:
|
||||
@@ -120,6 +120,7 @@ class PlaybackManager:
|
||||
if callback in self.x_axis_observers:
|
||||
self.x_axis_observers.remove(callback)
|
||||
|
||||
|
||||
class MainController:
|
||||
def __init__(self, scale: float = 1.0):
|
||||
self.scale = scale
|
||||
@@ -197,8 +198,12 @@ class MainController:
|
||||
if dpg.does_item_exist("save_layout_dialog"):
|
||||
dpg.delete_item("save_layout_dialog")
|
||||
with dpg.file_dialog(
|
||||
callback=self._save_layout_callback, tag="save_layout_dialog", width=int(700 * self.scale), height=int(400 * self.scale),
|
||||
default_filename="layout", default_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "layouts")
|
||||
callback=self._save_layout_callback,
|
||||
tag="save_layout_dialog",
|
||||
width=int(700 * self.scale),
|
||||
height=int(400 * self.scale),
|
||||
default_filename="layout",
|
||||
default_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "layouts"),
|
||||
):
|
||||
dpg.add_file_extension(".yaml")
|
||||
|
||||
@@ -206,8 +211,11 @@ class MainController:
|
||||
if dpg.does_item_exist("load_layout_dialog"):
|
||||
dpg.delete_item("load_layout_dialog")
|
||||
with dpg.file_dialog(
|
||||
callback=self._load_layout_callback, tag="load_layout_dialog", width=int(700 * self.scale), height=int(400 * self.scale),
|
||||
default_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "layouts")
|
||||
callback=self._load_layout_callback,
|
||||
tag="load_layout_dialog",
|
||||
width=int(700 * self.scale),
|
||||
height=int(400 * self.scale),
|
||||
default_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "layouts"),
|
||||
):
|
||||
dpg.add_file_extension(".yaml")
|
||||
|
||||
@@ -314,21 +322,23 @@ def main(route_to_load=None, layout_to_load=None):
|
||||
dpg.create_context()
|
||||
|
||||
# TODO: find better way of calculating display scaling
|
||||
#try:
|
||||
# try:
|
||||
# w, h = next(tuple(map(int, l.split()[0].split('x'))) for l in subprocess.check_output(['xrandr']).decode().split('\n') if '*' in l) # actual resolution
|
||||
# scale = pyautogui.size()[0] / w # scaled resolution
|
||||
#except Exception:
|
||||
# except Exception:
|
||||
# scale = 1
|
||||
scale = 1
|
||||
|
||||
with dpg.font_registry():
|
||||
default_font = dpg.add_font(os.path.join(BASEDIR, "selfdrive/assets/fonts/JetBrainsMono-Medium.ttf"), int(13 * scale * 2)) # 2x then scale for hidpi
|
||||
default_font = dpg.add_font(os.path.join(BASEDIR, "selfdrive/assets/fonts/JetBrainsMono-Medium.ttf"), int(13 * scale * 2)) # 2x then scale for hidpi
|
||||
dpg.bind_font(default_font)
|
||||
dpg.set_global_font_scale(0.5)
|
||||
|
||||
viewport_width, viewport_height = int(1200 * scale), int(800 * scale)
|
||||
dpg.create_viewport(
|
||||
title='JotPluggler', width=viewport_width, height=viewport_height,
|
||||
title='JotPluggler',
|
||||
width=viewport_width,
|
||||
height=viewport_height,
|
||||
)
|
||||
dpg.setup_dearpygui()
|
||||
|
||||
@@ -358,6 +368,7 @@ def main(route_to_load=None, layout_to_load=None):
|
||||
controller.shutdown()
|
||||
dpg.destroy_context()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="A tool for visualizing openpilot logs.")
|
||||
parser.add_argument("--demo", action="store_true", help="Use the demo route instead of providing one")
|
||||
|
||||
@@ -21,7 +21,7 @@ juggle_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
os.environ['LD_LIBRARY_PATH'] = os.environ.get('LD_LIBRARY_PATH', '') + f":{juggle_dir}/bin/"
|
||||
|
||||
DEMO_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19"
|
||||
DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496"
|
||||
RELEASES_URL = "https://github.com/commaai/PlotJuggler/releases/download/latest"
|
||||
INSTALL_DIR = os.path.join(juggle_dir, "bin")
|
||||
PLOTJUGGLER_BIN = os.path.join(juggle_dir, "bin/plotjuggler")
|
||||
@@ -105,8 +105,7 @@ def juggle_route(route_or_segment_name, can, layout, dbc, should_migrate):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="A helper to run PlotJuggler on openpilot routes",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser = argparse.ArgumentParser(description="A helper to run PlotJuggler 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("--can", action="store_true", help="Parse CAN data")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "tools/replay/seg_mgr.h"
|
||||
#include "tools/replay/timeline.h"
|
||||
|
||||
#define DEMO_ROUTE "a2a0ccea32023010|2023-07-27--13-01-19"
|
||||
#define DEMO_ROUTE "5beb9b58bd12b691/0000010a--a51155e496"
|
||||
|
||||
enum REPLAY_FLAGS {
|
||||
REPLAY_FLAG_NONE = 0x0000,
|
||||
|
||||
Reference in New Issue
Block a user