Files
flywms/step1_core_observer_design.md
2026-06-03 15:28:27 +02:00

6.3 KiB

FlyWMS Step 1 - Core/Observer Split

Data: 2026-05-29

Scopo

Ridurre il tempo totale della demo fino a portarlo vicino alla durata reale del video, evitando che la parte visuale OpenCV rallenti il loop critico di acquisizione, inferenza e logica demo.

Lo Step 1 non cambia ancora la struttura single-process del core di calcolo, ma separa in modo netto:

  • core: acquisizione, YOLO, tracking, macchina a stati, logging prestazioni
  • observer: processo separato per preview e telemetria

L'obiettivo e' ottenere una demo visibile senza riportare nel loop principale il costo della vecchia UI OpenCV.

Motivazione tecnica

I benchmark gia' disponibili dicono:

  • video reale: 658.3 s
  • benchmark headless: 762.13 s
  • demo vecchia con UI integrata: molto piu' lenta

La UI OpenCV dentro al loop ha gia' dimostrato di pesare in modo determinante. La strada piu' pulita e' quindi:

  1. mantenere il core il piu' simile possibile al benchmark
  2. spostare la visualizzazione in un processo esterno
  3. accettare che l'observer non mostri tutti i frame

Perimetro di Step 1

Step 1 include:

  • canale di telemetria core -> observer
  • canale preview core -> observer
  • observer separato e opzionale
  • modalita' latest update wins

Step 1 non include ancora:

  • multiprocessing tra capture e inference
  • shared memory
  • zero-copy
  • nuovo frontend DearPyGUI
  • protocollo distribuito multi-host

Architettura proposta

Processo core

Responsabilita':

  • legge il video o la camera
  • rispetta i limiti preview_fps e yolo_fps
  • esegue YOLO
  • aggiorna tracking e macchina a stati
  • salva snapshot e gestisce WMS
  • scrive tempistiche.txt
  • pubblica telemetria e preview in modo non bloccante

Il core non deve mai aspettare l'observer.

Processo observer

Responsabilita':

  • ricevere dati dal core
  • mantenere l'ultimo stato disponibile
  • mostrare:
    • preview principale
    • eventuali preview secondarie
    • comandi/stato
    • fps/logica macchina a stati

L'observer puo' perdere aggiornamenti. Questo e' accettabile.

Trasporto dati

Per Step 1 si usa un trasporto semplice su localhost, in modo da ridurre il rischio di complessita' prematura.

Scelta:

  • socket TCP locale per preview e telemetria

Motivi:

  • semplice da debuggare
  • leggibile anche con strumenti esterni
  • facile da riusare in seguito
  • non richiede introdurre subito shared memory

Formato messaggi

Telemetria

Formato: JSON line-delimited o JSON framed su socket

Campi minimi previsti:

{
  "type": "telemetry",
  "frame_id": 123,
  "timestamp": 1710000000.123,
  "state": "scan_level",
  "command_lines": ["...", "..."],
  "motion_text": "MOTO: stabile ...",
  "snapshot_counter": 4,
  "det_count": 2,
  "label_count": 1,
  "track_count": 2,
  "active_track_count": 2,
  "run_yolo": true,
  "last_yolo_ms": 28.4,
  "loop_fps": 25.8,
  "yolo_fps": 12.6,
  "video_fps": 30.0,
  "preview_fps": 30.0,
  "yolo_target_fps": 15.0
}

Preview

Formato: messaggio con header JSON + payload JPEG.

Campi minimi header:

{
  "type": "preview",
  "stream": "navigate",
  "frame_id": 123,
  "timestamp": 1710000000.123,
  "width": 960,
  "height": 540,
  "encoding": "jpeg",
  "jpeg_size": 45231
}

Il payload binario segue subito dopo l'header.

Frequenze observer

Per non pesare sul core:

  • telemetria: fino a 5-10 Hz
  • preview principale: 3-5 fps
  • preview snapshot/etichetta: solo su evento o ultima disponibile

Step 1 non ha l'obiettivo di mostrare una preview fluida. Ha l'obiettivo di restare credibile a livello demo senza penalizzare il core.

Strategia "latest update wins"

Il core non accumula backlog per l'observer.

Regole:

  • se l'observer e' lento, gli aggiornamenti vecchi possono essere scartati
  • il core invia solo l'ultimo stato rilevante
  • nessuna coda lunga per la preview

Questo vale in particolare per:

  • preview navigate
  • testo comandi
  • metriche fps

Gestione overlay

Step 1 adotta una soluzione intermedia:

  • il core genera una preview gia' ridotta
  • il core puo' continuare a disegnare l'overlay minimo necessario sulla preview inviata
  • l'observer resta semplice e mostra il risultato

Questo non e' il modello finale ideale, ma riduce il lavoro di riscrittura nello Step 1.

Evoluzione futura possibile:

  • inviare frame piu' bbox/stato
  • disegnare overlay interamente nell'observer

Modalita' di fallback

Il sistema deve funzionare anche senza observer.

Regole:

  • se l'observer non e' avviato, il core continua a lavorare
  • se il socket non e' disponibile, il core logga e prosegue
  • se l'observer si scollega, il core non deve bloccarsi

Questo e' un requisito fondamentale dello Step 1.

Parametri di configurazione da introdurre

Nuovi parametri suggeriti nel file INI:

  • observer_enabled = true/false
  • observer_host = 127.0.0.1
  • observer_port = 8765
  • observer_preview_fps = 4.0
  • observer_preview_width = 960
  • observer_jpeg_quality = 75
  • observer_telemetry_fps = 8.0

File previsti

Nuovo file

  • flywms_navigation_observer.py

Responsabilita':

  • connettersi al core
  • ricevere messaggi
  • mantenere ultimo stato per stream
  • mostrare finestre OpenCV lato observer

Modifiche a file esistente

  • flywms_navigation.py
    • aggiunta configurazione observer
    • serializzazione telemetria
    • invio preview/telemetria non bloccante
    • disattivazione progressiva della vecchia UI integrata

Piano implementativo di Step 1

  1. aggiungere parametri observer a config e argparse
  2. creare un piccolo publisher non bloccante nel core
  3. creare flywms_navigation_observer.py
  4. pubblicare:
    • preview navigate
    • preview snapshot
    • preview etichetta
    • telemetria/comandi
  5. rendere opzionale la vecchia UI integrata
  6. testare:
    • core senza observer
    • core con observer
    • benchmark con observer attivo ma leggero

Criteri di successo

Step 1 e' considerato riuscito se:

  1. il core continua a funzionare senza finestre locali
  2. l'observer mostra una preview leggibile e lo stato della missione
  3. l'observer non blocca il core se rallenta o si chiude
  4. il tempo totale della demo si avvicina al benchmark headless, senza ricadere nella penalizzazione della vecchia UI

Limiti noti

  • Step 1 non risolve ancora il costo seriale di cap.read() e inferenza
  • Step 1 non introduce ancora il multiprocessing tra capture e inference
  • Step 1 non ottimizza ancora l'uso adattivo di YOLO

Questi temi restano demandati agli Step 2 e 3.