Merge pull request 'Refractor/finger' (#4) from refractor/finger into dev
Reviewed-on: http://100.106.67.31:3000/orisys-tech/orisys-sdk/pulls/4
This commit was merged in pull request #4.
This commit is contained in:
@@ -6,7 +6,7 @@ a = Analysis(
|
|||||||
pathex=[],
|
pathex=[],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[('D:\\repo\\orisyssdk_git\\config', 'config'), ('D:\\repo\\orisyssdk_git\\assets', 'assets')],
|
datas=[('D:\\repo\\orisyssdk_git\\config', 'config'), ('D:\\repo\\orisyssdk_git\\assets', 'assets')],
|
||||||
hiddenimports=['PyQt5', 'pyqtgraph', 'open3d', 'cv2', 'orisys', 'gui', 'pipeline', 'viz', 'app_paths', 'plotly', '_plotly_utils', 'open3d.cpu.pybind'],
|
hiddenimports=['PyQt5', 'pyqtgraph', 'open3d', 'cv2', 'orisys', 'gui', 'pipeline', 'viz', 'gui.app_paths', 'plotly', '_plotly_utils', 'open3d.cpu.pybind'],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
runtime_hooks=[],
|
runtime_hooks=[],
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ HIDDEN_IMPORTS = [
|
|||||||
"gui",
|
"gui",
|
||||||
"pipeline",
|
"pipeline",
|
||||||
"viz",
|
"viz",
|
||||||
"app_paths",
|
"gui.app_paths",
|
||||||
"plotly",
|
"plotly",
|
||||||
"_plotly_utils",
|
"_plotly_utils",
|
||||||
# sometimes needed for open3d:
|
# sometimes needed for open3d:
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ def copy_bundle_items(repo_root: Path, pkg_dir: Path, items: list[dict]) -> dict
|
|||||||
def package_data_from_bundle(ext_suffix: str, items: list[dict]) -> dict[str, list[str]]:
|
def package_data_from_bundle(ext_suffix: str, items: list[dict]) -> dict[str, list[str]]:
|
||||||
package_data: dict[str, list[str]] = {
|
package_data: dict[str, list[str]] = {
|
||||||
"orisys": [f"*{ext_suffix}"],
|
"orisys": [f"*{ext_suffix}"],
|
||||||
"orisys.examples": ["*.py", "README.md", "app_paths.py", "viz/**/*.py", "pipeline/**/*.py", "gui/**/*.py"],
|
"orisys.examples": ["*.py", "README.md", "viz/**/*.py", "pipeline/**/*.py", "gui/**/*.py"],
|
||||||
}
|
}
|
||||||
for item in items:
|
for item in items:
|
||||||
if item["name"] == "examples":
|
if item["name"] == "examples":
|
||||||
|
|||||||
+1
-2
@@ -5,7 +5,6 @@ Top-level demo scripts under `examples/`. Run them from the repository root.
|
|||||||
## Top-Level Files
|
## Top-Level Files
|
||||||
|
|
||||||
- `README.md` — this overview of the root-level example entry points
|
- `README.md` — this overview of the root-level example entry points
|
||||||
- `app_paths.py` — path helpers used by the packaged / frozen dashboard entry point
|
|
||||||
- `basic_pipeline.py` — basic single-sensor OpenCV demo for the compound-eye pipeline
|
- `basic_pipeline.py` — basic single-sensor OpenCV demo for the compound-eye pipeline
|
||||||
- `plot_data.py` — single-sensor demo with OpenCV views plus PyQtGraph force charts
|
- `plot_data.py` — single-sensor demo with OpenCV views plus PyQtGraph force charts
|
||||||
- `two_sensor_pipeline.py` — two-sensor multiprocessing demo for parallel acquisition / display
|
- `two_sensor_pipeline.py` — two-sensor multiprocessing demo for parallel acquisition / display
|
||||||
@@ -59,7 +58,7 @@ pip install -e ".[gui]"
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- `finger_pipeline_3dview.py` is the main interactive demo. It uses `app_paths.py` so the same entry point works in editable and packaged runs.
|
- `finger_pipeline_3dview.py` is the main interactive demo. It uses `gui/app_paths.py` so the same entry point works in editable and packaged runs.
|
||||||
- Dashboard controls: click **启动** to start acquisition; `Q` quits, `R` resets, `S` starts recording, `E` stops recording, and `Esc` toggles fullscreen.
|
- Dashboard controls: click **启动** to start acquisition; `Q` quits, `R` resets, `S` starts recording, `E` stops recording, and `Esc` toggles fullscreen.
|
||||||
- `finger_pipeline.py` is the leanest finger example if you want to validate UV unroll + force/contact processing without the full dashboard.
|
- `finger_pipeline.py` is the leanest finger example if you want to validate UV unroll + force/contact processing without the full dashboard.
|
||||||
- `finger_pipeline.py` uses `orisys.finger.FingerRuntime` as the high-level entry point, then runs tactile analysis through `runtime.tactile`.
|
- `finger_pipeline.py` uses `orisys.finger.FingerRuntime` as the high-level entry point, then runs tactile analysis through `runtime.tactile`.
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ For the full demo (UV debug panels, dashboard, benchmarks) see:
|
|||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
|
|
||||||
os.environ.setdefault("OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS", "0")
|
os.environ.setdefault("OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS", "0")
|
||||||
|
|
||||||
@@ -20,19 +19,6 @@ import cv2
|
|||||||
import orisys
|
import orisys
|
||||||
from orisys.finger import FingerRuntime
|
from orisys.finger import FingerRuntime
|
||||||
|
|
||||||
from pipeline.profiling import StageProfiler, run_deformation_timed
|
|
||||||
|
|
||||||
_FINGER_PIPELINE_STAGES = (
|
|
||||||
"capture",
|
|
||||||
"uv_unroll",
|
|
||||||
"flow",
|
|
||||||
"hhd",
|
|
||||||
"contact",
|
|
||||||
"read_info",
|
|
||||||
"display",
|
|
||||||
"total",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Minimum UV-unroll finger tactile pipeline")
|
parser = argparse.ArgumentParser(description="Minimum UV-unroll finger tactile pipeline")
|
||||||
@@ -41,17 +27,6 @@ def main():
|
|||||||
parser.add_argument("--config", "-c", default="./config/dd02-ov.json", help="Orisys SDK config")
|
parser.add_argument("--config", "-c", default="./config/dd02-ov.json", help="Orisys SDK config")
|
||||||
parser.add_argument("--show", action="store_true", default=True, help="Show unrolled image window")
|
parser.add_argument("--show", action="store_true", default=True, help="Show unrolled image window")
|
||||||
parser.add_argument("--verbose", action="store_true", help="SDK verbose logs")
|
parser.add_argument("--verbose", action="store_true", help="SDK verbose logs")
|
||||||
parser.add_argument(
|
|
||||||
"--profile",
|
|
||||||
action="store_true",
|
|
||||||
help="Print per-stage timing (capture, UV, flow, HHD, contact, read_info, display)",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--profile-every",
|
|
||||||
type=int,
|
|
||||||
default=30,
|
|
||||||
help="When --profile is set, print rolling averages every N frames (default: 30)",
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -77,48 +52,17 @@ def main():
|
|||||||
|
|
||||||
runtime.warmup(color=False)
|
runtime.warmup(color=False)
|
||||||
tactile = runtime.tactile
|
tactile = runtime.tactile
|
||||||
profiler = (
|
|
||||||
StageProfiler(report_every=args.profile_every, stage_order=_FINGER_PIPELINE_STAGES)
|
|
||||||
if args.profile
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
|
|
||||||
print("Press 'q' to quit, 'r' to reset tracker.")
|
print("Press 'q' to quit, 'r' to reset tracker.")
|
||||||
if args.profile:
|
|
||||||
print(f"Profiling enabled (report every {args.profile_every} frames).")
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
frame_t0 = time.perf_counter()
|
|
||||||
|
|
||||||
if profiler is not None:
|
|
||||||
t0 = time.perf_counter()
|
|
||||||
ok, frame = runtime.read_source()
|
|
||||||
profiler.record("capture", (time.perf_counter() - t0) * 1000.0)
|
|
||||||
if not ok:
|
|
||||||
break
|
|
||||||
t0 = time.perf_counter()
|
|
||||||
unrolled = runtime.process_frame(frame, color=False)
|
|
||||||
profiler.record("uv_unroll", (time.perf_counter() - t0) * 1000.0)
|
|
||||||
else:
|
|
||||||
ok, unrolled = runtime.grab_and_process(color=False)
|
ok, unrolled = runtime.grab_and_process(color=False)
|
||||||
if not ok:
|
if not ok:
|
||||||
break
|
break
|
||||||
|
|
||||||
if profiler is not None:
|
|
||||||
flow_ms, hhd_ms = run_deformation_timed(
|
|
||||||
tactile, check_motion=True, threshold=0
|
|
||||||
)
|
|
||||||
profiler.record("flow", flow_ms)
|
|
||||||
profiler.record("hhd", hhd_ms)
|
|
||||||
else:
|
|
||||||
tactile.compute_deformation(check_motion=True, threshold=0)
|
tactile.compute_deformation(check_motion=True, threshold=0)
|
||||||
|
|
||||||
t0 = time.perf_counter()
|
|
||||||
tactile.compute_contact()
|
tactile.compute_contact()
|
||||||
if profiler is not None:
|
|
||||||
profiler.record("contact", (time.perf_counter() - t0) * 1000.0)
|
|
||||||
|
|
||||||
t0 = time.perf_counter()
|
|
||||||
fps, flow, vnormal, img, contour, centroid, depth_map, fnormal, fshearx, fsheary = tactile.read_info(
|
fps, flow, vnormal, img, contour, centroid, depth_map, fnormal, fshearx, fsheary = tactile.read_info(
|
||||||
tactile.info.FPS,
|
tactile.info.FPS,
|
||||||
tactile.info.VRAW,
|
tactile.info.VRAW,
|
||||||
@@ -131,8 +75,6 @@ def main():
|
|||||||
tactile.info.FSHEARX,
|
tactile.info.FSHEARX,
|
||||||
tactile.info.FSHEARY,
|
tactile.info.FSHEARY,
|
||||||
)
|
)
|
||||||
if profiler is not None:
|
|
||||||
profiler.record("read_info", (time.perf_counter() - t0) * 1000.0)
|
|
||||||
|
|
||||||
status = (
|
status = (
|
||||||
f"FPS={fps:.2f} normal={fnormal:.2f} shear=({fshearx:.2f}, {fsheary:.2f}) "
|
f"FPS={fps:.2f} normal={fnormal:.2f} shear=({fshearx:.2f}, {fsheary:.2f}) "
|
||||||
@@ -140,7 +82,6 @@ def main():
|
|||||||
)
|
)
|
||||||
|
|
||||||
if args.show:
|
if args.show:
|
||||||
t0 = time.perf_counter()
|
|
||||||
arrows = orisys.util.draw_arrows(
|
arrows = orisys.util.draw_arrows(
|
||||||
unrolled,
|
unrolled,
|
||||||
flow,
|
flow,
|
||||||
@@ -149,17 +90,7 @@ def main():
|
|||||||
arrow_scale=1.0,
|
arrow_scale=1.0,
|
||||||
)
|
)
|
||||||
cv2.imshow("UV Unrolled", arrows)
|
cv2.imshow("UV Unrolled", arrows)
|
||||||
if profiler is not None:
|
|
||||||
profiler.record("display", (time.perf_counter() - t0) * 1000.0)
|
|
||||||
|
|
||||||
if profiler is not None:
|
|
||||||
total_ms = (time.perf_counter() - frame_t0) * 1000.0
|
|
||||||
profiler.record("total", total_ms)
|
|
||||||
status += (
|
|
||||||
f" | wall={total_ms:.1f}ms flow={profiler.last.get('flow', 0):.1f}ms"
|
|
||||||
f" hhd={profiler.last.get('hhd', 0):.1f}ms"
|
|
||||||
)
|
|
||||||
profiler.tick()
|
|
||||||
print(status, end="\r")
|
print(status, end="\r")
|
||||||
|
|
||||||
key = cv2.waitKey(1) & 0xFF
|
key = cv2.waitKey(1) & 0xFF
|
||||||
@@ -170,8 +101,6 @@ def main():
|
|||||||
tactile.reset()
|
tactile.reset()
|
||||||
print("\nTracker reset.")
|
print("\nTracker reset.")
|
||||||
finally:
|
finally:
|
||||||
if profiler is not None and profiler.frame_count:
|
|
||||||
profiler.print_report(prefix="[profile final]")
|
|
||||||
runtime.close()
|
runtime.close()
|
||||||
cv2.destroyAllWindows()
|
cv2.destroyAllWindows()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import sys
|
|||||||
|
|
||||||
os.environ.setdefault("OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS", "0")
|
os.environ.setdefault("OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS", "0")
|
||||||
|
|
||||||
from app_paths import configure_frozen_runtime, default_config_path, ensure_examples_import_path
|
from gui.app_paths import configure_frozen_runtime, default_config_path, ensure_examples_import_path
|
||||||
|
|
||||||
configure_frozen_runtime()
|
configure_frozen_runtime()
|
||||||
ensure_examples_import_path()
|
ensure_examples_import_path()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Resolve bundled resource paths for dev runs and Nuitka standalone builds."""
|
"""Resolve bundled resource paths for dev runs and standalone builds."""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
@@ -6,7 +6,8 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
_EXAMPLES_DIR = Path(__file__).resolve().parent
|
_GUI_DIR = Path(__file__).resolve().parent
|
||||||
|
_EXAMPLES_DIR = _GUI_DIR.parent
|
||||||
_REPO_ROOT = _EXAMPLES_DIR.parent
|
_REPO_ROOT = _EXAMPLES_DIR.parent
|
||||||
|
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ from PyQt5.QtWidgets import (
|
|||||||
from pipeline.config import PipelineConfig
|
from pipeline.config import PipelineConfig
|
||||||
from pipeline.service import FingerPipeline
|
from pipeline.service import FingerPipeline
|
||||||
|
|
||||||
from app_paths import resource_path
|
from .app_paths import resource_path
|
||||||
from .layout import (
|
from .layout import (
|
||||||
DashboardLayout,
|
DashboardLayout,
|
||||||
LAYOUT,
|
LAYOUT,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ def resolve_viz_pose_path(path: str | Path | None = None) -> Path:
|
|||||||
here.parents[2] / raw,
|
here.parents[2] / raw,
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
from app_paths import app_root
|
from gui.app_paths import app_root
|
||||||
|
|
||||||
candidates.insert(0, app_root() / raw)
|
candidates.insert(0, app_root() / raw)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ dev_install = true
|
|||||||
name = "examples"
|
name = "examples"
|
||||||
source = "examples"
|
source = "examples"
|
||||||
target = "examples"
|
target = "examples"
|
||||||
patterns = ["*.py", "README.md", "app_paths.py", "viz/**/*.py", "pipeline/**/*.py", "gui/**/*.py"]
|
patterns = ["*.py", "README.md", "viz/**/*.py", "pipeline/**/*.py", "gui/**/*.py"]
|
||||||
preserve_tree = true
|
preserve_tree = true
|
||||||
|
|
||||||
[[tool.orisys.bundle.items]]
|
[[tool.orisys.bundle.items]]
|
||||||
|
|||||||
Reference in New Issue
Block a user