Faire une carte =============== **S'applique à :** :bdg-info-line:`Simulation` :bdg-warning-line:`Robot réel` Pour naviguer seul, le robot a besoin d'une **carte** du lieu : une image vue de dessus, où le noir est un obstacle, le blanc un espace libre et le gris l'inconnu. On la construit **une fois**, en promenant le robot pendant que son lidar balaie les lieux ; on l'enregistre ensuite pour la navigation (voir :doc:`navigation`). Le principe ----------- La cartographie résout deux problèmes à la fois — d'où son nom anglais de **SLAM**, *Simultaneous Localization And Mapping* : placer les obstacles sur la carte suppose de savoir d'où on les a vus, et savoir où l'on est suppose une carte. Le logiciel (``slam_toolbox``) procède pas à pas. L'odométrie donne une première estimation du déplacement ; chaque balayage du lidar est ensuite recalé sur la carte déjà construite, ce qui corrige l'estimation et ajoute les nouvelles mesures. Lorsque le robot revient dans une zone déjà vue, une **fermeture de boucle** répartit l'erreur accumulée sur tout le trajet. Ce qu'il vous faut ------------------ .. tab-set:: :sync-group: env .. tab-item:: Simulation :sync: sim - le PC prêt (:doc:`installation`) ; - le clavier ou une manette (voir :doc:`pilotage`). .. tab-item:: Robot réel :sync: reel - le robot **chargé**, allumé et prêt (voyant bleu), le **ST-Link débranché** ; - son lidar **vérifié** (voir :doc:`lidar`) : un lidar mal déclaré construit une carte à l'envers ; - le **PC**, sur le même réseau que le robot, avec la **manette** branchée (voir :doc:`pilotage`) ; - un morceau de **ruban adhésif** pour marquer le départ ; - une dizaine de minutes pour une pièce, préparation comprise. 1. Préparer ----------- .. tab-set:: :sync-group: env .. tab-item:: Simulation :sync: sim Choisissez un **décor** (voir :doc:`simulation`). Pour une première carte, ``hampton_simple.sdf`` est le plus facile : un labyrinthe sans boucle, aux couloirs larges. Lancez la simulation **sans vérité terrain** — l'option ``ground_truth_tf:=false`` est **obligatoire** pour cartographier (voir :doc:`simulation`) : .. code-block:: bash ./scripts/ratbot up hampton_simple ground_truth_tf:=false .. tab-item:: Robot réel :sync: reel **Préparez la pièce.** La carte fige ce que le lidar voit pendant la promenade : - **dégagez le sol** : le lidar balaie à un peu moins de 25 cm du sol et ne voit **ni** une chaussure, **ni** un câble, **ni** un objet bas. Ce qui reste sera aussi invisible pour la navigation ; - **écartez les meubles à pieds fins** — chaises, tables, lampadaires — ou rangez-les contre un mur. Le lidar fait un point par degré : à 2 m, deux points voisins sont à 3,5 cm l'un de l'autre, et un pied de 2 cm passe **entre deux rayons**. Il n'apparaît que par moments, ou pas du tout ; - **décidez des portes** : ouvertes ou fermées, elles resteront ainsi sur la carte ; - **que personne ne circule** dans la pièce : une jambe qui passe laisse une trace ; - les **miroirs, vitres et surfaces noires brillantes** renvoient mal le faisceau : attendez-vous à des trous à ces endroits. **Marquez le départ.** La carte prend pour origine la position du robot au lancement, et la navigation supposera plus tard qu'il y démarre. Posez le robot à son point de départ, et marquez au sol, au ruban, **l'emplacement des deux roues et le sens de l'avant** : vous pourrez le reposer exactement là. 2. Lancer la cartographie ------------------------- .. tab-set:: :sync-group: env .. tab-item:: Simulation :sync: sim La manette dans un deuxième terminal : .. code-block:: bash ./scripts/ratbot joy La cartographie dans un troisième : .. code-block:: bash ./scripts/ratbot slam 1 La commande vérifie que le robot est visible, reconnaît la simulation, puis ouvre RViz. La carte a pour origine la place de départ du robot dans le décor. Si la simulation a été lancée **avec** la vérité terrain, la commande refuse et rappelle l'option ``ground_truth_tf:=false``. .. tab-item:: Robot réel :sync: reel Sur le PC, la manette dans un terminal : .. code-block:: bash ./scripts/ratbot joy La cartographie dans un autre : .. code-block:: bash cd ~/ratbot_ws ./scripts/ratbot slam 1 La commande vérifie que le robot est visible, **remet son odométrie à zéro** — c'est ce qui fait du point de départ l'origine de la carte —, puis ouvre RViz. **Ne bougez pas le robot** avant que RViz soit ouvert. RViz s'ouvre et montre, robot immobile, les **points du lidar** qui dessinent les murs autour du robot, et la **carte** qui commence à se remplir autour de lui (voir :doc:`rviz`). .. Capture d'écran à insérer : RViz pendant la cartographie, la carte en train de se dessiner. Déposez _static/carte/slam-en-cours.png puis décommentez le bloc ci-dessous (retirez le préfixe « .. ») : .. .. image:: _static/carte/slam-en-cours.png .. :align: center .. :width: 90% 3. Promener le robot -------------------- **Roulez lentement**, surtout en tournant : si le robot se déplace trop entre deux balayages, ceux-ci ne se recouvrent plus assez pour être recalés, et les murs se dédoublent. Sur le robot réel, dont le lidar ne fait que 6,5 tours par seconde, **tenez L1 seul** — la vitesse lente — et n'appuyez pas sur CARRÉ. En conduisant, regardez RViz : - **longez les murs**, à 30 cm à 1 m, plutôt que le milieu de la pièce : le lidar voit mieux ce qui est proche ; - **tournez lentement**, de préférence en avançant un peu plutôt que sur place ; - **faites le tour complet**, puis **revenez au départ** en repassant par des endroits déjà vus : c'est ce retour qui ferme la boucle et corrige la dérive ; - passez derrière les meubles et dans les recoins : ce qui reste **gris** est inconnu, et la navigation l'évitera. Les murs doivent rester **fins et nets**. S'ils se dédoublent ou s'épaississent, arrêtez-vous, puis revenez **lentement** vers une zone déjà bien cartographiée : le logiciel se recale souvent de lui-même. 4. Enregistrer -------------- **Sans arrêter la cartographie**, dans un nouveau terminal, depuis la racine du dépôt : .. code-block:: bash ./scripts/ratbot map save 1 salon Un **simple nom** range la carte avec celles du dépôt, dans ``ros2_ws/src/ratbot_maps/maps/`` : elle sert aussitôt à la navigation, sans recompiler, depuis le PC comme depuis le conteneur Docker. Nommez-la d'après le **lieu** : la pièce pour un robot réel, le nom du décor en simulation — ``./scripts/ratbot nav 1`` charge alors seule la carte du décor en cours (voir :doc:`navigation`). ``./scripts/ratbot map list`` affiche les cartes du dépôt. Celles qui sont fournies avec lui, comme ``rooms``, ne peuvent pas être écrasées. Un chemin complet, avec un ``/``, enregistre ailleurs. Deux fichiers sont écrits : - ``.pgm`` : l'image de la carte, en niveaux de gris (noir : obstacle, blanc : libre, gris : inconnu) ; - ``.yaml`` : sa description — taille d'un pixel (5 cm), position de l'origine, seuils d'occupation. Gardez-les ensemble, **sans renommer l'un sans l'autre** : le ``.yaml`` désigne le ``.pgm`` par son nom. La cartographie peut ensuite être arrêtée (``Ctrl+C``). 5. Vérifier la carte -------------------- Ouvrez le ``.pgm`` avec un visualiseur d'images. Une bonne carte a : - des **murs droits**, d'un seul trait, qui se **referment** : pas de mur en double, pas de pièce « ouverte » là où il n'y a pas de passage ; - des **angles droits** là où le lieu en a ; - le moins de **gris** possible dans les zones où le robot devra circuler. Une carte ratée ne se répare pas : **refaites-la**, plus lentement, en fermant mieux la boucle. .. Capture d'écran à insérer : une carte réussie et une carte ratée (murs dédoublés), côte à côte. Déposez _static/carte/bonne-et-ratee.png puis décommentez le bloc ci-dessous (retirez le préfixe « .. ») : .. .. image:: _static/carte/bonne-et-ratee.png .. :align: center .. :width: 90% Plusieurs robots à la fois -------------------------- Chaque robot a sa propre cartographie : une commande ``slam`` par robot, dans des terminaux séparés. Chacune ouvre sa fenêtre RViz, dont la barre de titre porte le numéro du robot (``ratbot_2_slam.rviz``), et publie sa carte sur ``/ratbot_N/map``. On enregistre chaque carte avec le numéro de son robot : .. code-block:: bash ./scripts/ratbot map save 1 salon_robot1 ./scripts/ratbot map save 2 salon_robot2 Les cartes restent séparées : chacune a pour origine le point de départ de son robot. Leur fusion en une carte commune n'est pas encore disponible. Reprendre une carte plus tard ----------------------------- L'image ``.pgm`` ne suffit pas pour **reprendre ou agrandir** une carte. Il faut pour cela enregistrer aussi le travail interne de la cartographie, pendant qu'elle tourne : .. code-block:: bash ros2 service call /ratbot_1/slam_toolbox/serialize_map \ slam_toolbox/srv/SerializePoseGraph "{filename: '$HOME/cartes/salon'}" Et ensuite ---------- - :doc:`navigation` — faire naviguer le robot sur cette carte : **reposez-le d'abord sur son marquage de départ** ; - :doc:`exploration` — laisser le robot cartographier seul. En cas de souci --------------- **« robot 1 introuvable »** Le robot n'est pas allumé, pas sur le même réseau, ou le PC n'est pas dans le domaine ROS 77 (``echo $ROS_DOMAIN_ID``). **Le robot ne bouge pas** Gâchette L1 tenue ? Manette en mode PlayStation (LED bleue) ? Voyant du robot bleu, et non orange ou rouge (voir :doc:`arrets`) ? **RViz s'ouvre, mais pas de carte** La carte n'apparaît qu'après le premier balayage traité : attendre quelques secondes. Sinon, vérifier dans RViz le repère de référence (*Fixed Frame* ``ratbot_1/map``) et le topic de l'affichage *Map* (``/ratbot_1/map``). **Les murs se dédoublent** Trop vite, surtout en rotation : ralentir, revenir sur une zone connue. Si les murs se dédoublent **dès le premier virage**, même lentement, le lidar est peut-être mal déclaré (voir :doc:`lidar`). Dans un labyrinthe très symétrique, deux couloirs identiques peuvent aussi être confondus : c'est une limite de la cartographie au lidar, pas un défaut. **Le robot s'arrête en orange** Une sécurité s'est déclenchée — choc contre un meuble, patinage, blocage. Réarmer (voir :doc:`arrets`), puis reprendre : la cartographie continue, inutile de la relancer. **En simulation, Gazebo instable ou lidar en retard** Accès à la carte graphique manquant dans le conteneur : les balayages arrivent trop tard pour être recalés, et la cartographie échoue sans message clair. Voir :doc:`docker`.