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:
82
Dockerfile
Normal file
82
Dockerfile
Normal 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
0
config/.gitkeep
Normal file
74
hardware/camera_mount.scad
Normal file
74
hardware/camera_mount.scad
Normal 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
73
scripts/deploy_pi.sh
Normal 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"
|
||||
Reference in New Issue
Block a user