Files
alro65 deb04c9315 sprint-0: fundaciones VMS-Sailor
Sprint 0 completo del producto VMS-Sailor (Vessel Management System
integrado para buques 30-40m). Brief de referencia en
VMS_Sailor_v2_Parte_*.md (intacto).

Core (vmssailor.core, 95.17% coverage, 99 tests verde):
- ShipCoord: sistema naval x_pp/y_cl/z_bl frozen
- Vessel, Deck, Bulkhead
- Equipment, EquipmentModel, Sensor, EquipmentSpec
- Tag, AlarmConfig, TagBinding, Scaling
- CardInstance, Bus, Topology con validacion 21 puntos I/O AR-NMEA-IO-v1.0
- Alarm, PermissiveRule, Condition
- Project agregado raiz con validacion cross-entity
- Persistencia portable .vmsproj (SQLite) con roundtrip verificable

Biblioteca curada seed (vmssailor.library):
- systems_catalog.json completo (catalogo maestro Parte 1 sec 7)
- 2 vessels: Sunseeker 76, Ferretti 850
- 2 motores: MTU 12V 2000 M96, Volvo D13-900
- 1 genset: Northern Lights M65C13
- yacht_motor_planeo.yaml (reglas heuristicas)
- TODO marcado data_source=seed_estimate - requiere validacion datasheets

Tools:
- vms-validate-library: CLI valida biblioteca completa
- vms-generate-test-project: CLI demo + verificacion roundtrip persistencia

Design System + 8 mockups HTML estaticos:
- docs/design_system.md (paleta Deep Ocean, gradientes, typography, motion)
- docs/brand/ (logo + variantes SVG)
- docs/mockups/splash, studio_main, runtime_overview,
  runtime_mimic_fuel (P&ID animado), runtime_alarms, runtime_trim (panel
  estrella con horizonte artificial), mobile_overview, mobile_trim
- docs/mockups/index.html (galeria)

Firmware (Sprint 12+ implementacion):
- firmware/ar_nmea_io_v1/src/config/pinout.h con macros GPIO

Decisiones autonomas documentadas en docs/decisions_sprint0.md.

Stack: Python 3.11 + uv + Pydantic v2 + SQLite stdlib + hatchling +
pytest 9 + ruff + mypy. Sin PySide6, FastAPI, Flutter ni firmware
funcional (entran en sprints siguientes).

Criterio de aceptacion Sprint 0: cumplido.
- uv sync: OK
- pytest: 99/99 verde
- cov vmssailor.core: 95.17% (objetivo >=80%)
- ruff: clean
- vms-validate-library: OK
- vms-generate-test-project: INTEGRIDAD OK

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 07:26:06 -04:00

95 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Coordenadas navales — convención del proyecto
> Regla de oro #11: **coordenadas navales consistentes en TODO el código.**
## Sistema `ShipCoord`
```python
from vmssailor.core import ShipCoord
position = ShipCoord(x_pp=10.5, y_cl=-0.9, z_bl=1.4) # metros
```
### Ejes
- **`x_pp`**: distancia desde la **Perpendicular de Popa (Pp)**, positivo hacia **proa**.
- **`y_cl`**: distancia desde la **Línea de Crujía (CL)**, positivo a **estribor**, negativo a **babor**.
- **`z_bl`**: altura sobre la **Línea Base (BL)**, positivo hacia **arriba**.
### Unidad
**Metros (SI)** siempre. Sin excepciones internas. La conversión a pies/yardas se hace exclusivamente en renderers de UI cuando el usuario lo pida.
### Visualización mental
```
+y (estribor)
Pp │ Proa
(popa)─────────────────┼─────────────────────► +x
y (babor)
```
Y la altura:
```
+z (arriba, mástil)
───────────────┼────── línea de cubierta
═══════════════│══════ línea de flotación (aprox z_bl ≈ draft)
═══════════════│══════ Línea Base (BL = z_bl 0)
z (no se usa en práctica)
```
## Buques típicos del segmento 30-40 m
- Eslora total: **20-60 m** → x_pp en [0, 60]
- Manga máxima: **5-15 m** → y_cl en [-7.5, +7.5]
- Calado: 0.5-5 m → z_bl en [0.5, 5] para el casco bajo flotación
- Punto más alto (mástil): hasta z_bl +20 m
Validators de `ShipCoord` permiten márgenes (x ∈ [-5, 200], y ∈ [-30, +30], z ∈ [-10, +50]) para cubrir buques en desarrollo y errores tipográficos del integrador.
## Por qué este sistema y no otro
- **Estándar de la industria naval/arquitectura naval**. La Pp es el origen natural usado en arquitectura, despacho, regulación.
- **Independiente de UI / pantalla.** Los pixels y rotaciones de cámara viven en renderers, no en core.
- **Compatible con NMEA 2000.** El backbone publica posición geodésica (PGN 129025/129029) y actitud (PGN 127257). Para transformar a ShipCoord local del buque, se aplica el lay-out del buque (mounting offset y rotación de la IMU/GPS respecto al origen del buque) registrado en config del proyecto.
## Reglas para escribir código
**Sí:**
```python
location = ShipCoord(x_pp=5.5, y_cl=-0.9, z_bl=1.2)
distance = a.distance_to(b) # metros, 3D euclídea
```
**No:**
```python
# ¡No! No mezcles coordenadas de pantalla con coordenadas del buque.
location = (mouse_x, mouse_y)
# ¡No! Las transformaciones a pantalla viven en renderers, no en core.
class ShipCoord:
def to_screen_xy(self, ...): ... # ← esto NO va en core
```
## Conversión a pantalla (UI sprints)
En Sprint 1+ los renderers (QGraphicsView, Flutter Canvas) implementan **una sola** función `ship_to_screen(coord: ShipCoord, viewport) → QPointF` y todo lo demás trabaja en ShipCoord.
## Tests relevantes
- `tests/core/test_coords.py` — comportamiento de `ShipCoord`
- `tests/core/test_validation.py::test_equipment_out_of_hull_warning` — chequea que equipos no caigan fuera de la envolvente del buque