feat: Dockerfile BlueOS, deploy_pi.sh rsync, camera_mount.scad baseline 110mm

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Floppyrj45
2026-04-19 18:07:28 +02:00
parent f9436df2a0
commit d36255cf62
4 changed files with 229 additions and 0 deletions

82
Dockerfile Normal file
View File

@@ -0,0 +1,82 @@
# SLAM Stéréo BlueOS — Extension Docker
# Base: ROS2 Humble (Ubuntu 22.04)
# ORB-SLAM3 + Flask interface
FROM ros:humble-ros-base AS base
LABEL version="0.1.0"
LABEL description="SLAM Stéréo visuel pour AUV sous-marin — BlueOS Extension"
LABEL authors='[{"name": "Baptiste Moulin", "email": "claude@nowyouknow.fr"}]'
LABEL company='{"about": "AUV SLAM project", "name": "Baptiste Moulin", "email": "claude@nowyouknow.fr"}'
LABEL type="device-integration"
LABEL tags='["slam", "stereo", "vision", "auv", "underwater"]'
LABEL permissions='{"NetworkMode": "host", "Devices": ["/dev/video0", "/dev/video1"], "HostConfig": {"Privileged": false}}'
ENV DEBIAN_FRONTEND=noninteractive
ENV ROS_DISTRO=humble
# --- Dépendances système ---
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-pip \
python3-opencv \
libopencv-dev \
cmake \
build-essential \
git \
wget \
libssl-dev \
libusb-1.0-0-dev \
libeigen3-dev \
libglew-dev \
libpython3-dev \
python3-numpy \
python3-yaml \
# Pangolin deps
libgl1-mesa-dev \
libglu1-mesa-dev \
freeglut3-dev \
libwayland-dev \
libxkbcommon-dev \
wayland-protocols \
&& rm -rf /var/lib/apt/lists/*
# --- Python dependencies ---
RUN pip3 install --no-cache-dir \
flask>=3.0 \
numpy>=1.24 \
pyyaml>=6.0 \
opencv-python-headless>=4.8
# --- Pangolin (viewer 3D ORB-SLAM3) ---
RUN git clone --depth 1 https://github.com/stevenlovegrove/Pangolin /opt/Pangolin && \
cmake -S /opt/Pangolin -B /opt/Pangolin/build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TOOLS=OFF \
-DBUILD_EXAMPLES=OFF && \
cmake --build /opt/Pangolin/build --parallel $(nproc) && \
cmake --install /opt/Pangolin/build && \
rm -rf /opt/Pangolin
# --- ORB-SLAM3 dependencies (g2o, DBoW2 inclus dans ORB-SLAM3) ---
# Note: compilation complète ~15 min. Décommenter pour build final.
# RUN git clone --depth 1 https://github.com/UZ-SLAMLab/ORB_SLAM3 /opt/ORB_SLAM3 && \
# cd /opt/ORB_SLAM3 && chmod +x build.sh && bash build.sh
# --- Application SLAM ---
WORKDIR /app
COPY src/ ./src/
COPY config/ ./config/
# Créer config/ si vide
RUN mkdir -p /app/config
# --- Port Flask ---
EXPOSE 5000
# --- Healthcheck ---
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
CMD curl -f http://localhost:5000/ || exit 1
# --- Entrypoint ---
ENV PYTHONUNBUFFERED=1
CMD ["python3", "src/interface/app.py"]

0
config/.gitkeep Normal file
View File

View File

@@ -0,0 +1,74 @@
// camera_mount.scad — Support stéréo pour 2x Microsoft LifeCam HD-3000
// Baseline: 110 mm (médiane 10-12 cm optimal)
// Fixation: 4x M3 sur châssis AUV
// Matériau recommandé: PETG (résistance eau, impact)
// Auteur: Baptiste Moulin 2026
$fn = 60;
// --- Paramètres principaux ---
BASELINE = 110; // mm entre axes optiques
CAM_W = 34; // largeur boîtier LifeCam (section base)
CAM_H = 34; // hauteur boîtier LifeCam
CAM_DEPTH = 10; // profondeur empreinte caméra dans le support
MOUNT_THICK = 6; // épaisseur plaque support
MOUNT_H = 50; // hauteur totale support
BOLT_D = 3.4; // diamètre trou M3 (passage libre)
BOLT_PITCH_X = 96; // entraxe vis de fixation AUV (X)
BOLT_PITCH_Y = 30; // entraxe vis de fixation AUV (Y)
// --- Longueur totale de la plaque ---
PLATE_L = BASELINE + CAM_W + 10;
module cam_cutout() {
// Empreinte caméra: rectangle + passage câble USB
cube([CAM_W, CAM_DEPTH, CAM_H], center=true);
// Slot câble USB (6x10 mm) en bas de l'empreinte
translate([0, 0, -CAM_H/2 + 5])
cube([12, CAM_DEPTH + 2, 10], center=true);
}
module bolt_holes_mount() {
// 4 trous M3 pour fixation sur châssis AUV
for (x = [-BOLT_PITCH_X/2, BOLT_PITCH_X/2])
for (y = [-BOLT_PITCH_Y/2, BOLT_PITCH_Y/2])
translate([x, y, 0])
cylinder(d=BOLT_D, h=MOUNT_THICK + 2, center=true);
}
module support() {
difference() {
// Corps principal
union() {
// Plaque horizontale
cube([PLATE_L, MOUNT_THICK, MOUNT_H], center=true);
// Renforts latéraux sur chaque caméra
for (side = [-1, 1])
translate([side * BASELINE/2, MOUNT_THICK/2, 0])
cube([CAM_W + 4, MOUNT_THICK * 2, MOUNT_H], center=true);
}
// Empreinte caméra gauche
translate([-BASELINE/2, 0, 0])
cam_cutout();
// Empreinte caméra droite
translate([BASELINE/2, 0, 0])
cam_cutout();
// Trous de fixation AUV
bolt_holes_mount();
// Allègement central (triangle)
translate([0, 0, 0])
cube([BASELINE - CAM_W - 8, MOUNT_THICK + 2, MOUNT_H - 16], center=true);
}
}
// --- Rendu principal ---
support();
// --- Annotations (commentaires) ---
// Axes optiques à Z=0, Y=MOUNT_THICK+5
// Baseline mesurée = BASELINE mm entre les 2 marques rouges
// Imprimer à 0.2 mm layer height, 40% infill gyroid, 3 périmètres

73
scripts/deploy_pi.sh Normal file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# Deploy SLAM stéréo sur Raspberry Pi via SSH/rsync
# Usage: bash deploy_pi.sh <IP_PI>
set -e
# --- Variables ---
PI_USER="pi"
PI_PASS="raspberry"
PI_DEST="/home/pi/slam_stereo"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
# --- Argument ---
if [ -z "$1" ]; then
echo "[ERREUR] Usage: $0 <IP_PI>"
echo "Exemple: $0 192.168.2.2"
exit 1
fi
PI_HOST="$1"
echo "[INFO] Déploiement vers $PI_USER@$PI_HOST:$PI_DEST"
# --- Test connectivité ---
echo "[INFO] Test SSH..."
if ! sshpass -p "$PI_PASS" ssh -o StrictHostKeyChecking=no \
-o ConnectTimeout=5 "$PI_USER@$PI_HOST" "echo 'SSH OK'" 2>/dev/null; then
echo "[ERREUR] Impossible de se connecter à $PI_HOST"
echo "[INFO] Vérifier: IP correcte, Pi allumé, sshpass installé"
exit 1
fi
# --- Créer dossiers sur Pi ---
echo "[INFO] Création des dossiers..."
sshpass -p "$PI_PASS" ssh -o StrictHostKeyChecking=no "$PI_USER@$PI_HOST" \
"mkdir -p $PI_DEST/{src/calibration,src/slam,src/interface,config}"
# --- Rsync src/ ---
echo "[INFO] Transfert src/..."
sshpass -p "$PI_PASS" rsync -avz --progress \
-e "ssh -o StrictHostKeyChecking=no" \
"$PROJECT_DIR/src/" \
"$PI_USER@$PI_HOST:$PI_DEST/src/"
# --- Rsync config/ ---
echo "[INFO] Transfert config/..."
sshpass -p "$PI_PASS" rsync -avz --progress \
-e "ssh -o StrictHostKeyChecking=no" \
"$PROJECT_DIR/config/" \
"$PI_USER@$PI_HOST:$PI_DEST/config/" 2>/dev/null || echo "[WARN] config/ vide, skip"
# --- Install dépendances Python ---
echo "[INFO] Installation dépendances Python..."
sshpass -p "$PI_PASS" ssh -o StrictHostKeyChecking=no "$PI_USER@$PI_HOST" bash << 'REMOTE'
set -e
pip3 install --upgrade pip --quiet
pip3 install opencv-python flask numpy pyyaml --quiet
echo "[OK] Dépendances installées"
REMOTE
# --- Test Flask ---
echo "[INFO] Test Flask..."
sshpass -p "$PI_PASS" ssh -o StrictHostKeyChecking=no "$PI_USER@$PI_HOST" \
"cd $PI_DEST && python3 -c 'import flask, cv2, numpy, yaml; print(\"[OK] Imports OK\")'"
echo ""
echo "=== DEPLOY TERMINÉ ==="
echo "Interface web: http://$PI_HOST:5000"
echo "Démarrage manuel:"
echo " ssh $PI_USER@$PI_HOST"
echo " cd $PI_DEST && python3 src/interface/app.py"
echo ""
echo "Note BlueOS: utiliser aussi le Dockerfile pour extension native"