Files
AR-Autopilot/OVERNIGHT_SUMMARY.md
T
alro65 0be60c5161 docs: OVERNIGHT_SUMMARY.md -- overnight session recap
Summary of the autonomous overnight session covering Sprints 0-3 + 2.5
plus polish + dev scripts. Includes:

- Per-sprint commit/tag table
- "What you can do right now" checklist (verify, launch Studio, run
  cascade simulation, flash hardware)
- Demo PINs for the 4 RBAC roles
- Architectural decisions taken without asking (rationale + how to
  reverse if needed)
- Environment limitations (no host C++ compiler, no ESP32 hardware
  available during the session)
- Repository structure overview
- Test count per suite (258 total)
- Next sprints (4-10+) with rough effort estimates
- Open questions for the next session (Flutter SDK, WiX, EKF timing,
  knob hardware model)
2026-05-18 18:22:28 -04:00

14 KiB
Raw Blame History

Resumen del trabajo nocturno — AR-Autopilot

Generado al final de la sesión autónoma del 2026-05-18. Tu repo está en D:\Proyectos Software\AR-Autopilot\ con todos los sprints commited y taggeados en main. Working tree limpio.


TL;DR

5 sprints completos + 1 polish en una sesión:

Hito Commit Tag Test count
Sprint 0 — Foundations 700756c 80
Polish (ruff + mypy strict) 8d4a698 80
Scripts dev (PS + Bash) 0ec4ba3 80
Sprint 1 plan + research 1d7dd63 80
Sprint 1 — Firmware ESP32 base 6586094 sprint-1 80
Sprint 2 — PID inner + simulador 295efa2 sprint-2 129
Sprint 2.5 — RBAC + Studio + Flash Console 13a2867 sprint-2.5 231
Sprint 3 — PID outer + Heading Hold 42ee63b sprint-3 258
  • 258 tests Python verde en 5.3 s
  • Firmware ESP32 compila clean: RAM 6.8 %, Flash 27.1 % (355 KB)
  • Studio bootable con PySide6 + login PIN + Flash Console embebido
  • RBAC 4 roles funcional con dual-auth para Engineer flasheando

Qué puedes hacer YA cuando despiertes

1. Verificar todo desde cero

cd "D:\Proyectos Software\AR-Autopilot"
.\.venv\Scripts\Activate.ps1

# Ver el trabajo:
git log --oneline -10
git tag --list "sprint-*"

# Tests Python:
pytest

# Demo Sprint 0:
python examples\sprint0_demo.py

# Compilar firmware:
pio run -e esp32-dev -d firmware\ar_autopilot_v1

2. Lanzar el Studio con la Flash Console

# Poblar usuarios demo la primera vez:
python -m arautopilot.studio.app --seed-demo

# Abrir la GUI:
python studio_main.py

Login con cualquiera de estos PINs (cambia inmediatamente en producción):

User Rol PIN
Alvaro Super Admin 1111
Eng Demo Engineer 2222
Captain Owner 3333
Crew User 4444

Después del login verás la ventana principal con tabs:

  • Overview — bienvenida
  • Flash Console — la "mini Arduino IDE": selecciona puerto, variante, Compile / Compile + Flash. Si entras como Engineer, te pide el PIN del Super Admin antes de flashear (dual-auth).
  • Project — placeholder Sprint 4
  • Telemetry — placeholder Sprint 4

La barra de estado muestra el path del audit log (~/.ar-autopilot/studio/audit.jsonl).

3. Probar el cascade PID en simulación pura

pytest arautopilot\tests\test_pid_outer_python.py -v -k cascade

Esto corre el lazo completo outer + inner + dinámica del timón + dinámica de yaw del barco. Tres escenarios:

  • Step de 30° en rumbo
  • Step negativo (-30°)
  • Cruce de 360° (350° → 10°)

Todos convergen a <2° de error en 60 s con las ganancias seed del 30 m yacht.

4. Cuando enchufes la AR-NMEA-IO

