From 9a468241994fb9eb021c91adba189c05496d68ea Mon Sep 17 00:00:00 2001 From: Floppyrj45 Date: Sun, 19 Apr 2026 18:07:05 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20Sphinx=20=E2=80=94=209=20pages=20rst,?= =?UTF-8?q?=20conf.py=20rtd-theme,=20sources.bib,=20navigator=5Fimu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- docs/Makefile | 20 +++++ docs/make.bat | 35 +++++++++ docs/source/blueos.rst | 106 +++++++++++++++++++++++++ docs/source/calibration.rst | 101 ++++++++++++++++++++++++ docs/source/conf.py | 38 +++++++++ docs/source/deployment.rst | 98 +++++++++++++++++++++++ docs/source/hardware.rst | 74 ++++++++++++++++++ docs/source/index.rst | 24 ++++++ docs/source/navigator_imu.rst | 68 ++++++++++++++++ docs/source/slam_stack.rst | 134 ++++++++++++++++++++++++++++++++ docs/source/sources.bib | 59 ++++++++++++++ docs/source/sources.rst | 6 ++ docs/source/theory_baseline.rst | 98 +++++++++++++++++++++++ 13 files changed, 861 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/blueos.rst create mode 100644 docs/source/calibration.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/deployment.rst create mode 100644 docs/source/hardware.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/navigator_imu.rst create mode 100644 docs/source/slam_stack.rst create mode 100644 docs/source/sources.bib create mode 100644 docs/source/sources.rst create mode 100644 docs/source/theory_baseline.rst diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..dc1312a --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/blueos.rst b/docs/source/blueos.rst new file mode 100644 index 0000000..6a336fa --- /dev/null +++ b/docs/source/blueos.rst @@ -0,0 +1,106 @@ +Intégration BlueOS +================== + +BlueOS Overview +--------------- + +BlueOS est le système d'exploitation embarqué de Blue Robotics +pour le BlueROV2. Il tourne sous Raspberry Pi OS + Docker. +Les extensions BlueOS sont des conteneurs Docker exposés via +une API REST et une UI web intégrée. + +Extension SLAM +-------------- + +L'extension SLAM est définie dans ``/Dockerfile`` à la racine du projet. + +Format manifest BlueOS +~~~~~~~~~~~~~~~~~~~~~~~ + +Chaque extension doit inclure des labels Docker spécifiques : + +.. code-block:: dockerfile + + LABEL version="0.1.0" + LABEL permissions='{"NetworkMode": "host", "Devices": ["/dev/video0", "/dev/video1"]}' + LABEL authors='[{"name": "Baptiste Moulin", "email": "baptiste@example.com"}]' + LABEL company='{"about": "", "name": "Baptiste Moulin", "email": ""}' + LABEL type="device-integration" + LABEL tags='["slam", "stereo", "vision"]' + LABEL readme='https://raw.githubusercontent.com/.../README.md' + LABEL links='{"website": "", "support": ""}' + +Accès caméras USB +~~~~~~~~~~~~~~~~~ + +BlueOS utilise ``udev`` pour les caméras. S'assurer que : + +.. code-block:: bash + + # Sur le Pi, vérifier les devices + ls /dev/video* + # → /dev/video0 /dev/video1 + + # Dans BlueOS Docker, les devices sont passés via permissions JSON + # "Devices": ["/dev/video0", "/dev/video1"] + +Port réseau +~~~~~~~~~~~ + +L'interface Flask tourne sur le port **5000**. +BlueOS expose les extensions via son proxy Nginx. +Accès depuis l'interface BlueOS : ``http:///extensions/slam-stereo``. + +Installation via BlueOS UI +-------------------------- + +1. Ouvrir BlueOS : ``http://`` +2. Menu → Extensions → Installer +3. Entrer l'image Docker : ``ghcr.io/baptiste-moulin/slam-stereo-blueos:latest`` +4. Valider les permissions +5. Lancer l'extension + +Installation manuelle (SSH) +---------------------------- + +.. code-block:: bash + + ssh pi@ + + # Build l'image localement + cd /home/pi/slam_stereo + docker build -t slam-stereo-blueos . + + # Lancer le conteneur + docker run -d \ + --network host \ + --device /dev/video0 \ + --device /dev/video1 \ + -p 5000:5000 \ + --name slam-stereo \ + slam-stereo-blueos + +Logs +---- + +.. code-block:: bash + + docker logs -f slam-stereo + +MAVLink Integration (optionnel) +--------------------------------- + +Pour envoyer la pose estimée au pilote automatique (ArduSub/ArduPilot) : + +- Protocole MAVLink ``VISION_POSITION_ESTIMATE`` (ID 102) +- Bibliothèque Python : ``pymavlink`` +- Connexion via ``udpin:0.0.0.0:14550`` (BlueOS MAVLink router) + +.. code-block:: python + + # Exemple envoi pose (à implémenter dans src/slam/mavlink_bridge.py) + from pymavlink import mavutil + mav = mavutil.mavlink_connection('udpout:127.0.0.1:14550') + mav.mav.vision_position_estimate_send( + usec, x, y, z, roll, pitch, yaw + ) diff --git a/docs/source/calibration.rst b/docs/source/calibration.rst new file mode 100644 index 0000000..b59bae1 --- /dev/null +++ b/docs/source/calibration.rst @@ -0,0 +1,101 @@ +Calibration Stéréo +================== + +Matériel nécessaire +------------------- + +- Damier imprimé **9×6 cases** (intérieur), case **25 mm** +- Support rigide (plastifié recommandé) +- Éclairage uniforme sans reflets + +.. warning:: + Imprimer sur fond blanc mat. Plastifier sans brillance pour éviter + les reflets. Ne pas utiliser d'écran LCD (déformation optique). + +Procédure +--------- + +Étape 1 — Capture des paires +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: bash + + python src/calibration/stereo_capture.py + +- Lance les 2 webcams simultanément (USB 0 et 1) +- Appuyer sur ``ESPACE`` pour capturer une paire +- Objectif : **30 paires valides** minimum +- Varier : distance (0.3–1.5 m), inclinaison (±30°), position dans frame + +.. tip:: + Couvrir les 4 coins du champ + centre. Inclure des poses inclinées + pour mieux contraindre les coefficients de distorsion tangentielle. + +Étape 2 — Calibration +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: bash + + python src/calibration/stereo_calibrate.py + +Résultat attendu : + +.. code-block:: text + + Chargement 30 paires de damier... + Calibration stéréo... + RMS reprojection error: 0.42 px ← bon si < 0.8 px + Sauvegarde: config/stereo_calib.yaml + +Fichier YAML généré +------------------- + +``config/stereo_calib.yaml`` contient : + +.. code-block:: yaml + + K1: [[fx, 0, cx], [0, fy, cy], [0, 0, 1]] # caméra gauche + D1: [k1, k2, p1, p2, k3] # distorsion gauche + K2: [[fx, 0, cx], [0, fy, cy], [0, 0, 1]] # caméra droite + D2: [k1, k2, p1, p2, k3] # distorsion droite + R: [[...], [...], [...]] # rotation C2→C1 + T: [tx, ty, tz] # translation (baseline) + E: [[...]] # matrice essentielle + F: [[...]] # matrice fondamentale + R1, P1, R2, P2, Q # rectification + +Paramètres OpenCV +----------------- + +``stereoCalibrate`` avec flags : + +.. code-block:: python + + flags = ( + cv2.CALIB_FIX_INTRINSIC # si calibration individuelle faite avant + # ou cv2.CALIB_RATIONAL_MODEL # pour modèle 8 coefs + ) + criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-5) + +``stereoRectify`` avec ``alpha=0`` (recadrage maximal, pas de bandes noires). + +Validation +---------- + +Après calibration, vérifier : + +1. Erreur RMS < 0.8 px (idéalement < 0.5 px) +2. Lignes épipolaires horizontales sur image rectifiée +3. Translation T ≈ [−0.11, 0, 0] m (baseline sur axe X) +4. Épipole à l'infini (caméras parallèles après rectif) + +.. code-block:: bash + + # Visualisation rectification + python src/calibration/stereo_calibrate.py --show-rectified + +Références +---------- + +:cite:`bradski2008learning` — OpenCV stereoCalibrate, stereoRectify. +:cite:`ferrera2019underwater` — Prise en compte réfraction eau/verre. diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..8292d4c --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,38 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'SLAM_Stereo_BlueOS' +copyright = '2026, Baptiste Moulin' +author = 'Baptiste Moulin' + +version = '0.1' +release = '0.1' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.viewcode', + 'sphinx.ext.mathjax', + 'myst_parser', + 'sphinxcontrib.bibtex', +] + +templates_path = ['_templates'] +exclude_patterns = [] + +# BibTeX +bibtex_bibfiles = ['sources.bib'] + +# MyST +myst_enable_extensions = ['dollarmath', 'amsmath'] + +# -- Options for HTML output ------------------------------------------------- +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] diff --git a/docs/source/deployment.rst b/docs/source/deployment.rst new file mode 100644 index 0000000..df424c7 --- /dev/null +++ b/docs/source/deployment.rst @@ -0,0 +1,98 @@ +Déploiement — Raspberry Pi +========================== + +Prérequis +--------- + +- ``sshpass`` installé (``sudo apt install sshpass`` ou ``brew install sshpass``) +- ``rsync`` disponible +- Pi accessible via réseau (BlueOS Ethernet ou WiFi) +- Credentials par défaut : ``pi`` / ``raspberry`` + +Script deploy +------------- + +.. code-block:: bash + + bash scripts/deploy_pi.sh + # Exemple : + bash scripts/deploy_pi.sh 192.168.2.2 + +Le script effectue : + +1. Test de connectivité SSH +2. ``rsync`` de ``/src/`` vers ``/home/pi/slam_stereo/src/`` +3. ``rsync`` de ``/config/`` vers ``/home/pi/slam_stereo/config/`` +4. Installation pip des dépendances Python +5. Redémarrage du service Flask (si systemd configuré) + +Installation manuelle +--------------------- + +.. code-block:: bash + + ssh pi@ + + # Installer dépendances système + sudo apt update + sudo apt install -y python3-pip python3-opencv libopencv-dev + + # Installer dépendances Python + pip3 install flask numpy pyyaml opencv-python + + # Copier les fichiers (depuis PC) + rsync -av src/ pi@:/home/pi/slam_stereo/src/ + rsync -av config/ pi@:/home/pi/slam_stereo/config/ + +Service systemd (optionnel) +----------------------------- + +Créer ``/etc/systemd/system/slam-stereo.service`` sur le Pi : + +.. code-block:: ini + + [Unit] + Description=SLAM Stereo Flask Interface + After=network.target + + [Service] + User=pi + WorkingDirectory=/home/pi/slam_stereo + ExecStart=/usr/bin/python3 src/interface/app.py + Restart=always + + [Install] + WantedBy=multi-user.target + +.. code-block:: bash + + sudo systemctl enable slam-stereo + sudo systemctl start slam-stereo + +Vérification +------------ + +.. code-block:: bash + + # Depuis le Pi + curl http://localhost:5000/ + + # Depuis le réseau + curl http://:5000/ + + # Logs Flask + journalctl -u slam-stereo -f + +Notes BlueOS +------------ + +BlueOS expose le Pi sur ``192.168.2.2`` par défaut (connexion USB-Ethernet). +En WiFi, l'IP est assignée par DHCP. + +Pour trouver l'IP : + +.. code-block:: bash + + # Depuis BlueOS web UI : Settings → Network + # Ou scan réseau : + nmap -sn 192.168.2.0/24 diff --git a/docs/source/hardware.rst b/docs/source/hardware.rst new file mode 100644 index 0000000..28062ab --- /dev/null +++ b/docs/source/hardware.rst @@ -0,0 +1,74 @@ +Hardware +======== + +Composants +---------- + +Raspberry Pi 4B +~~~~~~~~~~~~~~~ + +- **CPU** : Broadcom BCM2711, Cortex-A72 64-bit @ 1.8 GHz +- **RAM** : 4 GB LPDDR4 +- **OS** : BlueOS (Raspbian Bullseye + Docker) +- **Connexion** : Ethernet ou WiFi 5 GHz +- **Alimentation** : 5V 3A via câble BlueROV2 ou USB-C + +Caméras stéréo — Microsoft LifeCam HD-3000 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- **Résolution** : 1280×720 @ 30 fps +- **Interface** : USB 2.0 +- **Focale estimée** : ~525 px (à calibrer) +- **Champ** : ~68° horizontal +- **Boîtier** : étanche DIY ou logement BlueROV2 + +.. note:: + Les caméras ne sont pas étanches nativement. Un boîtier optique + plat (port verre optique sans distorsion) est nécessaire. + Utiliser du verre borosilicate 5 mm, joint EPDM, serrage 6 vis M3. + +Carte Navigator (Blue Robotics) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +La carte Navigator est directement connectée au GPIO 40-pins du Pi4B. + +- **IMU** : Bosch BMI088 (accéléromètre + gyroscope 6-axes séparés) +- **Baromètre/profondimètre** : TE MS5837-30BA (0–300 bar) +- **PWM thrusters** : NXP PCA9685 (16 canaux I2C) +- **Interface** : SPI (BMI088) + I2C (MS5837, PCA9685) +- **Fréquence IMU** : jusqu'à 400 Hz configurable via ArduSub +- Voir ``docs/source/navigator_imu.rst`` pour détail fusion VIO + +Support caméras (OpenSCAD) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Voir ``/hardware/camera_mount.scad``. + +- Espacement fixe **11 cm** (médiane de la plage optimale 10–12 cm) +- Trous M3 × 4 pour fixation sur châssis AUV +- Slot câbles USB intégré +- Matériau recommandé : PETG (résistance eau, déformation thermique) + +Montage +------- + +:: + + Vue de dessus : + + USB-A Pi4 USB-A Pi4 + | | + ________↓_________ _________↓________ + | LifeCam gauche |←11cm→| LifeCam droite | + |__________________| |__________________| + ↓ ↓ + Cam 0 Cam 1 + (cv2.VideoCapture(0)) (cv2.VideoCapture(1)) + + +Connectique BlueROV2 +-------------------- + +Le Raspberry Pi 4B se loge dans le tube électronique principal. +Les câbles USB traversent le presse-étoupe 4 trous M10. +Prévoir longueur câble USB ≥ 30 cm (interne) + 15 cm (externe vers support). diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..43dc7aa --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,24 @@ +SLAM Stéréo BlueOS — Documentation +==================================== + +SLAM visuel stéréo pour AUV sous-marin autonome. +Intégration BlueOS (Raspberry Pi 4B), ORB-SLAM3, Flask. + +.. toctree:: + :maxdepth: 2 + :caption: Contenu + + hardware + theory_baseline + calibration + navigator_imu + slam_stack + blueos + deployment + sources + +Indices et tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/docs/source/navigator_imu.rst b/docs/source/navigator_imu.rst new file mode 100644 index 0000000..98d2253 --- /dev/null +++ b/docs/source/navigator_imu.rst @@ -0,0 +1,68 @@ +Carte Navigator — BMI088 IMU +============================= + +La carte Navigator de Blue Robotics embarque : + +- **IMU** : Bosch BMI088 (accéléromètre 6-axes + gyroscope 6-axes, séparés physiquement) +- **Baromètre** : TE MS5837-30BA (profondimètre 300 bar) +- **PWM** : NXP PCA9685 (16 canaux, contrôle thrusters via ArduSub) + +Spécifications BMI088 +--------------------- + +.. list-table:: + :header-rows: 1 + + * - Paramètre + - Valeur + * - Plage accéléromètre + - ±3g / ±6g / ±12g / ±24g + * - Bruit accéléromètre + - 175 μg/√Hz + * - Plage gyroscope + - ±125 à ±2000 °/s + * - Bruit gyroscope + - 0.014 °/s/√Hz + * - Interface + - SPI / I2C + * - Fréquence sortie + - 100–400 Hz (configurable) + +Accès via BlueOS / MAVLink +--------------------------- + +ArduSub lit le BMI088 via l'interface SPI interne de la Navigator. +Les données IMU sont accessibles en MAVLink (message ``SCALED_IMU``). + +.. code-block:: python + + from pymavlink import mavutil + + mav = mavutil.mavlink_connection('udpin:192.168.0.174:14550') + mav.wait_heartbeat() + + while True: + msg = mav.recv_match(type='SCALED_IMU', blocking=True) + if msg: + ax = msg.xacc / 1000.0 # mg -> g + ay = msg.yacc / 1000.0 + az = msg.zacc / 1000.0 + gx = msg.xgyro / 1000.0 # mrad/s -> rad/s + print(f"Acc: {ax:.3f} {ay:.3f} {az:.3f} g") + +Fusion visuo-inertielle (VIO) +------------------------------ + +ORB-SLAM3 mode **Stereo-Inertial** requiert : + +1. Extrinsèques IMU-caméra (matrice ``T_cam_imu``) — à calibrer via Kalibr +2. Biais accéléromètre et gyroscope (InitialAccBias, InitialGyroBias) +3. Fréquence IMU ≥ 200 Hz (configurer ArduSub ``IMU_FAST_RATE=1``) + +Fichier config ORB-SLAM3 : ``config/navigator_imu.yaml`` (à générer après calibration Kalibr). + +Références +---------- + +- `Blue Robotics Navigator Documentation `_ +- BMI088 Datasheet — Bosch Sensortec BST-BMI088-DS001 diff --git a/docs/source/slam_stack.rst b/docs/source/slam_stack.rst new file mode 100644 index 0000000..f5eaa3e --- /dev/null +++ b/docs/source/slam_stack.rst @@ -0,0 +1,134 @@ +Stack SLAM +========== + +Choix : ORB-SLAM3 +----------------- + +ORB-SLAM3 :cite:`campos2021orbslam3` est retenu comme backend SLAM. + +Justification : + +- **Modes** : Monoculaire, Stéréo, RGB-D, IMU (Stéréo-Inertiel) +- **Précision** : RMSE trajectoire < 2 cm en stéréo indoor (EuRoC dataset) +- **Open-source** : GPLv3, actif sur GitHub +- **ROS2** : wrappers disponibles (ros2-orbslam3) +- **Robustesse** : réinitialisation automatique, loop closure, multi-map + +Comparatif +---------- + +.. list-table:: + :header-rows: 1 + :widths: 20 20 20 20 20 + + * - Stack + - Mode stéréo + - IMU + - ROS2 + - Licence + * - **ORB-SLAM3** + - Oui + - Oui + - Via wrapper + - GPLv3 + * - VINS-Fusion + - Oui + - Oui + - ROS1 natif + - GPLv3 + * - OpenVSLAM + - Oui + - Non + - Oui + - BSD + * - Kimera + - Oui + - Oui + - ROS1 + - BSD + * - ElasticFusion + - RGB-D only + - Non + - Non + - Non-commercial + +VINS-Fusion :cite:`qin2019fusion` — candidat secondaire. +Avantage : robustesse outdoor. Inconvénient : ROS1, moins maintenu. + +Architecture ORB-SLAM3 +---------------------- + +.. code-block:: text + + ┌─────────────────────────────────────────────────┐ + │ ORB-SLAM3 │ + │ │ + │ Tracking Thread ──► Local Mapping Thread │ + │ │ │ │ + │ Feature ORB Map Points │ + │ Matching KeyFrames │ + │ │ │ │ + │ Pose Estimation Loop Closing Thread │ + │ (PnP + IMU) (DBoW2 + g2o) │ + │ │ │ + │ Atlas (Multi-Map) │ + └─────────────────────────────────────────────────┘ + +Dépendances compilation +----------------------- + +.. code-block:: bash + + # Eigen3 + sudo apt install libeigen3-dev + + # OpenCV 4.x + sudo apt install libopencv-dev + + # Pangolin (viewer 3D) + git clone https://github.com/stevenlovegrove/Pangolin + cd Pangolin && cmake -B build && cmake --build build + + # g2o (inclus dans ORB-SLAM3) + # DBoW2 (inclus dans ORB-SLAM3) + + # ORB-SLAM3 + git clone https://github.com/UZ-SLAMLab/ORB_SLAM3 + cd ORB_SLAM3 && chmod +x build.sh && ./build.sh + +Paramètres SLAM — fichier YAML +-------------------------------- + +Voir ``config/orbslam3_stereo.yaml`` (à créer après calibration) : + +.. code-block:: yaml + + Camera.type: "KannalaBrandt8" # ou "Pinhole" + Camera.fx: 525.0 + Camera.fy: 525.0 + Camera.cx: 640.0 + Camera.cy: 360.0 + + Stereo.b: 0.11 # baseline en mètres + Stereo.ThDepth: 35.0 # profondeur max (b * ThDepth pixels) + + ORBextractor.nFeatures: 1000 + ORBextractor.scaleFactor: 1.2 + ORBextractor.nLevels: 8 + +Contraintes sous-marines +------------------------- + +- **Texture** : eau lisse = peu de features. Pointer vers fond ou structure. +- **Absorption** : rouge absorbé > 3 m. Filtre passe-haut sur illumination. +- **Turbidité** : features instables. Réduire ``ThDepth``, augmenter ``nFeatures``. +- **Réfraction** : calibration en air ≠ en eau. Recalibrer si possible en eau. + +Références +---------- + +:cite:`campos2021orbslam3` + +:cite:`qin2019fusion` + +:cite:`joshi2019survey` diff --git a/docs/source/sources.bib b/docs/source/sources.bib new file mode 100644 index 0000000..0687c2a --- /dev/null +++ b/docs/source/sources.bib @@ -0,0 +1,59 @@ +% ORB-SLAM3 — Campos et al. 2021, IEEE Transactions on Robotics +@article{campos2021orbslam3, + author = {Campos, Carlos and Elvira, Richard and Gómez Rodríguez, Juan J. + and Montiel, José M. M. and Tardós, Juan D.}, + title = {{ORB-SLAM3}: An Accurate Open-Source Library for Visual, + Visual-Inertial, and Multimap {SLAM}}, + journal = {IEEE Transactions on Robotics}, + volume = {37}, + number = {6}, + pages = {1874--1890}, + year = {2021}, + doi = {10.1109/TRO.2021.3075644}, +} + +% VINS-Fusion — Qin & Shen 2019 +@article{qin2019fusion, + author = {Qin, Tong and Pan, Jie and Cao, Shaozu and Shen, Shaojie}, + title = {A General Optimization-based Framework for Local Odometry + Estimation with Multiple Sensors}, + journal = {arXiv preprint arXiv:1901.03638}, + year = {2019}, + url = {https://arxiv.org/abs/1901.03638}, +} + +% Calibration sous-marine — Ferrera et al. 2019 +@inproceedings{ferrera2019underwater, + author = {Ferrera, Maxime and Moras, Julien and Trouvé-Peloux, Pauline}, + title = {Real-Time Monocular Visual Odometry for Turbid and Dynamic + Underwater Environments}, + booktitle = {Proceedings of the IEEE International Conference on Robotics + and Automation (ICRA)}, + year = {2019}, + pages = {9720--9726}, + doi = {10.1109/ICRA.2019.8793818}, +} + +% Survey SLAM AUV — Joshi et al. 2019 +@article{joshi2019survey, + author = {Joshi, Bharat and Rahman, Sharmin and Kalaitzakis, Michail + and Cain, Brennan and Johnson, James and Xanthidis, Marios + and Karapetyan, Nare and Hernandez, Aven and Henderson, + Thomas C. and Rekleitis, Ioannis}, + title = {Experimental Comparison of Open Source Visual-Inertial-Based + State Estimation Algorithms in the Underwater Domain}, + booktitle = {2019 IEEE/RSJ International Conference on Intelligent Robots + and Systems (IROS)}, + year = {2019}, + pages = {7227--7234}, + doi = {10.1109/IROS40897.2019.8968049}, +} + +% OpenCV Learning — Bradski & Kaehler 2008 +@book{bradski2008learning, + author = {Bradski, Gary and Kaehler, Adrian}, + title = {Learning {OpenCV}: Computer Vision with the {OpenCV} Library}, + publisher = {O'Reilly Media}, + year = {2008}, + isbn = {978-0596516130}, +} diff --git a/docs/source/sources.rst b/docs/source/sources.rst new file mode 100644 index 0000000..79339fa --- /dev/null +++ b/docs/source/sources.rst @@ -0,0 +1,6 @@ +Bibliographie +============= + +.. bibliography:: + :all: + :style: unsrt diff --git a/docs/source/theory_baseline.rst b/docs/source/theory_baseline.rst new file mode 100644 index 0000000..1301b63 --- /dev/null +++ b/docs/source/theory_baseline.rst @@ -0,0 +1,98 @@ +Théorie — Baseline Stéréo +========================== + +Modèle géométrique +------------------ + +Le système stéréo calibré suit le modèle trou d'aiguille rectifié. +Après rectification, les lignes épipolaires sont horizontales et +la disparité est uniquement sur l'axe X. + +Relation profondeur–disparité +------------------------------ + +.. math:: + + Z = \frac{f \cdot B}{d} + +Avec : + +- :math:`Z` — profondeur en mètres +- :math:`f` — focale en **pixels** (après calibration) +- :math:`B` — baseline en **mètres** +- :math:`d` — disparité en **pixels** + +Paramètres du système +--------------------- + +.. list-table:: + :header-rows: 1 + + * - Paramètre + - Valeur + - Source + * - Focale estimée :math:`f` + - 525 px + - LifeCam HD-3000, résolution 1280×720 + * - Baseline :math:`B` + - 0.11 m + - Support OpenSCAD, médiane 10–12 cm + * - Disparité min :math:`d_{min}` + - 1 px + - Limite théorique + * - Disparité max :math:`d_{max}` + - 64 px + - StereoBM / SGBM config + +Portée théorique +---------------- + +.. math:: + + Z_{max} = \frac{f \cdot B}{d_{min}} = \frac{525 \times 0.11}{1} = 57.75 \text{ m} + +.. math:: + + Z_{min} = \frac{f \cdot B}{d_{max}} = \frac{525 \times 0.11}{64} \approx 0.9 \text{ m} + +**Portée pratique sous-marin** : 0.5 m – 5 m + +La limite pratique est imposée par la **visibilité de l'eau** (turbidité, +diffusion), pas par la géométrie. En eau claire méditerranéenne, +portée max mesurée ≈ 8 m. En eau verte côtière : ≈ 2–3 m. + +Pourquoi 10–12 cm ? +-------------------- + +**Baseline trop courte** (< 5 cm) : + +- Disparité trop faible → bruit dominant +- :math:`Z_{max}` réduit, peu de points 3D à grande distance + +**Baseline trop longue** (> 20 cm) : + +- Zone aveugle centrale grande (:math:`Z_{min}` augmente) +- Occultations importantes (objet vu par une seule caméra) +- Synchronisation temporelle plus critique + +**Plage 10–12 cm** : + +- Compromise optimal pour portée 0.5–5 m +- Compatible avec gabarit BlueROV2 (largeur tube ~10 cm) +- Résolution en profondeur : :math:`\delta Z = Z^2 / (f \cdot B)` ≈ 4 cm à 2 m + +Sensibilité à la calibration +----------------------------- + +Une erreur de 1 mm sur la baseline :math:`B` induit une erreur +:math:`\delta Z / Z = \delta B / B \approx 0.9\%` sur toutes les profondeurs. + +Conserver le support imprimé rigide et éviter le choc thermique +(dilatation différentielle PETG/aluminium). + +Références +---------- + +:cite:`campos2021orbslam3` — ORB-SLAM3, précision stéréo-inertiel. + +:cite:`ferrera2019underwater` — Calibration sous-marine, modèle réfraction.