Environnement Docker

S’applique à : Simulation Robot réel

Le RatBot est développé sous ROS 2 Humble (Ubuntu 22.04). Si vous disposez déjà de cet environnement, vous pouvez travailler directement sur votre machine et ignorer cette page.

Dans les autres cas, le dépôt fournit une image Docker contenant ROS 2, la simulation, les piles de cartographie et de navigation, et les outils de mise au point. Elle assure un environnement reproductible sans installation sur le système hôte, et sert aussi bien à la simulation qu’au pilotage des robots réels depuis le PC.

Note

L’environnement est testé sous Linux. Docker existe aussi sous Windows et peut y être utilisé, mais cet usage n’a pas été testé.

Prérequis

Docker Engine avec le plugin Docker Compose (commande docker compose) : https://docs.docker.com/engine/install/

Votre compte doit appartenir au groupe docker, sans quoi chaque commande exige sudo. Une fois, puis fermer et rouvrir la session :

sudo usermod -aG docker $USER

Avec une carte graphique NVIDIA, installer aussi, avant le premier démarrage, le nvidia-container-toolkit (voir Accès GPU, plus bas) : le compose.yaml réserve le GPU, et sans ce paquet docker compose run échoue.

Cloner le dépôt du RatBot, puis se placer à sa racine, où se trouvent Dockerfile et compose.yaml :

git clone <adresse du dépôt> ratbot_ws
cd ratbot_ws

Construire l’image

Depuis la racine du dépôt, une fois :

docker compose build

La construction télécharge ROS 2 et les outils du Dockerfile : elle dure plusieurs minutes et demande un accès à Internet. L’image obtenue, ratbot-dev, sert ensuite à chaque démarrage. Elle n’est à reconstruire, par la même commande, que si le Dockerfile change.

Démarrage

Autoriser l’accès au serveur graphique, une fois par session de l’hôte :

xhost +local:docker

xhost confirme par non-network local connections being added to access control list : les programmes de la machine, conteneur compris, peuvent ouvrir des fenêtres. L’autorisation dure jusqu’à la fin de la session ; xhost -local: la retire plus tôt.

Ouvrir un shell dans le conteneur :

docker compose run --rm ratbot

--rm supprime le conteneur à la sortie, non l’image. Le dépôt entier est monté depuis l’hôte, dans /workspace : code, artefacts de compilation et cartes y sont conservés, et la commande ./scripts/ratbot y est disponible. Le conteneur s’ouvre dans screen (voir Terminaux multiples, plus bas), à la racine du dépôt, /workspace : ./scripts/ratbot s’y lance tel quel. L’historique du shell est également persistant, via un volume nommé.

Avertissement

Seul /workspace est conservé. Un fichier écrit ailleurs — dans ~, c’est-à-dire /root — disparaît à la sortie du conteneur.

Les paquets installés manuellement dans un conteneur (apt install) sont en revanche perdus à la sortie ; les ajouter au Dockerfile pour les rendre permanents.

Compilation

Depuis le shell du conteneur :

./scripts/ratbot build
source ros2_ws/install/setup.bash

À la première compilation, ratbot build récupère aussi les paquets externes que le workspace compile à partir de leurs sources (exploration autonome, pont avec la carte du robot ; voir Les paquets du RatBot) : elle demande un accès à Internet. Les suivantes se contentent de recompiler.

Chaque shell du conteneur source automatiquement ROS 2 et le workspace ; le source explicite n’est nécessaire qu’après une compilation.

Le conteneur exécute le code de ros2_ws/ tel qu’il est sur l’hôte : après un git pull, il suffit de recompiler dans le conteneur, l’image n’est à reconstruire (docker compose build) que si le Dockerfile change.

Une compilation faite sur le PC ne fonctionne pas dans le conteneur, et inversement. Les deux restent donc séparées : dans le conteneur, les dossiers build/, install/ et log/ sont en réalité ceux du PC nommés build_docker/, install_docker/ et log_docker/. On peut compiler des deux côtés et passer de l’un à l’autre sans rien effacer.

Simulation ou robot réel : le domaine ROS

Les machines ROS 2 ne se voient que si elles partagent le même domaine, un numéro fixé par la variable ROS_DOMAIN_ID. Les robots utilisent le domaine 77.

Le conteneur est réglé sur ce domaine (ROS_DOMAIN_ID=77, dans compose.yaml) : il voit les robots allumés sans autre réglage, comme une installation native.

ros2 topic list            # les topics /ratbot_N/... des robots allumés