# Flashear desde la línea de comandos (alternativa a la Flash Console):
pio run -e esp32-dev -d firmware\ar_autopilot_v1 -t upload --upload-port COM7

# Monitor serie:
pio device monitor -d firmware\ar_autopilot_v1 --port COM7

# Cliente Modbus para probar el slave:
pip install "pymodbus>=3.6,<4"
python firmware\ar_autopilot_v1\tools\modbus_client_test.py --port COM7

El firmware boota en STANDBY. Para activar HEADING_HOLD:

  1. Tiene que recibir PGN 127250 (heading) del bus NMEA 2000 (o un AR-ECDIS / simulador).
  2. El median filter del timón tiene que haber llenado (50 muestras × 10 ms = 0.5 s desde boot).
  3. Escribir 1 al holding register HOLDING_MODE_REQUEST (40001).

Si falta cualquiera de las dos validaciones, el log dice exactamente por qué rechazó el cambio de modo.


Decisiones técnicas que tomé sin preguntar

Bajo tu autorización "tienes todos los permisos, tu puedes acabar el proyecto" tomé estas decisiones. Todas reversibles si no te gustan:

Sprint 1

  1. Framework Arduino-on-ESP32 solo (NO el dual Arduino-as-ESP-IDF-component que proponía el plan original). Rationale: Arduino on ESP32 ya da FreeRTOS completo (xTaskCreatePinnedToCore, prioridades, TWDT, ESP_LOG); el dual framework es notoriamente frágil en PlatformIO. Si Sprint 8 necesita features ESP-IDF-only (OTA con rollback, secure boot), migramos. Documentado en CHANGELOG.md y docs/firmware.md.

  2. CAN pins por defecto: TX=GPIO3, RX=GPIO1 (placeholders en pinout.h). Verificar contra el schematic real de la AR-NMEA-IO cuando lo tengas a mano.

  3. Modbus framing 38400 8N1, slave ID 1. Estándar marino.

Sprint 2

  1. Simulador "marino-realista" (actuator_gain=0.2 produce v_max ~5 dps a 100 % PWM, coherente con brief "típico 3-6 dps" para yate 30 m). Versión inicial era "cohete" (actuator_gain=60), la reescalé.

  2. PID en Python = source of truth, C++ es port línea-por-línea. Esto facilita iteración (cambios en Python primero, luego port). Cross-validation Python↔C++ via ctypes está pendiente (necesita compilador host).

Sprint 2.5

  1. PBKDF2-HMAC-SHA256 con 200k iteraciones para hashear PINs (stdlib, sin dependencia nueva).

  2. PIN solo numérico 4-8 dígitos. Argumento: en consola del barco con guantes mojados, contraseña alfanumérica es cruel.

  3. Audit log JSONL append-only sin firma criptográfica todavía. La firma con hash-chain llega en Sprint 8 con HWID activation.

  4. PySide6 como optional-dependencies grupo "studio" — el core se puede instalar sin GUI para CI / headless test bench. Instalar con pip install -e ".[studio]".

Sprint 3

  1. SOG hardcoded a 15 kn mientras no llegue PGN 129026 (Sprint 5). Modbus permite override manual (HOLDING_PID_OUTER_SPEED_KN_REQ_X10).

  2. Captura del rumbo actual al engage HEADING_HOLD. Si el operador hizo engage sin escribir setpoint primero, el piloto NO se lanza hacia un valor stale; mantiene el rumbo que llevaba.

  3. Gain schedule 3 puntos seed (5/15/28 nudos) hardcoded en el firmware. Escribir kp/ki/kd vía Modbus desactiva el schedule (override del integrator). Sprint 4 llevará schedules customizables vía .appack.


Lo que NO pude hacer (limitaciones del entorno)

