mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-23 01:21:13 +00:00
refactor(01-01): convert hot-path schemas/*.py to hot_types re-export shims
- schemas/eskf.py: keep ConfidenceTier + ESKFConfig; re-export IMUSample and ESKFState from hot_types (define ConfidenceTier BEFORE the hot_types imports to avoid circular import — eskf_state.py imports ConfidenceTier from this module). Legacy alias IMUMeasurement = IMUSample. - schemas/vo.py: re-export Features, Matches, RelativePose, Motion, VOEstimate from hot_types.vo_estimate. - schemas/satellite.py: re-export TileCoords, TileBounds, SatelliteAnchor. - schemas/metric.py: keep LiteSAMConfig; re-export AlignmentResult, ChunkAlignmentResult, Sim3Transform. - schemas/rotation.py: keep HeadingHistory + RotationConfig; re-export RotationResult. Auto-fixes (Rules 1 + 3) needed to keep the 216-test floor green: - core/rotation.py: refactor try_rotation_steps to use dataclasses.replace instead of attribute assignment on RotationResult (Rule 1 — frozen dataclass forbids mutation; Pydantic silently allowed it). PATTERNS.md §6.1 already flagged Pose mutation but missed this site. - hot_types/vo_estimate.py: add Optional `covariance: np.ndarray` field to RelativePose (Rule 3 — five test sites construct RelativePose with `covariance=np.eye(6)`; Pydantic v2 silently accepted the extra kwarg via default `extra="ignore"`. Declaring the field preserves the construction contract under the dataclass migration without editing tests). Verification: pytest tests/ -q --ignore=tests/e2e → 216 passed, 8 skipped (matches baseline). Accuracy bench (23 tests) passes.
This commit is contained in:
@@ -1,46 +1,17 @@
|
||||
"""Metric Refinement schemas (Component F09)."""
|
||||
"""Metric Refinement schemas (Component F09).
|
||||
|
||||
Phase 1 shim — hot-path types `AlignmentResult`, `ChunkAlignmentResult`,
|
||||
`Sim3Transform` live in `gps_denied.hot_types.alignment_result`.
|
||||
`LiteSAMConfig` (config) stays here as a Pydantic boundary type.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from pydantic import BaseModel
|
||||
|
||||
from gps_denied.schemas import GPSPoint
|
||||
|
||||
|
||||
class AlignmentResult(BaseModel):
|
||||
"""Result of aligning a UAV image to a single satellite tile."""
|
||||
model_config = {"arbitrary_types_allowed": True}
|
||||
|
||||
matched: bool
|
||||
homography: np.ndarray # (3, 3)
|
||||
gps_center: GPSPoint
|
||||
confidence: float
|
||||
inlier_count: int
|
||||
total_correspondences: int
|
||||
reprojection_error: float # Mean error in pixels
|
||||
|
||||
|
||||
class Sim3Transform(BaseModel):
|
||||
"""Sim(3) transformation: scale, rotation, translation."""
|
||||
model_config = {"arbitrary_types_allowed": True}
|
||||
|
||||
translation: np.ndarray # (3,)
|
||||
rotation: np.ndarray # (3, 3) rotation matrix
|
||||
scale: float
|
||||
|
||||
|
||||
class ChunkAlignmentResult(BaseModel):
|
||||
"""Result of aligning a chunk array of UAV images to a satellite tile."""
|
||||
model_config = {"arbitrary_types_allowed": True}
|
||||
|
||||
matched: bool
|
||||
chunk_id: str
|
||||
chunk_center_gps: GPSPoint
|
||||
rotation_angle: float
|
||||
confidence: float
|
||||
inlier_count: int
|
||||
transform: Sim3Transform
|
||||
reprojection_error: float
|
||||
from gps_denied.hot_types.alignment_result import ( # noqa: F401
|
||||
AlignmentResult,
|
||||
ChunkAlignmentResult,
|
||||
Sim3Transform,
|
||||
)
|
||||
|
||||
|
||||
class LiteSAMConfig(BaseModel):
|
||||
@@ -51,3 +22,11 @@ class LiteSAMConfig(BaseModel):
|
||||
max_reprojection_error: float = 2.0 # pixels
|
||||
multi_scale_levels: int = 3
|
||||
chunk_min_inliers: int = 30
|
||||
|
||||
|
||||
__all__ = [
|
||||
"AlignmentResult",
|
||||
"ChunkAlignmentResult",
|
||||
"LiteSAMConfig",
|
||||
"Sim3Transform",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user