- simulator.py: flux JSONL réaliste (Ping360 angle/dist, IMU, heading, depth, altitude) + vérité terrain - slam.py: dead-reckoning + scan-to-map ICP 2D (cKDTree) + fermeture de boucle - process.py: ingestion streaming ligne-par-ligne → trajectory.csv + map_2d.csv + cloud.ply - stream_replay.py: rejoue le flux (vision streaming remote) - SCHEMA.md: contrat format données ROV réel↔sim - RMS dead-reckoning 0.386m → scan-matching 0.188m (2x)
4.8 KiB
4.8 KiB
SCHEMA.md — Contrat de flux capteurs moulin-mapper
Principe
Une ligne JSONL = un échantillon Ping360 (un faisceau sonar émis à un angle donné) avec la télémétrie co-enregistrée à cet instant exact.
Le pipeline de traitement doit fonctionner identiquement sur :
- données simulées (simulator.py)
- données réelles BlueROV (juste changer la source)
Champs optionnels futurs (image_ref, confidence, etc.) peuvent s'ajouter
sans casser le pipeline — tous les champs inconnus sont ignorés.
Format : JSONL (JSON Lines)
Un objet JSON par ligne, terminé par \n. Pas de tableau englobant.
Exemple
{"t": 12.345, "ping360_angle": 174.6, "ping360_distance": 3.21, "heading": 88.2, "altitude": 1.05, "depth": 1.82, "ax": 0.01, "ay": -0.02, "az": 9.79, "gx": 0.001, "gy": 0.0, "gz": 0.05}
Champs obligatoires
| Champ | Type | Unité | Description |
|---|---|---|---|
t |
float | s | Timestamp depuis le démarrage du flux (epoch relatif) |
ping360_angle |
float | deg | Angle du faisceau sonar relatif au cap ROV (0 = avant ROV) |
ping360_distance |
float | m | Distance mesurée jusqu'au premier écho (0.0 = dropout/pas d'écho) |
heading |
float | deg | Cap magnétique ROV, convention Nord=0, Est=90 (CW) |
altitude |
float | m | Hauteur au-dessus du fond (Ping1D vers le bas), 0.0 = dropout |
depth |
float | m | Profondeur sous la surface (pression bar → m d'eau), positif vers le bas |
ax |
float | m/s² | Accélération IMU axe X (avant ROV dans repère corps) |
ay |
float | m/s² | Accélération IMU axe Y (gauche ROV dans repère corps) |
az |
float | m/s² | Accélération IMU axe Z (haut ROV dans repère corps), ~+9.81 au repos |
gx |
float | rad/s | Gyromètre axe X (roulis) |
gy |
float | rad/s | Gyromètre axe Y (tangage) |
gz |
float | rad/s | Gyromètre axe Z (lacet, positif = rotation CW vue du dessus) |
Repères et conventions
Repère monde : ENU local
- X = Est, Y = Nord, Z = vers le haut
- Origine = position initiale du ROV au démarrage
- Le heading 0° correspond à +Y (Nord)
Ping360
- 400 pas/tour (comme le vrai Ping360 BlueRobotics) → résolution angulaire 0.9°/pas
ping360_angleest relatif au cap ROV (0° = avant du ROV)- Pour obtenir l'angle monde :
angle_monde = (heading + ping360_angle) % 360 - Plage : [0, 360) degrés
ping360_distance = 0.0signifie absence d'écho (dropout) — à ignorer dans le pipeline
Heading
- Convention magnétique compas : 0°=Nord, 90°=Est, 180°=Sud, 270°=Ouest (CW)
- Bruit typique simulé : ~0.5° RMS
- Dérive lente optionnelle pour simuler un mauvais magnéto
Altitude (Ping1D)
- Sonar vertical pointant vers le bas
- Mesure la distance ROV → fond en mètres
altitude = 0.0signifie dropout (confidence trop basse)- Hauteur ROV au-dessus du fond =
altitude - Profondeur fond =
depth + altitude
IMU
- Repère corps ROV (Body frame) — PAS ENU
az≈ +9.81 m/s² au repos (gravité remontant dans le repère corps)- Biais gyro simulé : ~0.005 rad/s — cause dérive dead-reckoning ~18°/min
Fréquences typiques
| Source | Fréquence |
|---|---|
| Ping360 | 400 msgs/sweep, ~1 sweep/4 s (configurable) |
| IMU | 1 msg par ligne JSONL (co-enregistré avec le ping sonar) |
| heading | idem |
| altitude | idem |
| depth | idem |
Fichier vérité terrain (simulation uniquement)
run_L_truth.csv — colonnes : t, x, y, heading_deg, z
- x, y en mètres ENU depuis l'origine
- heading_deg : cap vrai (sans bruit)
- z : profondeur (positif vers le bas)
- Ce fichier n'existe PAS sur données réelles — sert uniquement à valider l'algo
Champs optionnels (présents dans la simulation, rétrocompatibles)
| Champ | Type | Unité | Description |
|---|---|---|---|
vf |
float | m/s | Vitesse corps forward (avant ROV) — modèle thruster ou DVL |
vl |
float | m/s | Vitesse corps latérale — modèle thruster ou DVL |
image_ref |
string | — | Nom du fichier image caméra co-enregistrée |
confidence |
float | [0,1] | Confiance écho Ping360 |
temperature |
float | °C | Capteur eau |
battery_v |
float | V | Tension batterie |
vf et vl sont produits par le simulateur depuis le modèle de thruster.
Sur un vrai BlueROV, ils peuvent venir d'un DVL ou du contrôleur de poussée.
Le pipeline DR utilise vf/vl s'ils sont présents, sinon intègre ax/ay.