Cosa Por qué Cuándo se hace
Flashear ESP32 físico No tengo tu AR-NMEA-IO conectada Tú mañana con pio run -t upload --upload-port COMx o el Flash Console del Studio
Verificar timing real PID en hardware Mismo motivo Cuando flashees y conectes un timón simulado o real
Tests Unity en host (median filter, PID inner/outer) No hay g++/clang/mingw en este Windows Instalas MinGW-w64 o MSVC Build Tools y pio test -e native corre los 8+ tests
Cross-validation Python↔C++ vía ctypes Mismo motivo (necesita host compiler) Mismo paso de arriba
NMEA 2000 contra bus real No hay adaptador USB-CAN aquí Conectas tu AR-ECDIS al backbone o un adaptador USB-CAN
Verificar GUI Studio visualmente El entorno no tiene display server interactivo Tú al lanzar python studio_main.py

Estado del repositorio

Estructura final

AR-Autopilot/
├── arautopilot/                       # Python package
│   ├── core/                          # Data model + RBAC + audit
│   │   ├── actuator_config.py
│   │   ├── alarms.py
│   │   ├── audit.py                   # NEW Sprint 2.5
│   │   ├── ids.py
│   │   ├── knob_state.py
│   │   ├── modes.py
│   │   ├── pid_config.py
│   │   ├── project_config.py
│   │   ├── rbac.py                    # NEW Sprint 2.5
│   │   ├── user.py                    # NEW Sprint 2.5
│   │   ├── user_store.py              # NEW Sprint 2.5
│   │   └── vessel_config.py
│   ├── library/                       # Seed actuator + tunings
│   ├── shared/
│   │   └── modbus_register_map.py     # GENERATED from YAML
│   ├── studio/                        # PySide6 GUI
│   │   ├── app.py                     # Entry point (Sprint 2.5)
│   │   ├── flash_console.py           # "mini Arduino IDE" (Sprint 2.5)
│   │   ├── login_window.py            # (Sprint 2.5)
│   │   ├── main_window.py             # (Sprint 2.5)
│   │   ├── session.py                 # Auth + audit context
│   │   └── simulator/                 # Bench simulators (Sprint 2+3)
│   │       ├── pid_inner.py           # Python PID inner (source of truth)
│   │       ├── pid_outer.py           # Python PID outer + gain scheduling
│   │       ├── rudder_dynamics.py     # Physical rudder model
│   │       └── vessel_heading.py      # Yaw dynamics model
│   └── tests/                         # 258 pytest tests
│
├── firmware/ar_autopilot_v1/          # ESP32 firmware (PlatformIO)
│   ├── platformio.ini
│   ├── modbus_registers.yaml          # SINGLE SOURCE OF TRUTH for the map
│   ├── src/
│   │   ├── main.cpp
│   │   ├── filters/median.h           # (Sprint 1)
│   │   ├── hal/                       # (Sprint 1)
│   │   │   ├── di_do.{h,cpp}
│   │   │   ├── pinout.h
│   │   │   ├── rudder_actuator.{h,cpp}
│   │   │   └── rudder_sensor.{h,cpp}
│   │   ├── modes/standby.{h,cpp}      # STANDBY + HEADING_HOLD (Sprint 3)
│   │   ├── pid/
│   │   │   ├── pid_inner.h            # Header-only (Sprint 2)
│   │   │   ├── pid_inner_task.{h,cpp}
│   │   │   ├── pid_outer.h            # Header-only (Sprint 3)
│   │   │   └── pid_outer_task.{h,cpp}
│   │   ├── protocols/
│   │   │   ├── modbus_registers.h     # GENERATED
│   │   │   ├── modbus_slave.{h,cpp}
│   │   │   └── nmea2000_consumer.{h,cpp}
│   │   ├── safety/                    # (Sprint 1)
│   │   │   ├── safety_monitor.{h,cpp}
│   │   │   └── watchdog.{h,cpp}
│   │   └── system/                    # (Sprint 1)
│   │       ├── ar_log.h
│   │       ├── heartbeat.cpp
│   │       └── task_config.h
│   ├── test/test_median_filter/       # Unity tests host-side
│   └── tools/modbus_client_test.py    # Manual Modbus client
│
├── tools/
│   └── gen_modbus_registers.py        # YAML -> C++ + Python generator
│
├── scripts/                           # dev convenience (PS + Bash)
│
├── examples/sprint0_demo.py
│
└── docs/
    ├── AR_Autopilot_brief.md
    ├── architecture.md
    ├── firmware.md
    ├── firmware-libraries-research.md
    ├── sprint-1-plan.md
    ├── sprint-2-plan.md
    ├── sprint-2.5-plan.md
    ├── sprint-3-plan.md
    └── OVERNIGHT_SUMMARY.md           # ← este archivo

