mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 23:31:13 +00:00
275c7b4642
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
102 lines
4.0 KiB
Markdown
102 lines
4.0 KiB
Markdown
---
|
|
phase: "01"
|
|
plan: "06"
|
|
subsystem: mavlink_io
|
|
tags: [refactor, hexagonal, mavlink, shim]
|
|
dependency_graph:
|
|
requires: [01-05]
|
|
provides: [components/mavlink_io]
|
|
affects: [core/mavlink.py]
|
|
tech_stack:
|
|
added: []
|
|
patterns: [shim-re-export, circular-import-avoidance-via-local-imports]
|
|
key_files:
|
|
created:
|
|
- src/gps_denied/components/mavlink_io/pymavlink_bridge.py
|
|
- src/gps_denied/components/mavlink_io/mock_mavlink.py
|
|
modified:
|
|
- src/gps_denied/components/mavlink_io/__init__.py
|
|
- src/gps_denied/core/mavlink.py
|
|
decisions:
|
|
- "Used local (deferred) imports of MockMAVConnection inside MAVLinkBridge methods to avoid circular import between pymavlink_bridge and mock_mavlink"
|
|
- "Shim re-exports all seven names including three private helpers (_confidence_to_fix_type, _eskf_to_gps_input, _unix_to_gps_time) per CRITICAL warning"
|
|
metrics:
|
|
duration: "~5 minutes"
|
|
completed: "2026-05-11"
|
|
tasks: 5
|
|
files: 4
|
|
---
|
|
|
|
# Phase 01 Plan 06: MAVLink I/O Split Summary
|
|
|
|
Split `core/mavlink.py` (483 LOC) into component modules under `components/mavlink_io/`, replacing the original with a shim that re-exports all public and private names verbatim.
|
|
|
|
## LOC Distribution
|
|
|
|
| File | LOC | Contents |
|
|
|------|-----|----------|
|
|
| `components/mavlink_io/pymavlink_bridge.py` | 455 | MAVLinkBridge class + 3 module-level helpers + pymavlink conditional import |
|
|
| `components/mavlink_io/mock_mavlink.py` | 30 | MockMAVConnection (no-op for dev/CI) |
|
|
| `core/mavlink.py` (shim) | 29 | Re-export shim only |
|
|
| `components/mavlink_io/__init__.py` | 20 | Package surface |
|
|
|
|
Original: 483 LOC → split across 4 files (514 total including shim and `__init__.py`).
|
|
|
|
## Test Counts
|
|
|
|
| Test file | Result |
|
|
|-----------|--------|
|
|
| `tests/test_mavlink.py` | 32 passed |
|
|
| `tests/test_gps_input_encoding.py` | included in the 32 above |
|
|
| Full regression (`tests/`) | 216 passed, 8 skipped |
|
|
|
|
Regression floor: 216 passed (baseline). Status: MAINTAINED.
|
|
|
|
## Private Helper Verification
|
|
|
|
The three underscore names required by `test_mavlink.py` and `test_gps_input_encoding.py` resolve correctly via the shim:
|
|
|
|
```
|
|
python -c "from gps_denied.core.mavlink import _confidence_to_fix_type, _eskf_to_gps_input, _unix_to_gps_time; print('private helpers ok')"
|
|
# Output: private helpers ok
|
|
```
|
|
|
|
All three are exported from `core/mavlink.py` → `components/mavlink_io/pymavlink_bridge.py` → callable.
|
|
|
|
## `_PYMAVLINK_AVAILABLE` on Dev Machine
|
|
|
|
```
|
|
_PYMAVLINK_AVAILABLE = True
|
|
```
|
|
|
|
pymavlink is installed on this development machine, so `MAVLinkBridge._open_connection()` will attempt a real connection before falling back to `MockMAVConnection`.
|
|
|
|
## Deviations from Plan
|
|
|
|
### Auto-fixed Issues
|
|
|
|
**1. [Rule 3 - Blocking] Circular import between pymavlink_bridge and mock_mavlink**
|
|
|
|
- **Found during:** Task 1 (design review before writing)
|
|
- **Issue:** `pymavlink_bridge.py` (MAVLinkBridge) uses `isinstance(self._conn, MockMAVConnection)` checks. If `mock_mavlink.py` were imported at module level in `pymavlink_bridge.py`, and `__init__.py` imports both, a circular import chain would form.
|
|
- **Fix:** Used local (deferred) imports of `MockMAVConnection` inside each method that references it (`_send_gps_input`, `_recv_imu`, `_send_reloc_request`, `_send_telemetry`, `_open_connection`). This matches the pattern used in similar hexagonal refactors in this codebase.
|
|
- **Files modified:** `pymavlink_bridge.py`
|
|
- **Commit:** f965ac7
|
|
|
|
## Known Stubs
|
|
|
|
None. All data paths are wired: bridge reads from live ESKFState, writes to real or mock MAVLink connection.
|
|
|
|
## Threat Flags
|
|
|
|
None. No new network endpoints or auth paths introduced. The MAVLink UART connection was already present in the original `core/mavlink.py`.
|
|
|
|
## Self-Check: PASSED
|
|
|
|
- `src/gps_denied/components/mavlink_io/pymavlink_bridge.py` — FOUND
|
|
- `src/gps_denied/components/mavlink_io/mock_mavlink.py` — FOUND
|
|
- `src/gps_denied/components/mavlink_io/__init__.py` — FOUND (updated)
|
|
- `src/gps_denied/core/mavlink.py` — FOUND (shim, 29 LOC)
|
|
- Commit f965ac7 — FOUND
|
|
- 216 tests passed — CONFIRMED
|