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 prestazioniobserver: 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:
- mantenere il core il piu' simile possibile al benchmark
- spostare la visualizzazione in un processo esterno
- 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_fpseyolo_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/falseobserver_host = 127.0.0.1observer_port = 8765observer_preview_fps = 4.0observer_preview_width = 960observer_jpeg_quality = 75observer_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
- aggiungere parametri observer a config e argparse
- creare un piccolo publisher non bloccante nel core
- creare
flywms_navigation_observer.py - pubblicare:
- preview
navigate - preview
snapshot - preview
etichetta - telemetria/comandi
- preview
- rendere opzionale la vecchia UI integrata
- testare:
- core senza observer
- core con observer
- benchmark con observer attivo ma leggero
Criteri di successo
Step 1 e' considerato riuscito se:
- il core continua a funzionare senza finestre locali
- l'observer mostra una preview leggibile e lo stato della missione
- l'observer non blocca il core se rallenta o si chiude
- 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.