105 lines
2.8 KiB
Markdown
105 lines
2.8 KiB
Markdown
# Step 2 - Disaccoppiamento Capture / Inference
|
|
|
|
## Obiettivo
|
|
|
|
Ridurre la serializzazione del loop principale separando:
|
|
|
|
- acquisizione video e campionamento metadati;
|
|
- inferenza, tracking e logica demo.
|
|
|
|
Lo scopo non e' introdurre ancora una pipeline completa multi-processo stile ROS, ma togliere dal percorso critico almeno la parte `cap.read()` e la preparazione del pacchetto frame.
|
|
|
|
## Vincolo architetturale
|
|
|
|
Il frame consumato dall'inferenza non puo' essere un'immagine grezza isolata.
|
|
|
|
Ogni frame deve essere rappresentato da un pacchetto logico di acquisizione che congela nello stesso istante:
|
|
|
|
- `frame_id`
|
|
- `timestamp`
|
|
- `video_time_sec`
|
|
- immagine
|
|
- posa / stato del drone campionati nel momento di acquisizione
|
|
|
|
Questo segue il modello gia' fissato nei documenti di architettura:
|
|
|
|
- `capture` non inventa la posa;
|
|
- `capture` la campiona dalla sorgente di stato disponibile;
|
|
- `inference` consuma un `CapturedFrame` gia' coerente.
|
|
|
|
Nel contesto della demo video attuale non esiste ancora una posa SLAM reale. Quindi il campo posa verra' popolato con una posa simulata minima, ma congelata all'acquisizione, utile a:
|
|
|
|
- mantenere il contratto architetturale corretto;
|
|
- evitare che in futuro frame e stato si disallineino;
|
|
- propagare i metadati fino agli snapshot.
|
|
|
|
## Struttura dati proposta
|
|
|
|
```text
|
|
CapturedFrame
|
|
- frame_id
|
|
- timestamp
|
|
- video_time_sec
|
|
- frame
|
|
- pose
|
|
```
|
|
|
|
Dove `pose` e' un dizionario o struttura equivalente con almeno:
|
|
|
|
- `mode`
|
|
- `frame_id`
|
|
- `video_time_sec`
|
|
- `scan_direction`
|
|
- `route_progress_ratio`
|
|
|
|
Il campo `pose` potra' essere sostituito piu' avanti da un provider reale SLAM / PX4 / odometria senza cambiare il contratto tra capture e inference.
|
|
|
|
## Strategia di esecuzione
|
|
|
|
### Capture worker
|
|
|
|
Un worker separato:
|
|
|
|
- legge da `VideoCapture`
|
|
- costruisce `CapturedFrame`
|
|
- pubblica solo l'ultimo frame disponibile
|
|
|
|
### Inference / control loop
|
|
|
|
Il loop principale:
|
|
|
|
- legge l'ultimo `CapturedFrame`
|
|
- esegue YOLO, tracking e logica demo
|
|
- usa sempre i metadati congelati nel pacchetto
|
|
|
|
## Regola di coda
|
|
|
|
La coda deve essere piccola:
|
|
|
|
- niente backlog lungo;
|
|
- meglio perdere frame che accumulare ritardo;
|
|
- politica `latest frame wins`.
|
|
|
|
## Impatto sul codice esistente
|
|
|
|
### Nuove entita'
|
|
|
|
- `CapturedFrame`
|
|
- `CaptureWorker`
|
|
- helper `sample_demo_pose(...)`
|
|
|
|
### Oggetti da aggiornare
|
|
|
|
- `CandidateSnapshot`
|
|
- `NavigationSnapshot`
|
|
- metadata snapshot JSON
|
|
- observer telemetry, se utile, con riferimento alla posa dell'ultimo frame
|
|
|
|
## Criteri di successo
|
|
|
|
1. il core continua a produrre lo stesso comportamento funzionale della demo;
|
|
2. inferenza e snapshot lavorano su frame con metadati coerenti;
|
|
3. `cap.read()` non sta piu' nel loop principale critico;
|
|
4. nessun backlog crescente;
|
|
5. nessun blocco se il capture worker arriva piu' veloce o piu' lento del consumer.
|