Une simulation lancée dans ce domaine pendant que des robots réels sont allumés s’y mélangerait : robots simulés et réels porteraient les mêmes noms. ./scripts/ratbot up le vérifie avant de démarrer et refuse dans ce cas (voir La simulation en détail). Pour simuler pendant que des robots tournent, choisir un autre domaine, dans chaque terminal de la simulation :

export ROS_DOMAIN_ID=0

Piloter un robot réel depuis le conteneur

Le conteneur partage le réseau du PC : il voit les robots allumés sur le même réseau, comme une installation native. La manette, branchée avant le démarrage du conteneur, y est accessible.

Toutes les commandes de La commande ratbot s’utilisent depuis la racine du dépôt :

./scripts/ratbot slam 1                      # cartographie du robot 1
./scripts/ratbot map save 1 salon            # dans les cartes du dépôt
./scripts/ratbot nav 1 salon

Une carte désignée par son seul nom est rangée dans le dépôt, sous /workspace : elle est conservée sur le PC, alors qu’une carte écrite dans ~/cartes serait perdue à la sortie du conteneur.

Terminaux multiples

La plupart des nœuds ROS restent au premier plan, ce qui impose plusieurs terminaux. Le conteneur s’ouvre donc dans screen, qui en gère plusieurs dans la même fenêtre. Ses commandes sont préfixées par Ctrl-a :

Après Ctrl-a

Action

c

Nouvelle fenêtre

n / p

Fenêtre suivante / précédente

0, 1, 2…

Accès direct à une fenêtre

| puis Tab

Partage vertical de l’écran, changement de zone

d

Détachement : retour à un shell simple, screen -r pour reprendre

La barre d’état affiche les fenêtres ouvertes et la fenêtre courante. Fermer la dernière fenêtre (exit) quitte le conteneur.

On peut aussi ouvrir un shell supplémentaire dans le conteneur en cours, depuis un autre terminal de l’hôte :

docker exec -it $(docker ps -qf name=ratbot) bash

Cette commande suppose un seul conteneur RatBot en cours. S’il y en a plusieurs, docker ps les liste : passer à docker exec -it l’identifiant de celui qui convient.

Outils de mise au point

L’image inclut :

  • rqt_robot_monitor — visualisation de /diagnostics ;

  • ros2 run tf2_tools view_frames — génération de l’arbre TF ;

  • plotjuggler — tracé temporel de topics (vitesses, batterie, cap) ;

  • ros2 bag — enregistrement et rejeu des topics ;

  • utilitaires système : nano, htop, tree, ping, ip.

Accès GPU

La simulation requiert un accès à la carte graphique : Gazebo (moteur ogre2) exige OpenGL 3.3 et le lidar simulé (gpu_lidar) est calculé par le GPU.

Deux symptômes en cas d’accès manquant :

  • échec au démarrage de Gazebo (OGRE EXCEPTION: OpenGL 3.3 is not supported, éventuellement suivi d’une erreur de segmentation) ;

  • ou fonctionnement apparent mais lidar en retard : le repli logiciel est trop lent, les balayages sont horodatés en deçà de /clock et ne peuvent plus être appariés à une pose. Le SLAM échoue alors sans message explicite (« Failed to compute odom pose », « No map received »).

Note

Pour une carte NVIDIA, --device /dev/dri est insuffisant : les bibliothèques NVIDIA doivent être présentes dans le conteneur, ce que fournit le nvidia-container-toolkit.

Prérequis : pilote NVIDIA fonctionnel sur l’hôte (nvidia-smi). Installation du toolkit, sur l’hôte, une fois :

sudo apt-get install -y --no-install-recommends ca-certificates curl gnupg
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
  | sudo gpg --dearmor --yes -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -sL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

Le compose.yaml réserve déjà le GPU et fixe NVIDIA_DRIVER_CAPABILITIES=all — la valeur par défaut utility,compute n’expose pas OpenGL.

Astuce

Sans GPU NVIDIA, le rendu logiciel (Mesa/llvmpipe) permet de dépanner mais reste insuffisant pour le SLAM. Les avertissements libEGL warning isolés sont sans conséquence si le reste fonctionne.

Divers

La distribution ROS 2 est paramétrée par ROS_DISTRO (humble par défaut), modifiable dans compose.yaml ; reconstruire ensuite l’image (docker compose build).

Suppression complète, image comprise (le code, monté depuis l’hôte, n’est pas affecté) :

docker compose down --rmi all

Une manette de jeu doit être connectée avant le démarrage du conteneur pour être visible (La simulation en détail).