1. tuned arrow mesh drawing

2. centralixzed arrow config in layout.py
3. seperate mesh render and display resolution to speed up (~40 fps)
This commit is contained in:
ykcheungab
2026-06-19 14:28:28 +08:00
parent 3fd9b839a9
commit 2e5c047d1e
19 changed files with 980 additions and 147 deletions
+89 -21
View File
@@ -3,6 +3,7 @@
from __future__ import annotations
import time
from dataclasses import dataclass
import numpy as np
from orisys.finger import FingerRuntime
@@ -11,6 +12,18 @@ from viz import FrameRecorder, build_uv_surface_mesh, resolve_viz_pose_path
from .config import PipelineConfig
from .frame import FingerFrameView
from .profiling import StageProfiler, run_deformation_timed
@dataclass
class TickTimings:
capture_ms: float = 0.0
uv_unroll_ms: float = 0.0
flow_ms: float = 0.0
hhd_ms: float = 0.0
contact_ms: float = 0.0
read_info_ms: float = 0.0
pipeline_ms: float = 0.0
class FingerPipeline:
@@ -24,6 +37,9 @@ class FingerPipeline:
self.uv_mesh = None
self.world_to_cam: np.ndarray | None = None
self.mesh_lookat: np.ndarray | None = None
self.profiler: StageProfiler | None = (
StageProfiler(report_every=config.profile_every) if config.profile else None
)
@property
def is_open(self) -> bool:
@@ -60,6 +76,8 @@ class FingerPipeline:
self.mesh_lookat = self.uv_mesh.rest_vertices.mean(axis=0)
def close(self) -> None:
if self.profiler is not None and self.profiler.frame_count:
self.profiler.print_report(prefix="[profile final]")
if self.runtime is not None:
self.runtime.close()
self.runtime = None
@@ -69,33 +87,17 @@ class FingerPipeline:
if self.runtime is not None:
self.runtime.tactile.reset()
def tick(self) -> FingerFrameView | None:
if self.runtime is None or self._start_time is None:
return None
ok, unrolled = self.runtime.grab_and_process(color=self.config.use_color)
if not ok:
return None
tactile = self.runtime.tactile
self.recorder.write_if_recording(tactile.frame)
tactile.compute_deformation(decompose=True, check_motion=True, threshold=0)
tactile.compute_contact()
fps, flow, vnormal, img, contour, centroid, depth_map, fnormal, fshearx, fsheary = tactile.read_info(
def _read_frame_view(self, tactile, unrolled) -> FingerFrameView:
fps, flow, vnormal, depth_map, centroid, fnormal, fshearx, fsheary = tactile.read_info(
tactile.info.FPS,
tactile.info.VRAW,
tactile.info.VNORMAL,
tactile.info.IMG,
tactile.info.CONTOUR,
tactile.info.CENTROID,
tactile.info.DEPTH,
tactile.info.CENTROID,
tactile.info.FNORMAL,
tactile.info.FSHEARX,
tactile.info.FSHEARY,
)
return FingerFrameView(
timestamp=time.time() - self._start_time,
fps=float(fps),
@@ -103,8 +105,8 @@ class FingerPipeline:
flow=flow,
vnormal=vnormal,
depth_map=depth_map,
img=img,
contour=contour,
img=np.array([]),
contour=np.array([]),
centroid=centroid,
fnormal=float(fnormal),
fshearx=float(fshearx),
@@ -114,6 +116,72 @@ class FingerPipeline:
raw_frame=tactile.frame,
)
def tick(self) -> FingerFrameView | None:
frame, _timings = self.tick_timed()
return frame
def tick_timed(self) -> tuple[FingerFrameView | None, TickTimings]:
timings = TickTimings()
if self.runtime is None or self._start_time is None:
return None, timings
pipeline_t0 = time.perf_counter()
profile = self.profiler is not None
if profile:
t0 = time.perf_counter()
ok, frame = self.runtime.read_source()
timings.capture_ms = (time.perf_counter() - t0) * 1000.0
if not ok:
return None, timings
t0 = time.perf_counter()
unrolled = self.runtime.process_frame(frame, color=self.config.use_color)
timings.uv_unroll_ms = (time.perf_counter() - t0) * 1000.0
else:
ok, unrolled = self.runtime.grab_and_process(color=self.config.use_color)
if not ok:
return None, timings
tactile = self.runtime.tactile
self.recorder.write_if_recording(tactile.frame)
if profile:
flow_ms, hhd_ms = run_deformation_timed(
tactile, check_motion=True, threshold=0
)
timings.flow_ms = flow_ms
timings.hhd_ms = hhd_ms
self.profiler.record("capture", timings.capture_ms)
self.profiler.record("uv_unroll", timings.uv_unroll_ms)
self.profiler.record("flow", timings.flow_ms)
self.profiler.record("hhd", timings.hhd_ms)
else:
tactile.compute_deformation(decompose=True, check_motion=True, threshold=0)
t0 = time.perf_counter()
tactile.compute_contact()
timings.contact_ms = (time.perf_counter() - t0) * 1000.0
if profile:
self.profiler.record("contact", timings.contact_ms)
t0 = time.perf_counter()
view = self._read_frame_view(tactile, unrolled)
timings.read_info_ms = (time.perf_counter() - t0) * 1000.0
if profile:
self.profiler.record("read_info", timings.read_info_ms)
timings.pipeline_ms = (time.perf_counter() - pipeline_t0) * 1000.0
if profile:
self.profiler.record("pipeline", timings.pipeline_ms)
return view, timings
def record_total_frame(self, total_ms: float) -> None:
if self.profiler is None:
return
self.profiler.record("total", total_ms)
self.profiler.tick()
def start_recording(self) -> bool:
if self.runtime is None:
return False