External observer with OpenCV UI baseline
This commit is contained in:
261
step1_core_observer_design.md
Normal file
261
step1_core_observer_design.md
Normal file
@@ -0,0 +1,261 @@
|
||||
# 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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
Reference in New Issue
Block a user