pipeline in linea single thread

This commit is contained in:
administrator
2026-05-19 08:52:44 +02:00
parent 98b43ce903
commit f728524ee6
43 changed files with 5245 additions and 154 deletions

View File

@@ -1,116 +1,255 @@
# FlyWMS handoff - GUI navigazione
# FlyWMS handoff
Data: 2026-05-15
Data: 2026-05-18
## Stato repository
- Branch: `master`
- Remote: `origin` su Gitea
- Ultimo lavoro: aggiunta shell DearPyGUI separata per la simulazione dimostrativa di `flywms_navigation.py`.
- Commit da creare per questa milestone: `pipeline in linea single thread`
- Tag git previsto per questa milestone: `pipeline-in-linea-single-thread`
## Contesto recuperato
## Stato funzionale attuale
L'obiettivo discusso era trasformare `flywms_navigation.py` in una simulazione piu' ordinata e dimostrativa, senza contaminare la logica esistente. Il programma originale contiene gia':
La base di lavoro e' ancora una pipeline sostanzialmente single-thread, con logica completa di navigazione/demo in Python.
- detector YOLO/Ultralytics;
- tracking geometrico leggero dei `gaylord`;
- decisione di snapshot quando una track e' centrata;
- salvataggio frame debug, payload OCR e `snapshots.jsonl`;
- simulazione comandi `STOP`, `SCATTA_FOTO`, `ASSOCIA_POSIZIONE`, `INVIA_ROI_REMOTA`, `ATTENDI_ACK`, `RIPARTI_*`;
- UI debug OpenCV integrata nel `main()`.
Componenti principali presenti:
## Decisione architetturale
- [flywms_navigation.py](C:/devel/flywms/flywms_navigation.py)
- detector Ultralytics YOLO
- tracking geometrico
- logica snapshot gaylord + etichetta
- macchina a stati demo per movimento verso etichetta, stabilizzazione, scatto, ritorno, attesa WMS
- client WMS asincrono
- log prestazioni dettagliato per frame
- profilo `benchmark`
- [flywms_wms_server.py](C:/devel/flywms/flywms_wms_server.py)
- server demo FastAPI
- ricezione payload e immagini
- OCR lato server
- salvataggio payload/immagini ricevute
- [flywms_paddleocr_worker.py](C:/devel/flywms/flywms_paddleocr_worker.py)
- worker persistente per PaddleOCR
- [flywms_navigation_gui.py](C:/devel/flywms/flywms_navigation_gui.py)
- shell DearPyGUI separata dalla logica principale
La GUI DearPyGUI e' stata tenuta in un file separato, `flywms_navigation_gui.py`.
## Stato GPU / librerie
Motivo: non toccare il ciclo originale e non rischiare regressioni nella logica di navigazione. La GUI importa `flywms_navigation.py` e riusa:
Verificato su questo PC:
- `UltralyticsDetector`;
- `LightweightTracker`;
- `NavigationController`;
- `draw_navigation_debug`;
- configurazione da `flywms_navigation.ini`.
- OpenCV con CUDA e GUI Win32 attivi
- cuDNN attivo
- YOLO/Ultralytics su GPU RTX 3050
- `yolo_half = true` supportato
In pratica `flywms_navigation.py` resta il simulatore CLI/OpenCV funzionante; `flywms_navigation_gui.py` e' una shell dimostrativa sopra la stessa logica.
PaddleOCR al momento resta nel worker dedicato e non e' il focus della prossima rifattorizzazione.
## Implementato
## Configurazione importante
File nuovo:
File: [flywms_navigation.ini](C:/devel/flywms/flywms_navigation.ini)
- `flywms_navigation_gui.py`
Valori chiave attuali:
Funzioni principali:
- `ultralytics_device = 0`
- `yolo_half = true`
- `preview_fps = 24.0`
- `yolo_fps = 15.0`
- `benchmark_mode = false`
- `benchmark_preview_fps = 30.0`
- `perf_log_path = tempistiche.txt`
- `NavigationDemoEngine`: esegue un singolo step del ciclo video/YOLO/tracking/navigazione e restituisce uno stato frame-by-frame.
- `NavigationDemoGui`: gestisce finestra DearPyGUI, comandi Avvia/Pausa, Step, Reset, preview, metriche, comandi, payload OCR e track.
- conversione frame OpenCV BGR in texture RGBA DearPyGUI.
- gestione texture corretta con tag univoci quando cambia la dimensione immagine.
- resize visuale della preview principale a 960x540.
Il video di lavoro locale usato durante i test recenti e' `testhd2_edit.mp4`.
Nota: i file video locali non sono necessariamente da committare.
DearPyGUI e' stato installato nell'ambiente Python corrente con:
## Log e benchmark
### Log demo con UI
File:
- [tempistiche.txt](C:/devel/flywms/tempistiche.txt)
Risultati principali gia' analizzati:
- video sorgente: circa `10.97 min` a `30 fps`
- run demo completo molto piu' lento a causa di:
- UI OpenCV pesante
- pause snapshot
- attese WMS
Numeri rilevanti del run demo:
- `demo_active_s = 1092.85 s`
- `demo_draw_ui_s = 597.18 s`
Conclusione:
- la UI OpenCV e il rendering accessorio pesano moltissimo
- la pipeline di calcolo non deve piu' essere accoppiata alla UI in questo modo
### Benchmark headless
File:
- [tempistiche-benchmark.txt](C:/devel/flywms/tempistiche-benchmark.txt)
Profilo usato:
```powershell
python -m pip install dearpygui
python flywms_navigation.py --benchmark-mode
```
## Verifiche eseguite
Caratteristiche del profilo benchmark:
Compilazione:
- nessuna finestra OpenCV
- `preview_target = 30 fps`
- log tempi separato
Risultati benchmark gia' analizzati:
- `benchmark_active_s = 762.13 s`
- durata video reale: `658.3 s`
- scarto residuo netto: circa `103.8 s` = `1.73 min`
- `active_fps = 25.97`
- `active_yolo_fps = 12.69`
Tempi medi in regime stabile:
- `mean_loop_ms = 36.90`
- `mean_read_ms = 6.10`
- `mean_yolo_ms = 31.20`
- `mean_track_ms = 0.18`
Conclusione benchmark:
- togliere la UI fa recuperare circa `5.5 min`
- la pipeline core e' vicina all'obiettivo ma non ancora allineata alla durata reale del video
- il residuo e' dovuto soprattutto a:
- inferenza YOLO sotto il target dei `15 fps`
- `cap.read()`
- struttura single-thread del loop
## Decisione architetturale emersa oggi
La prossima fase non deve essere "ottimizzare la GUI attuale", ma formalizzare una separazione netta dei ruoli.
### Ruoli da formalizzare
`Capture`
- acquisisce frame
- acquisisce posa drone nello stesso istante
- produce un pacchetto coerente `frame + pose + timestamp + frame_id`
`Vision / YOLO`
- riceve il frame gia' corredato di posa
- produce bbox, associazioni, offset, misure visive
- non decide il workflow
- non parla direttamente con WMS
`Navigation / Control`
- interpreta i risultati visivi
- decide comandi di scansione, centraggio, scatto, ritorno, ripresa
- e' il vero orchestratore della missione
`Drone I/O`
- invia i comandi al drone o al simulatore
- riceve stato / ack / posa aggiornata
- esegue lo scatto reale
`WMS Client`
- riceve payload finale pronto
- invia al WMS
- non decide il volo
## Punto concettuale gia' chiarito
Ogni frame che YOLO riceve deve avere gia' associata la posa del drone.
Quindi il thread di cattura non passa solo l'immagine, ma un record strutturato del tipo:
```text
CapturedFrame {
frame_id
timestamp
image
pose_x
pose_y
pose_z
yaw
pitch
roll
}
```
YOLO non deve rileggere la posizione "corrente" a posteriori.
La posa da usare per interpretare quel frame e' quella congelata al momento della cattura.
## Domande aperte per domani
1. Formalizzare le strutture dati tra thread:
- `CapturedFrame`
- `VisionResult`
- `DroneCommand`
- `CommandResult`
- `WmsPayload`
2. Disegnare la pipeline multi-thread minima:
- `capture_thread`
- `vision_thread`
- `navigation/control_thread`
- `wms_thread`
3. Decidere se il primo passo implementativo deve essere:
- solo `capture + vision` separati
- oppure `capture + vision + command pipeline`
4. Formalizzare bene il flusso "scatto etichetta":
- il controller decide
- il layer drone/scatto produce immagine e posa
- il payload finale va al WMS senza far diventare YOLO l'orchestratore del sistema
## Raccomandazione per il prossimo avvio
Domani, in una nuova chat, partire da qui:
1. leggere questo `handoff.md`
2. leggere gli ultimi aggiornamenti:
- [aggiornamento-2026-05-18-18-30.md](C:/devel/flywms/aggiornamento-2026-05-18-18-30.md)
- [aggiornamento-2026-05-18-19-14.md](C:/devel/flywms/aggiornamento-2026-05-18-19-14.md)
- [aggiornamento-2026-05-18-19-58.md](C:/devel/flywms/aggiornamento-2026-05-18-19-58.md)
3. cominciare scrivendo le specifiche formali di:
- responsabilita'
- messaggi tra thread
- ownership dei dati
- chi comanda chi
## Comandi utili
Server WMS:
```powershell
python -m py_compile flywms_navigation_gui.py flywms_navigation.py
python flywms_wms_server.py
```
Test motore GUI senza finestra persistente:
Demo navigazione con UI OpenCV:
```text
state1 1 (720, 1280, 3)
state2 2 (720, 1280, 3)
```powershell
python flywms_navigation.py --wms-enabled
```
Test aggiornamento UI/texture:
Benchmark headless:
```text
ui step ok
960 540
```powershell
python flywms_navigation.py --benchmark-mode
```
Avvio manuale usato:
GUI DearPyGUI:
```powershell
python flywms_navigation_gui.py
```
## Osservazioni performance
Con CPU, la GUI scende circa da 6 fps a 3.8 fps. Il dato e' credibile perche' la shell GUI aggiunge:
- disegno overlay OpenCV;
- conversione BGR -> RGBA;
- normalizzazione/copia texture `float32`;
- aggiornamento pannelli DearPyGUI nello stesso thread di YOLO.
Il carico CPU alto su tutti gli 8 core e' credibile: PyTorch/OpenCV/NumPy usano thread nativi anche se il loop Python e' singolo.
Quando sara' disponibile una GPU corretta, conviene rimisurare separando:
- fps YOLO/tracking;
- fps GUI;
- tempo medio YOLO;
- tempo medio conversione texture.
## Prossimi passi consigliati
1. Migliorare la GUI come demo:
- timeline eventi `STOP`, `SCATTA_FOTO`, `ACK/NACK`, `RIPARTI`;
- pannello soglie principali;
- evidenza piu' leggibile dello stato `entering/candidate/centered/snapshotted`;
- contatori snapshot e posizioni simulate.
2. Ottimizzare solo se serve:
- aggiornare texture a frequenza limitata;
- convertire per GUI un frame gia' ridotto;
- separare inferenza e GUI con stato latest-frame;
- aggiornare testo solo quando cambia.
3. Non modificare la logica di `flywms_navigation.py` finche' la GUI non ha stabilizzato i requisiti dimostrativi.