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 |
Action |
|---|---|
|
Nouvelle fenêtre |
|
Fenêtre suivante / précédente |
|
Accès direct à une fenêtre |
|
Partage vertical de l’écran, changement de zone |
|
Détachement : retour à un shell simple, |
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
/clocket 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).