diff --git a/AGENTS.md b/AGENTS.md index aac6813..8f5fdcc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,7 @@ ## Workflow - install: `docker build -t lidar-lidar .` (deps baked into image) +- lancement local en une commande (GPU facultatif) : `./start.sh` (carte 8973), `./start.sh process [options]`, `./start.sh logs|stop` — crée `input/`/`output/` à l'uid courant, ajoute `docker-compose.cpu.yml` (`gpus: !reset`) si Docker n'accède à aucun GPU. - build: `docker build -t lidar-lidar .` - build carte légère (Raspberry Pi, déploiement 2 machines — cf. `docs/DEPLOY_WEBAPP.md`) : `docker compose -f docker-compose.maps.yml up -d --build` (image `Dockerfile.maps`, sans PDAL/GPU) - build générateur de tuiles (machine de traitement) : `docker compose -f docker-compose.worker.yml up -d --build` (service `worker` = mapserve sur l'image complète, API + tuiles + inventaire pour les cartes distantes) diff --git a/README.md b/README.md index 5c14092..f8a75e2 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,21 @@ lidar_pipeline/ Ajouter une visualisation = 1 fonction + 1 entrée dans `VIZ_STEPS` + 1 entrée dans `COLORMAPS`. +## Démarrage rapide + +```bash +git clone && cd lidar_rendu +./start.sh # construit l'image, démarre la carte sur http://localhost:8973/ +./start.sh process --fetch-tiles 1037,6779 --file LHD_FXX_1037_6779_PTS_LAMB93_IGN69.copc.laz + # télécharge une dalle IGN et la traite +./start.sh logs # journal du serveur +./start.sh stop # arrêt +``` + +`start.sh` crée `input/` et `output/` à votre nom et détecte le GPU : sans GPU +NVIDIA utilisable par Docker, il ajoute `docker-compose.cpu.yml` et le +traitement tourne sur le CPU (plus lent). Docker Compose ≥ 2.24 requis. + ## Installation Docker ```bash diff --git a/docker-compose.cpu.yml b/docker-compose.cpu.yml new file mode 100644 index 0000000..93330b8 --- /dev/null +++ b/docker-compose.cpu.yml @@ -0,0 +1,11 @@ +# Surcharge pour une machine SANS GPU NVIDIA : retire `gpus: all` des services +# de docker-compose.yml (sinon Docker refuse de démarrer : « failed to +# discover GPU vendor from CDI »). Le pipeline bascule alors seul sur le CPU. +# Utilisée automatiquement par ./start.sh ; à la main : +# docker compose -f docker-compose.yml -f docker-compose.cpu.yml up -d --build serve +# `!reset` exige Docker Compose ≥ 2.24. +services: + serve: + gpus: !reset [] + process: + gpus: !reset [] diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..2863a86 --- /dev/null +++ b/start.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Lancement local de la carte LiDAR en une commande (GPU facultatif). +# +# ./start.sh construit l'image et démarre la carte (port 8973) +# ./start.sh stop arrête la carte +# ./start.sh logs suit le journal du serveur +# ./start.sh process [opts] traitement ponctuel des dalles de input/ +# (options passées au pipeline, ex. --file NOM) +# +# Sans GPU NVIDIA utilisable par Docker, docker-compose.cpu.yml est ajouté +# automatiquement (le pipeline tourne alors sur le CPU, plus lentement). +set -euo pipefail + +cd "$(dirname "$0")" + +# input/ et output/ créés au nom de l'utilisateur : créés par Docker, ils +# appartiendraient à root et le conteneur (uid 1000) ne pourrait pas y écrire. +mkdir -p input output +for d in input output; do + if [ ! -w "$d" ]; then + echo "Erreur : $d/ n'est pas accessible en écriture (propriétaire : $(stat -c %U "$d"))." >&2 + echo "Corrigez avec : sudo chown -R $(id -u):$(id -g) $d" >&2 + exit 1 + fi +done +if [ "$(id -u)" != "1000" ]; then + echo "Attention : les conteneurs tournent sous l'uid 1000, vous êtes $(id -u) :" >&2 + echo "input/ et output/ doivent rester accessibles en écriture à l'uid 1000." >&2 +fi + +# GPU : nvidia-smi présent ET Docker capable de le donner à un conteneur. +compose=(docker compose -f docker-compose.yml) +if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1 \ + && docker run --rm --gpus all --entrypoint true busybox >/dev/null 2>&1; then + echo "GPU NVIDIA détecté : traitement accéléré." +else + echo "Pas de GPU utilisable : traitement sur le CPU (plus lent)." + compose+=(-f docker-compose.cpu.yml) +fi + +case "${1:-up}" in + up) + "${compose[@]}" up -d --build serve + echo "Carte : http://localhost:8973/" + echo "Journal : ./start.sh logs — arrêt : ./start.sh stop" + ;; + stop) + "${compose[@]}" down + ;; + logs) + "${compose[@]}" logs -f serve + ;; + process) + shift + if [ $# -gt 0 ]; then + # Des options remplacent la commande par défaut du service : la + # reprendre en entier (entrée, sortie, 0,2 m, tous les GPU). + "${compose[@]}" run --rm --build process \ + python3 -m lidar_pipeline /data/input -o /data/output -r 0.2 -g all "$@" + else + "${compose[@]}" run --rm --build process + fi + ;; + *) + sed -n '2,10p' "$0" | sed 's/^# \{0,1\}//' + exit 1 + ;; +esac