feat: docs Sphinx pipeline + lien dashboard header

This commit is contained in:
Flag
2026-04-23 21:17:49 +00:00
parent 1bbb6c8e6d
commit 91b25f0aae
90 changed files with 9557 additions and 5 deletions

162
docs/_build/html/_sources/data.rst.txt vendored Normal file
View File

@@ -0,0 +1,162 @@
Données — Stockage et budget disque
=====================================
Où sont stockées les données
------------------------------
.. list-table::
:header-rows: 1
:widths: 30 20 50
* - Type de donnée
- Emplacement
- Remarques
* - MP4 bruts GoPro
- z620 ``/mnt/portablessd``
- Ne quittent jamais z620. Jamais copiés sur workers.
* - Frames JPEG
- Worker ``/cosma-qc-frames/job_{id}/frame_*.jpg``
- Conservés pour reprise sur crash. Supprimables après validation du stitch.
* - PLY par job
- Worker ``/cosma-qc-frames/job_{id}/reconstruction.ply``
- Entrée du stitch per_auv.
* - PLY stitch par AUV
- Worker ``/cosma-qc-frames/stitch_{N}.ply``
- Fusion des segments d'un AUV.
* - PLY stitch global
- Worker ``/cosma-qc-frames/stitch_global.ply``
- Nuage de points final toute mission.
* - GLB (export web)
- Worker ``/cosma-qc-frames/job_{id}/reconstruction.glb``
- Généré à la demande. 5M points, ~76 MB.
Budget disque observé
----------------------
.. list-table::
:header-rows: 1
:widths: 40 30 30
* - Type
- Taille typique
- Base de calcul
* - Frames JPEG par job
- ~11 GB
- job 45 min à 2 fps, 1920x1080
* - PLY par job (reconstruction)
- 2 5 GB
- dépend de la densité de la scène
* - GLB par job (export web)
- ~76 MB
- 5M points (job_21 observé)
* - PLY stitch AUV
- variable
- somme des PLY segments
* - PLY global
- variable
- somme de tous les AUV
Pour un AUV avec 4 jobs de 45 min chacun :
- Frames : 4 x 11 GB = **~44 GB** (supprimables après validation)
- PLY jobs : 4 x 3.5 GB = **~14 GB**
- PLY stitch AUV : **~6-10 GB**
Politique de nettoyage
------------------------
Frames JPEG
^^^^^^^^^^^
Les frames sont conservées uniquement pour permettre la reprise sur crash.
Une fois le stitch per_auv validé visuellement, **les frames peuvent être supprimées**.
.. code-block:: bash
# Supprimer les frames d'un job (conserver le PLY !)
rm -rf /cosma-qc-frames/job_ID/frame_*.jpg
rm -f /cosma-qc-frames/job_ID/.video_*.done
# Vérifier que le PLY est intact avant suppression
ls -lh /cosma-qc-frames/job_ID/reconstruction.ply
PLY intermédiaires
^^^^^^^^^^^^^^^^^^
Les PLY par job peuvent être supprimés après que le stitch per_auv est validé
et sauvegardé hors-ligne.
.. code-block:: bash
# Conserver uniquement le stitch, supprimer les PLY jobs
rm /cosma-qc-frames/job_ID/reconstruction.ply
Vérification espace disque
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
# Espace total workers
ssh floppyrj45@192.168.0.84 "df -h /cosma-qc-frames"
ssh floppyrj45@192.168.0.87 "df -h /cosma-qc-frames"
# Taille par job
du -sh /cosma-qc-frames/job_*/
# Top consommateurs
du -sh /cosma-qc-frames/* | sort -rh | head -20
Export GLB
-----------
Le GLB est une version allégée du nuage de points pour visualisation web.
Génération via l'API dashboard :
.. code-block:: bash
curl -X POST http://192.168.0.82:3849/jobs/ID/export_glb
Génération manuelle sur le worker :
.. code-block:: python
import trimesh, numpy as np
pc = trimesh.load('/cosma-qc-frames/job_ID/reconstruction.ply')
idx = np.random.choice(len(pc.vertices), 5_000_000, replace=False)
sub = trimesh.PointCloud(pc.vertices[idx], colors=pc.colors[idx])
sub.export('/cosma-qc-frames/job_ID/reconstruction.glb')
Téléchargement :
.. code-block:: bash
# Lancer le serveur HTTP sur le worker
ssh floppyrj45@192.168.0.84 \
"python3 -m http.server 8300 --directory /cosma-qc-frames"
# Télécharger depuis PC
wget http://192.168.0.84:8300/job_ID/reconstruction.glb
Reprise sur crash — marqueurs .done
-------------------------------------
Chaque MP4 extrait avec succès génère un fichier marqueur :
.. code-block:: text
/cosma-qc-frames/job_ID/.video_0.done
/cosma-qc-frames/job_ID/.video_1.done
...
En cas de crash, la reprise saute automatiquement les vidéos déjà traitées.
Pour forcer une ré-extraction complète :
.. code-block:: bash
rm /cosma-qc-frames/job_ID/.video_*.done

13
docs/_build/html/_sources/index.rst.txt vendored Normal file
View File

@@ -0,0 +1,13 @@
cosma-qc — Documentation
=========================
Pipeline de contrôle qualité vidéo pour drones sous-marins AUV COSMA.
.. toctree::
:maxdepth: 2
:caption: Contenu
pipeline
infrastructure
data
usage

View File

@@ -0,0 +1,171 @@
Infrastructure
==============
Réseau LAN — 192.168.0.0/24
-----------------------------
.. code-block:: text
┌─────────────────────────────────────────────────────────┐
│ LAN 192.168.0.0/24 │
│ │
│ .82 CORE Dispatcher (systemd) + FastAPI :3849 │
│ Gitea + Grafana + InfluxDB + Caddy │
│ │
│ .84 ml-stack GPU worker RTX 3090 24GB │
│ .87 gpu GPU worker RTX 3060 12GB │
│ │
│ .168 z620 Proxmox host HP Z620 │
│ SSD → /mnt/portablessd (MP4 bruts) │
└─────────────────────────────────────────────────────────┘
Nœud core (.82)
----------------
**Rôle :** orchestrateur central du pipeline.
Services actifs :
- **Dispatcher** — service systemd cosma-qc-dispatcher.
Boucle principale qui dispatch les jobs aux workers GPU.
- **Dashboard FastAPI** — conteneur Docker exposé sur le port **3849**.
Interface web de monitoring des jobs.
- **Gitea** — dépôt source floppyrj45/cosma-qc.
- **Grafana / InfluxDB** — monitoring infrastructure.
Commandes utiles :
.. code-block:: bash
# Statut dispatcher
sudo systemctl status cosma-qc-dispatcher
# Logs dispatcher temps réel
sudo journalctl -u cosma-qc-dispatcher -f
# Dashboard
http://192.168.0.82:3849
Nœuds GPU workers (.84 et .87)
--------------------------------
.. list-table::
:header-rows: 1
:widths: 15 25 20 40
* - IP
- Nom
- GPU
- VRAM
* - .84
- ml-stack
- RTX 3090
- 24 GB
* - .87
- gpu
- RTX 3060
- 12 GB
**Rôle :** exécution de ffmpeg (extraction frames) et lingbot-map (reconstruction 3D).
Répertoire de travail sur chaque worker :
.. code-block:: text
/cosma-qc-frames/
├── job_1/
│ ├── frame_000001.jpg … frame_NNNNNN.jpg
│ ├── .video_0.done
│ ├── reconstruction.ply
│ └── reconstruction.glb (généré à la demande)
├── job_2/
│ └── …
└── stitch_1.ply
Nœud z620 (.168)
-----------------
**Rôle :** stockage des MP4 bruts GoPro.
- Proxmox host HP Z620.
- SSD monté sur /mnt/portablessd.
- Les MP4 **ne quittent jamais** z620 — ffmpeg s'y exécute via SSH.
Accès SSH depuis core :
.. code-block:: bash
ssh floppyrj45@192.168.0.168
Service systemd dispatcher
---------------------------
Fichier de service : /etc/systemd/system/cosma-qc-dispatcher.service
.. code-block:: ini
[Unit]
Description=COSMA QC Dispatcher
After=network.target
[Service]
User=floppyrj45
WorkingDirectory=/home/floppyrj45/docker/cosma-qc
ExecStart=/usr/bin/python3 app/dispatcher.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Commandes de gestion :
.. code-block:: bash
sudo systemctl start cosma-qc-dispatcher
sudo systemctl stop cosma-qc-dispatcher
sudo systemctl restart cosma-qc-dispatcher
sudo systemctl enable cosma-qc-dispatcher # démarrage auto
Conteneur Docker dashboard
---------------------------
Le dashboard FastAPI tourne dans un conteneur Docker.
.. code-block:: bash
cd /home/floppyrj45/docker/cosma-qc
docker compose up -d # démarrer
docker compose down # arrêter
docker compose logs -f # logs
Accès : http://192.168.0.82:3849
Ports réseau récapitulatifs
----------------------------
.. list-table::
:header-rows: 1
:widths: 15 15 70
* - Host
- Port
- Service
* - .82
- 3849
- Dashboard FastAPI cosma-qc
* - .84 / .87
- 8100+N
- Viser viewer (reconstruction job N)
* - .84 / .87
- 8300
- HTTP server GLB export

View File

@@ -0,0 +1,185 @@
Pipeline cosma-qc
=================
Vue d'ensemble
--------------
Le pipeline cosma-qc traite les vidéos GoPro brutes acquises par les drones sous-marins
AUV COSMA pour produire des nuages de points 3D denses (PLY) et des exports web (GLB).
Flux de données global
----------------------
.. code-block:: text
z620 (/mnt/portablessd)
├── GX*.MP4 (brut)
▼ [1. Ingest]
SQLite DB (jobs)
▼ [2. Extraction ffmpeg]
GPU worker /cosma-qc-frames/job_{id}/frame_%06d.jpg
▼ [3. Reconstruction lingbot-map]
GPU worker /cosma-qc-frames/job_{id}/reconstruction.ply
▼ [4. Stitch per_auv]
GPU worker /cosma-qc-frames/stitch_{N}.ply (par AUV)
▼ [5. Stitch cross_auv]
GPU worker /cosma-qc-frames/stitch_global.ply
▼ [6. Export GLB (à la demande)]
GPU worker /cosma-qc-frames/job_{id}/reconstruction.glb
Étape 1 — Ingest
-----------------
**Script :** scripts/ingest.py
**Rôle :** Scanner le SSD de z620, regrouper les MP4 GoPro par AUV/GoPro/segment
temporel et écrire les jobs dans la base SQLite.
Logique de regroupement :
- Les fichiers sont groupés par numéro de caméra GoPro (GXXX).
- Un nouveau segment est créé si l'écart entre deux fichiers dépasse **5 minutes**.
- Chaque segment → un job en base avec statut pending.
Structure d'un job en base :
.. code-block:: sql
CREATE TABLE jobs (
id INTEGER PRIMARY KEY,
auv TEXT,
gopro TEXT,
segment INTEGER,
files TEXT, -- JSON list of z620:/path/GX*.MP4
status TEXT, -- pending / running / done / failed
worker TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Les chemins vidéo sont stockés sous la forme z620:/chemin/absolu/GX*.MP4
pour indiquer que la source est sur z620, pas sur le worker GPU.
Étape 2 — Extraction des frames
---------------------------------
**Fonction :** do_extract dans le dispatcher (core .82)
**Outil :** ffmpeg
Paramètres d'extraction :
.. code-block:: bash
ffmpeg -i input.mp4 -vf fps=2,scale=1920:1080 -q:v 2 {frames_dir}/job_{id}/frame_%06d.jpg
**Particularité z620 :** lorsque la source est z620:/..., ffmpeg s'exécute
**directement sur z620** via SSH — seuls les JPEG voyagent sur le réseau.
Les MP4 bruts ne quittent jamais z620.
Filtre hors-eau (heuristique de luminosité) :
- Les frames dont la luminosité moyenne est au-dessus d'un seuil sont supprimées
(ciel, surface, hors-eau).
- Ce filtre réduit le bruit dans la reconstruction.
Reprise sur crash :
- Un fichier marqueur .video_N.done est créé après chaque MP4 traité.
- En cas de redémarrage, les vidéos déjà traitées sont ignorées.
Étape 3 — Reconstruction 3D
-----------------------------
**Fonction :** do_reconstruct
**Outil :** lingbot-map (demo.py) sur le worker GPU
**Entrée :** répertoire de frames {worker_frames_dir}/job_{id}/
**Sortie :** {worker_frames_dir}/job_{id}/reconstruction.ply
(nuage de points dense, jusqu'à **150 millions de points**)
Un viewer Viser est automatiquement démarré sur le port 8100 + job_id
pendant la reconstruction pour visualisation en temps réel.
.. code-block:: bash
# Visualiser pendant reconstruction
# naviguer vers http://{worker_ip}:{8100+job_id}
Étape 4 — Stitch par AUV
--------------------------
**Fonction :** do_stitch_per_auv
**Déclenchement :** automatique quand **tous les jobs d'un AUV** sont en statut done.
**Outil :** cosma-stitch.py
**Opération :** alignement et fusion des PLY de tous les segments d'un même AUV.
**Sortie :** {worker_frames_dir}/stitch_{N}.ply
Ce stitch s'exécute sur le worker qui détient les PLY (pas de copie inter-workers).
Étape 5 — Stitch cross-AUV
----------------------------
**Fonction :** do_stitch_cross_auv
**Déclenchement :** automatique quand **tous les stitches per_auv** sont validés.
**Opération :** fusion de tous les PLY par AUV en un nuage de points global final.
**Sortie :** {worker_frames_dir}/stitch_global.ply
Étape 6 — Export GLB (à la demande)
-------------------------------------
**Outil :** trimesh (conversion PLY → GLB)
**Sous-échantillonnage :** 5 millions de points (adapté web/navigateur)
**Sortie :** {worker_frames_dir}/job_{id}/reconstruction.glb
Un serveur HTTP minimal est lancé sur le worker (port **8300**) pour le téléchargement :
.. code-block:: bash
# Sur le worker
python3 -m http.server 8300 --directory {worker_frames_dir}
# Télécharger depuis un PC
wget http://{worker_ip}:8300/job_{id}/reconstruction.glb
Statuts de jobs
---------------
.. list-table::
:header-rows: 1
:widths: 20 80
* - Statut
- Description
* - pending
- Job créé, en attente de dispatch
* - running
- En cours de traitement (extraction ou reconstruction)
* - done
- Reconstruction terminée, PLY disponible
* - failed
- Erreur — voir logs du dispatcher

181
docs/_build/html/_sources/usage.rst.txt vendored Normal file
View File

@@ -0,0 +1,181 @@
Utilisation
===========
Ingérer une nouvelle acquisition
----------------------------------
1. Connecter le SSD GoPro à z620 (ou s'assurer que les MP4 sont dans ``/mnt/portablessd``).
2. Lancer l'ingest depuis core :
.. code-block:: bash
ssh floppyrj45@192.168.0.82
cd /home/floppyrj45/docker/cosma-qc
python3 scripts/ingest.py --path /mnt/portablessd/AUV009/
3. Vérifier les jobs créés :
.. code-block:: bash
python3 -c "
import sqlite3
conn = sqlite3.connect('cosma-qc.db')
for row in conn.execute('SELECT id, auv, gopro, segment, status FROM jobs ORDER BY id'):
print(row)
conn.close()
"
4. Le dispatcher prend automatiquement en charge les jobs en statut ``pending``.
Surveiller les jobs
--------------------
Dashboard web
^^^^^^^^^^^^^
Accéder au dashboard : http://192.168.0.82:3849
Il affiche en temps réel :
- Statut de chaque job (pending / running / done / failed)
- Worker assigné
- Progression des frames
- Liens vers les PLY et GLB
Logs dispatcher
^^^^^^^^^^^^^^^
.. code-block:: bash
# Logs temps réel
sudo journalctl -u cosma-qc-dispatcher -f
# Logs des 100 dernières lignes
sudo journalctl -u cosma-qc-dispatcher -n 100
# Filtrer erreurs
sudo journalctl -u cosma-qc-dispatcher | grep -i error
Base de données
^^^^^^^^^^^^^^^
.. code-block:: bash
# État global des jobs
sqlite3 /home/floppyrj45/docker/cosma-qc/cosma-qc.db \
"SELECT id, auv, status, worker, updated_at FROM jobs ORDER BY id;"
# Jobs en cours
sqlite3 cosma-qc.db \
"SELECT id, auv, worker FROM jobs WHERE status='running';"
# Jobs échoués
sqlite3 cosma-qc.db \
"SELECT id, auv, status FROM jobs WHERE status='failed';"
Visualiser un nuage de points PLY
-----------------------------------
Sur le worker avec viewer Viser (lancé automatiquement pendant reconstruction) :
.. code-block:: bash
# Naviguer vers (remplacer ID par le numéro de job)
http://192.168.0.84:8100 # pour job 0
http://192.168.0.84:8101 # pour job 1
# etc.
Avec CloudCompare depuis un PC (si PLY téléchargé) :
.. code-block:: bash
# Copier le PLY vers PC
scp floppyrj45@192.168.0.84:/cosma-qc-frames/job_ID/reconstruction.ply ./
# Ouvrir dans CloudCompare
Télécharger un GLB
-------------------
1. Générer le GLB via l'API :
.. code-block:: bash
curl -X POST http://192.168.0.82:3849/jobs/ID/export_glb
2. Attendre la fin de la génération (peut prendre quelques minutes selon la taille du PLY).
3. Lancer le serveur HTTP sur le worker concerné :
.. code-block:: bash
ssh floppyrj45@192.168.0.84 \
"nohup python3 -m http.server 8300 --directory /cosma-qc-frames > /tmp/http8300.log 2>&1 &"
4. Télécharger :
.. code-block:: bash
wget http://192.168.0.84:8300/job_ID/reconstruction.glb
5. Arrêter le serveur HTTP après téléchargement :
.. code-block:: bash
ssh floppyrj45@192.168.0.84 "pkill -f 'http.server 8300'"
Relancer un job échoué
-----------------------
.. code-block:: bash
# Remettre un job en pending
sqlite3 /home/floppyrj45/docker/cosma-qc/cosma-qc.db \
"UPDATE jobs SET status='pending', worker=NULL WHERE id=ID;"
# Supprimer les marqueurs .done pour forcer ré-extraction complète
ssh floppyrj45@192.168.0.84 \
"rm -f /cosma-qc-frames/job_ID/.video_*.done"
# Redémarrer le dispatcher si nécessaire
sudo systemctl restart cosma-qc-dispatcher
Le dispatcher reprend le job au prochain cycle.
Redémarrer le pipeline complet
--------------------------------
.. code-block:: bash
# Arrêter
sudo systemctl stop cosma-qc-dispatcher
docker compose -f /home/floppyrj45/docker/cosma-qc/docker-compose.yml down
# Démarrer
docker compose -f /home/floppyrj45/docker/cosma-qc/docker-compose.yml up -d
sudo systemctl start cosma-qc-dispatcher
Vérifications rapides post-mission
------------------------------------
.. code-block:: bash
# 1. Tous les jobs done ?
sqlite3 cosma-qc.db "SELECT COUNT(*) FROM jobs WHERE status != 'done';"
# Doit retourner 0
# 2. Tous les PLY présents ?
for id in $(sqlite3 cosma-qc.db "SELECT id FROM jobs WHERE status='done'"); do
worker=$(sqlite3 cosma-qc.db "SELECT worker FROM jobs WHERE id=$id")
ssh floppyrj45@$worker "ls -lh /cosma-qc-frames/job_${id}/reconstruction.ply"
done
# 3. Espace disque OK ?
ssh floppyrj45@192.168.0.84 "df -h /cosma-qc-frames"
ssh floppyrj45@192.168.0.87 "df -h /cosma-qc-frames"