86 lines
3.3 KiB
Python
86 lines
3.3 KiB
Python
"""
|
|
yolo_api.py — YOLO detection interface with fallback stubs
|
|
"""
|
|
import sys
|
|
import os
|
|
from Core.config_loader import load_config
|
|
from Core.env_loader import PROJECT_ROOT
|
|
|
|
YOLO_AVAILABLE = False
|
|
|
|
# Fallback stubs
|
|
def _stub_sees(c, **kw): return False
|
|
def _stub_count(c): return 0
|
|
def _stub_closest(c="person"): return None
|
|
def _stub_summary(): return "YOLO not loaded"
|
|
def _stub_ppe(): return []
|
|
def _stub_too_close(**k): return False
|
|
def _stub_all(): return set()
|
|
def _stub_fps(): return 0.0
|
|
|
|
yolo_sees = _stub_sees
|
|
yolo_count = _stub_count
|
|
yolo_closest = _stub_closest
|
|
yolo_summary = _stub_summary
|
|
yolo_ppe_violations = _stub_ppe
|
|
yolo_person_too_close = _stub_too_close
|
|
yolo_all_classes = _stub_all
|
|
yolo_fps = _stub_fps
|
|
|
|
|
|
def init_yolo(raw_frame_ref, frame_lock) -> bool:
|
|
"""Start YOLO inference. Returns True if successful."""
|
|
global YOLO_AVAILABLE
|
|
global yolo_sees, yolo_count, yolo_closest, yolo_summary
|
|
global yolo_ppe_violations, yolo_person_too_close, yolo_all_classes, yolo_fps
|
|
|
|
# marcus_yolo.py lives in Vision/
|
|
models_dir = os.path.join(PROJECT_ROOT, "Vision")
|
|
if models_dir not in sys.path:
|
|
sys.path.insert(0, models_dir)
|
|
|
|
try:
|
|
from marcus_yolo import (
|
|
start_yolo, yolo_sees as _ys, yolo_count as _yc, yolo_closest as _ycl,
|
|
yolo_summary as _ysu, yolo_ppe_violations as _ypp,
|
|
yolo_person_too_close as _yptc, yolo_all_classes as _yac, yolo_fps as _yfps,
|
|
)
|
|
except ImportError as e:
|
|
print(f"marcus_yolo.py not found ({e})")
|
|
return False
|
|
|
|
# GPU is required. _resolve_device() raises RuntimeError when CUDA is
|
|
# missing — surface that with an actionable banner before re-raising so
|
|
# Marcus hard-fails with a clear error instead of a raw stack trace.
|
|
try:
|
|
ok = start_yolo(raw_frame_ref=raw_frame_ref, frame_lock=frame_lock)
|
|
except RuntimeError as e:
|
|
print()
|
|
print("╔" + "═" * 68 + "╗")
|
|
print("║ MARCUS STARTUP ABORTED — GPU REQUIRED".ljust(69) + "║")
|
|
print("╠" + "═" * 68 + "╣")
|
|
print(f"║ {str(e)[:66]:<66} ║")
|
|
print("║" + " " * 68 + "║")
|
|
print("║ On the Jetson, verify:".ljust(69) + "║")
|
|
print("║ tegrastats # GPU exists & is not throttled".ljust(69) + "║")
|
|
print("║ python3 -c 'import torch; print(torch.cuda.is_available())'".ljust(69) + "║")
|
|
print("║ nvcc --version # CUDA toolkit reachable".ljust(69) + "║")
|
|
print("║ Expected: torch 2.1.0 nv23.06, CUDA 11.4, GPU=Orin.".ljust(69) + "║")
|
|
print("║ See Doc/environment.md section 9 for the reinstall recipe.".ljust(69) + "║")
|
|
print("╚" + "═" * 68 + "╝")
|
|
print()
|
|
raise
|
|
|
|
if ok:
|
|
YOLO_AVAILABLE = True
|
|
yolo_sees = _ys
|
|
yolo_count = _yc
|
|
yolo_closest = _ycl
|
|
yolo_summary = _ysu
|
|
yolo_ppe_violations = _ypp
|
|
yolo_person_too_close = _yptc
|
|
yolo_all_classes = _yac
|
|
yolo_fps = _yfps
|
|
print(f"YOLO {'started' if ok else 'failed to start'}")
|
|
return ok
|