pipeline in linea single thread
This commit is contained in:
293
handoff.md
293
handoff.md
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user