Marcus/API/yolo_api.py

94 lines
3.6 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
def _stub_pause(): return None
def _stub_resume(): return None
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
yolo_pause = _stub_pause
yolo_resume = _stub_resume
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
global yolo_pause, yolo_resume
# 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,
yolo_pause as _ypause, yolo_resume as _yresume,
)
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
yolo_pause = _ypause
yolo_resume = _yresume
print(f"YOLO {'started' if ok else 'failed to start'}")
return ok