mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 05:36:36 +00:00
feat(gpr): explicitly mark GlobalPlaceRecognition as AnyLoc-VLAD-DINOv2 baseline
GlobalPlaceRecognition already implements AnyLoc-VLAD-DINOv2 (existing code). This change makes the sprint 1 GPR technology selection explicit: - Expand class docstring with selection rationale vs NetVLAD / SP+LG - Document INT8 quantization as known-broken for ViT on Jetson - Reference design doc §2.3 and stage2 backlog - Add two marker tests asserting 4096-d descriptor + DINOv2 engine name No behavioral change — existing Mock/TRT path unchanged. Ref: docs/superpowers/specs/2026-04-18-oss-stack-tech-audit-design.md §2.3 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,12 +62,21 @@ class IGlobalPlaceRecognition(ABC):
|
|||||||
|
|
||||||
|
|
||||||
class GlobalPlaceRecognition(IGlobalPlaceRecognition):
|
class GlobalPlaceRecognition(IGlobalPlaceRecognition):
|
||||||
"""AnyLoc (DINOv2) coarse localisation component.
|
"""AnyLoc-VLAD-DINOv2 coarse localisation component — sprint 1 GPR baseline.
|
||||||
|
|
||||||
GPR-01: load_index() tries to open a real Faiss .index file; falls back to
|
GPR-01: load_index() tries to open a real Faiss .index file; falls back to
|
||||||
a NumPy L2 mock when the file is missing or Faiss is not installed.
|
a NumPy L2 mock when the file is missing or Faiss is not installed.
|
||||||
GPR-02: Descriptor computed via DINOv2 engine (TRT on Jetson, Mock on dev/CI).
|
GPR-02: Descriptor computed via DINOv2 engine (TRT FP16 on Jetson, Mock on
|
||||||
|
dev/CI). INT8 quantization is disabled — broken for ViT on Jetson
|
||||||
|
(NVIDIA/TRT#4348, facebookresearch/dinov2#489).
|
||||||
GPR-03: Candidates ranked by descriptor similarity (L2 → converted to [0,1]).
|
GPR-03: Candidates ranked by descriptor similarity (L2 → converted to [0,1]).
|
||||||
|
|
||||||
|
Selected over NetVLAD (deprecated, −2.4% R@1 on MSLS 2024) and SuperPoint+
|
||||||
|
LightGlue (unvalidated for cross-view UAV↔satellite gap at sprint 1).
|
||||||
|
Stage 2 evaluation: SP+LG+FAISS per _docs/03_backlog/stage2_ideas/.
|
||||||
|
Long-term target: EigenPlaces (ICCV 2023) — cleaner ONNX export.
|
||||||
|
|
||||||
|
Ref: docs/superpowers/specs/2026-04-18-oss-stack-tech-audit-design.md §2.3
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_DIM = 4096 # DINOv2 VLAD descriptor dimension
|
_DIM = 4096 # DINOv2 VLAD descriptor dimension
|
||||||
|
|||||||
@@ -110,3 +110,36 @@ def test_descriptor_is_l2_normalised(gpr):
|
|||||||
img = np.random.randint(0, 255, (200, 200, 3), dtype=np.uint8)
|
img = np.random.randint(0, 255, (200, 200, 3), dtype=np.uint8)
|
||||||
desc = gpr.compute_location_descriptor(img)
|
desc = gpr.compute_location_descriptor(img)
|
||||||
assert np.isclose(np.linalg.norm(desc), 1.0, atol=1e-5)
|
assert np.isclose(np.linalg.norm(desc), 1.0, atol=1e-5)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# AnyLoc baseline markers — document sprint 1 GPR technology selection.
|
||||||
|
# GlobalPlaceRecognition IS the AnyLoc-VLAD-DINOv2 baseline (see class docstring).
|
||||||
|
# Ref: docs/superpowers/specs/2026-04-18-oss-stack-tech-audit-design.md §2.3
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_anyloc_baseline_descriptor_dim_is_4096(gpr):
|
||||||
|
"""AnyLoc-VLAD-DINOv2 baseline produces 4096-d descriptors (ViT-base + VLAD)."""
|
||||||
|
img = np.random.randint(0, 255, (224, 224, 3), dtype=np.uint8)
|
||||||
|
desc = gpr.compute_location_descriptor(img)
|
||||||
|
assert desc.shape == (4096,), (
|
||||||
|
f"AnyLoc-VLAD-DINOv2 expects 4096-d descriptor, got {desc.shape}. "
|
||||||
|
"If you changed this, update the baseline reference in "
|
||||||
|
"docs/superpowers/specs/2026-04-18-oss-stack-tech-audit-design.md §2.3"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_anyloc_baseline_uses_dinov2_engine():
|
||||||
|
"""Sprint 1 GPR baseline must call DINOv2 via ModelManager."""
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from gps_denied.core.gpr import GlobalPlaceRecognition
|
||||||
|
|
||||||
|
mm = MagicMock()
|
||||||
|
mm.get_inference_engine.return_value.infer.return_value = np.ones(4096, dtype=np.float32)
|
||||||
|
gpr_local = GlobalPlaceRecognition(mm)
|
||||||
|
gpr_local.compute_location_descriptor(np.zeros((224, 224, 3), dtype=np.uint8))
|
||||||
|
|
||||||
|
# AnyLoc == DINOv2 + VLAD. Engine name must be "DINOv2".
|
||||||
|
mm.get_inference_engine.assert_called_with("DINOv2")
|
||||||
|
|||||||
Reference in New Issue
Block a user