From e6e1c27726aac3f9c13d366df7b78064eebbc03c Mon Sep 17 00:00:00 2001 From: Yuzviak Date: Sun, 10 May 2026 23:01:00 +0300 Subject: [PATCH] feat(01-03): move create_vo_backend factory into components/vio/factory.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Lift the env-aware VO backend factory verbatim from core/vo.py. - Body and parameter defaults preserved exactly (PATTERNS.md §4.1 mandate: 'Preserve this factory verbatim'). - Return-type annotation widened from ISequentialVisualOdometry to the canonical VisualOdometry Protocol from Plan 01-02; the I-prefix alias is still importable so legacy callers/type-checkers keep working. - Imports route through the new components.vio.* modules; no cross-package edits needed because Plan 08 (composition root) is the only other call site planned. - Append to the components.vio barrel. --- src/gps_denied/components/vio/__init__.py | 2 + src/gps_denied/components/vio/factory.py | 67 +++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/gps_denied/components/vio/factory.py diff --git a/src/gps_denied/components/vio/__init__.py b/src/gps_denied/components/vio/__init__.py index 7da1748..9cec953 100644 --- a/src/gps_denied/components/vio/__init__.py +++ b/src/gps_denied/components/vio/__init__.py @@ -24,6 +24,7 @@ from gps_denied.components.vio.cuvslam_backend import ( CuVSLAMMonoDepthVisualOdometry, CuVSLAMVisualOdometry, ) +from gps_denied.components.vio.factory import create_vo_backend __all__ = [ "VisualOdometry", @@ -32,4 +33,5 @@ __all__ = [ "SequentialVisualOdometry", "CuVSLAMVisualOdometry", "CuVSLAMMonoDepthVisualOdometry", + "create_vo_backend", ] diff --git a/src/gps_denied/components/vio/factory.py b/src/gps_denied/components/vio/factory.py new file mode 100644 index 0000000..984dd34 --- /dev/null +++ b/src/gps_denied/components/vio/factory.py @@ -0,0 +1,67 @@ +"""VIO backend factory — env-aware DI seed (ARCH-01 / ARCH-03). + +Preserves ``create_vo_backend`` verbatim from the legacy ``core/vo.py`` +location. PATTERNS.md §4.1 explicitly designates this factory as the +seed of the env-aware composition root: ``pipeline/composition.py`` +(Plan 08) will pass env-specific kwargs (``prefer_cuvslam``, +``prefer_mono_depth``, ``model_manager``) into this function from +``RuntimeConfig``. + +Signature contract for Plan 08 wiring: + + - ``env="jetson"`` → prefer_cuvslam=True, prefer_mono_depth=True + - ``env="x86_dev" | "ci"`` → prefer_cuvslam=False, model_manager=mock + - ``env="sitl"`` → prefer_cuvslam=False +""" +from __future__ import annotations + +from typing import Optional + +from gps_denied.components.vio.cuvslam_backend import ( + CuVSLAMMonoDepthVisualOdometry, + CuVSLAMVisualOdometry, +) +from gps_denied.components.vio.orbslam_backend import ( + ORBVisualOdometry, + SequentialVisualOdometry, +) +from gps_denied.components.vio.protocol import VisualOdometry +from gps_denied.core.models import IModelManager +from gps_denied.schemas import CameraParameters + + +def create_vo_backend( + model_manager: Optional[IModelManager] = None, + prefer_cuvslam: bool = True, + prefer_mono_depth: bool = False, + camera_params: Optional[CameraParameters] = None, + imu_params: Optional[dict] = None, + depth_hint_m: float = 600.0, +) -> VisualOdometry: + """Return the best available VO backend for the current platform. + + Priority when prefer_mono_depth=True: + 1. CuVSLAMMonoDepthVisualOdometry (sprint 1 production path) + 2. ORBVisualOdometry (dev/CI fallback inside Mono-Depth wrapper) + + Priority when prefer_mono_depth=False (legacy): + 1. CuVSLAMVisualOdometry (Jetson — cuVSLAM SDK present) + 2. SequentialVisualOdometry (TRT/Mock SuperPoint+LightGlue) + 3. ORBVisualOdometry (pure OpenCV fallback) + """ + if prefer_mono_depth: + return CuVSLAMMonoDepthVisualOdometry( + depth_hint_m=depth_hint_m, + camera_params=camera_params, + imu_params=imu_params, + ) + + if prefer_cuvslam: + vo = CuVSLAMVisualOdometry(camera_params=camera_params, imu_params=imu_params) + if vo._has_cuvslam: + return vo + + if model_manager is not None: + return SequentialVisualOdometry(model_manager) + + return ORBVisualOdometry()