Tests por suite

test_actuator_config.py                   9   ✅
test_alarms.py                           14   ✅
test_audit.py                             9   ✅  (Sprint 2.5)
test_knob_state.py                       11   ✅
test_library_loader.py                    6   ✅
test_modbus_register_map.py              30   ✅
test_modes.py                            10   ✅
test_pid_config.py                       13   ✅
test_pid_inner_python.py                 10   ✅  (Sprint 2)
test_pid_outer_python.py                 12   ✅  (Sprint 3)
test_project_config.py                    9   ✅
test_rbac.py                             32   ✅  (Sprint 2.5)
test_roundtrip.py                         3   ✅
test_rudder_simulator.py                  9   ✅  (Sprint 2)
test_session.py                           9   ✅  (Sprint 2.5)
test_studio_smoke.py                      5   ✅  (Sprint 2.5)
test_user.py                             11   ✅  (Sprint 2.5)
test_user_store.py                       10   ✅  (Sprint 2.5)
test_vessel_config.py                     5   ✅
test_vessel_heading_simulator.py         15   ✅  (Sprint 3)
                                       ====
                                        258

Próximos sprints (si quieres seguir)

Sprint Foco Tiempo estimado
4 Studio completo (project config + .appack + MSI) + Display Flutter básico ~2-3 días autónomos
5 True Course + Track Keeping + Dodge + PGN 129025/9/6 ~2 días
6 Alarmas completas + publicar PGN 127245/127237 + lectura VMS ~1.5 días
7 Knob físico + comisionado wizard + auto-tuning Ziegler-Nichols ~2 días
8 EKF + adaptive tuning + HWID + VPN + telemetría + firma audit log ~3-4 días
9 Hardening + tests integrados + manual operador ~2 días
10+ Fase 2 (modos viento para veleros) abierto

Preguntas tuyas para cuando despiertes

Si me dejas otra ventana autónoma, estas son las decisiones que me ayudarían a no atascarme:

  1. Sprint 4 Display Flutter — ¿lo arranco en display/ con flutter create? (Necesitaría que instales Flutter SDK antes, no es algo que pueda hacer yo). Alternativa: lo dejo solo en mock-up HTML/CSS hasta que tengas Flutter SDK.

  2. Sprint 4 MSI installer — ¿WiX Toolset disponible en este Windows? Si no, lo dejo escrito y se compila cuando lo instales.

  3. Sprint 5 True Course — el cálculo de set/leeway puede usar filtros clásicos (Sprint 5 simple) o ya enchufar el EKF (Sprint 8). El brief dice Sprint 5 con filtros clásicos primero. Confirmo eso a menos que digas otra cosa.

  4. Sprint 7 Knob hardware — ¿qué modelo concreto eliges? Brief dice "Grayhill / Bourns serie panel o encoder + knob aluminio aparte". Necesito el modelo para el datasheet (resolución, debounce, push button electrical char).


Si encuentras un problema

Cualquier sprint se puede reverter con:

git reset --hard sprint-2     # vuelves a Sprint 2 state
# o sprint-1, sprint-0-approved, etc.

Todos los cambios están firmados con Co-Authored-By: Claude Opus 4.7 para que sepas qué tocó la IA.

Audit log de mis acciones dentro del Studio: ~/.ar-autopilot/studio/audit.jsonl.

Que duermas bien — al despertar te queda un producto funcional + base sólida para los próximos 6 sprints. 🌅