La simulation en détail ======================= **S'applique à :** :bdg-info-line:`Simulation` Le RatBot se simule à deux niveaux : - **Gazebo** — simulation physique : masse, adhérence, collisions, capteurs (lidar, centrale inertielle, batterie) ; - **RViz** — visualiseur : il ne simule rien et affiche l'état estimé par le robot (voir :doc:`rviz`). Le premier lancement est décrit dans :doc:`demarrage`. Cette page détaille les options de la simulation, les décors fournis et la notion de vérité terrain. Visualisation du modèle ----------------------- Affichage du modèle 3D sans simulation physique : .. code-block:: bash ros2 launch ratbot_description display.launch.py ros2 launch ratbot_description display.launch.py use_lidar:=false RViz s'ouvre avec le robot et une interface ``joint_state_publisher_gui`` permettant d'actionner les articulations manuellement. Utile pour vérifier des dimensions ou le placement d'un capteur. .. image:: _static/simulation/rviz-modele.png :align: center :width: 90% Simulation physique ------------------- La façon la plus simple de lancer la simulation, depuis la racine du dépôt : .. code-block:: bash ./scripts/ratbot up # décor par défaut, un robot ./scripts/ratbot up rooms # le décor « rooms » ./scripts/ratbot up hampton_simple 3 # trois robots dans ce décor ./scripts/ratbot up --list # les décors disponibles Le **décor** se donne par son nom ; ``--list`` affiche ceux qui sont installés, avec le nombre de robots que chacun accueille. Le **nombre de robots** va de 1 à 4 : chaque décor déclare ses propres places de départ, et les robots y sont posés automatiquement (voir **Ajouter un décor**, plus bas). Les robots sont numérotés à partir de 1. ``ratbot up`` lance la simulation **avec la vérité terrain**, et rappelle à chaque lancement comment s'en passer pour cartographier ou naviguer (voir **La vérité terrain**, plus bas). Tout argument ``nom:=valeur`` ajouté en fin de commande est transmis au lanceur : ``./scripts/ratbot up rooms 2 rviz:=true``. Le lanceur s'utilise aussi directement : .. code-block:: bash ros2 launch ratbot_gazebo gazebo.launch.py robots:=2 rviz:=true \ world:=$(ros2 pkg prefix ratbot_gazebo)/share/ratbot_gazebo/worlds/rooms.sdf Ses arguments, combinables : .. list-table:: :header-rows: 1 :widths: 22 18 60 * - Argument - Défaut - Rôle * - ``world`` - ``ratbot_lab.sdf`` - Fichier de décor (``.sdf``), avec son chemin complet. * - ``robots`` - ``1`` - Nombre de robots, de 1 à 4, posés sur les places de départ du décor. * - ``robot_id`` - ``1`` - Numéro du premier robot ; les suivants sont numérotés à la suite. * - ``x``, ``y`` - — - Déplacent le **premier** robot, au lieu de sa place de départ. * - ``rviz`` - ``false`` - Démarre également RViz, préconfiguré pour la simulation. * - ``use_lidar`` - ``true`` - Inclut le lidar dans le modèle et le pont de capteurs. * - ``use_tof`` - ``true`` - Inclut le capteur de distance avant et sa simulation (:doc:`tof`). * - ``screen`` - ``false`` - Ouvre l'**écran** de chaque robot : une fenêtre avec l'afficheur 128 × 64 et ses six boutons cliquables (haut, bas, gauche, droite, OK, ESC), qui ouvrent et parcourent le menu (voir l'image plus bas). * - ``gui`` - ``true`` - Fenêtre 3D de Gazebo. ``false`` bascule en rendu hors écran : allège la charge GPU, au bénéfice du lidar simulé. L'écran (``screen``) n'ouvre alors pas de fenêtre non plus. * - ``ground_truth_tf`` - ``true`` - Publie la vérité terrain. **À passer à** ``false`` pour la cartographie, la navigation et l'exploration (voir plus bas). * - ``use_ekf`` - ``true`` - Fusionne odométrie et centrale inertielle, comme sur le robot réel. .. image:: _static/simulation/gazebo-physique.png :align: center :width: 90% Dans Gazebo, le robot est représenté par des **formes simples** (boîtes et cylindres aux dimensions réelles) ; RViz affiche sa maquette 3D. Le lidar simulé se heurtait à la maquette, qui dépasse son plan de balayage. Avec ``screen:=true``, chaque robot a sa fenêtre d'écran. Ci-dessous, ``./scripts/ratbot up rooms 2 screen:=true`` : les écrans des deux robots, et Gazebo à droite. Sous les six boutons de navigation, la fenêtre reproduit aussi les quatre interrupteurs (SW1 à SW4) et les quatre voyants (LED1 à LED4) de la carte du robot. .. image:: _static/simulation/ecrans-deux-robots.png :align: center :width: 100% Décors fournis -------------- Tous les décors sont **fermés** : leur contour est scellé, sans ouverture. Une ouverture conduirait le lidar à mesurer vers l'extérieur et le SLAM à cartographier un espace non borné. ``hampton_simple.sdf`` Labyrinthe (~17 × 10 m) inspiré de Hampton Court, **sans aucune boucle** : chaque couloir annulaire est coupé par un mur radial, l'espace libre forme donc un arbre. Le robot revient sur ses pas plutôt que de tourner en rond, ce qui supprime les fermetures de boucle ambiguës. Couloirs de 1,7 m et cour de départ de 5 × 6 m, dimensionnée pour quatre robots. **Décor recommandé pour une première cartographie.** ``hampton_signature.sdf`` Labyrinthe compact (~6 × 3,6 m), couloirs de 0,6 m. Ses trois anneaux concentriques forment autant de boucles : décor utile pour observer les limites du SLAM, mais peu adapté à une première prise en main. ``hampton_full.sdf`` Version étendue (~8,4 × 5 m), parcours plus long. ``rooms.sdf`` Bâtiment de 6 × 4 m : couloir central, pièces de tailles différentes reliées par des portes de 0,8 m, pilier. Volontairement asymétrique, ce qui limite les ambiguïtés perceptuelles — décor recommandé pour la navigation et l'exploration. ``tables.sdf`` Pièce de 5 × 4 m et deux tables à **pied central**, l'une à pied en croix (branches de 4 cm de haut), l'autre à socle en disque (3 cm). Le lidar voit leurs colonnes, pas leurs pieds : décor d'essai du capteur de distance avant (:doc:`tof`). Sa carte, ``tables.yaml``, est dessinée d'après le plan et ne contient, comme le verrait le lidar, que les murs et les colonnes. ``enclos.sdf`` Enclos de planches de 2 × 1 m à l'intérieur (planches de 30 cm de haut, blanc brillant), le robot au départ à 30 cm de la planche du fond. C'est la copie de l'enclos du premier essai sur le robot réel : les mêmes épreuves s'y font en simulation et en vrai. Dimensions prévues, à corriger d'après l'enclos réel. ``lisv.sdf`` Le laboratoire LISV en entier (34 × 38 m) : couloirs, bureaux, salles, 50 portes et les fenêtres des murs extérieurs. Le décor est **construit d'après le plan DXF du laboratoire** (``worlds/lisv.dxf``), et sa carte, ``lisv.yaml``, d'après ce décor. Les robots démarrent dans le grand couloir. Pièces sans porte ou derrière une porte fermée : grises, inconnues sur la carte. Décor d'essai de la navigation avant le vrai laboratoire. .. code-block:: bash ./scripts/ratbot up rooms rviz:=true Dans RViz, les mesures lidar doivent coïncider avec les murs. Un décalage ou un retard indique un problème d'accès GPU (:doc:`docker`). .. image:: _static/simulation/hampton-rviz-scan.png :align: center :width: 90% Ajouter un décor ---------------- Un décor est un fichier SDF, le format de Gazebo. Pour en ajouter un : 1. le déposer dans ``ros2_ws/src/ratbot_gazebo/worlds/``, par exemple ``salle.sdf`` ; 2. pour y poser **plusieurs robots**, lui adjoindre un fichier ``salle.spawn.yaml`` qui liste ses places de départ, dans l'ordre des robots — quatre au plus : .. code-block:: yaml spawn: - {x: 0.0, y: 0.0, yaw: 0.0} # robot 1 - {x: 0.6, y: 0.0, yaw: 0.0} # robot 2 - {x: 0.0, y: 0.6, yaw: 0.0} # robot 3 ``x`` et ``y`` en mètres, ``yaw`` en radians (0 : face à l'axe x). Choisissez des places à au moins **30 cm** de tout mur et **60 cm** l'une de l'autre. Sans ce fichier, le décor n'accueille qu'un robot, posé à l'origine ; 3. recompiler la simulation : ``./scripts/ratbot build`` ; 4. pour y **naviguer**, lui donner une carte. Plutôt qu'une cartographie, la dessiner d'après son plan — exacte, et ce que verrait le lidar : .. code-block:: bash cd ros2_ws/src/ratbot_gazebo python3 -m ratbot_gazebo.world_map worlds/salle.sdf ../ratbot_maps/maps/salle La carte prend le nom du décor : ``ratbot nav 1``, en simulation, la charge seule. Le décor doit être fermé, sinon l'outil refuse. Le décor apparaît alors dans ``./scripts/ratbot up --list``. Un décor doit être **fermé**, sans ouverture vers l'extérieur : sinon le lidar mesure dans le vide, et la cartographie s'étend sans limite. La vérité terrain : ``ground_truth_tf`` --------------------------------------- La position du robot est décrite par une chaîne de transformations entre repères : :: map ─────────────► odom ─────────────► base_footprint correction odométrie (cartographie / (roues + gyroscope) localisation) ``odom → base_footprint`` vient de l'odométrie : continue et précise à court terme, mais sujette à une dérive qui s'accumule. ``map → odom`` corrige cette dérive en recalant les mesures du lidar ; elle est publiée par la cartographie, ou par la localisation en navigation. Un repère ne peut avoir **qu'un seul parent**. Or, par défaut, la simulation publie en plus la position **exacte** du robot — la *vérité terrain*, que seul un simulateur connaît — sous forme d'une transformation vers ``odom``. Elle entre alors en conflit avec celle de la cartographie ou de la localisation : les deux se contredisent, et la localisation échoue. ``ground_truth_tf:=false`` supprime la transformation de vérité terrain. Cette option est **obligatoire** pour la cartographie, la navigation et l'exploration ; l'oublier est l'erreur la plus fréquente. Quand la garder, quand l'enlever ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 40 60 * - Usage - Vérité terrain * - regarder les robots dans RViz, les piloter, comparer leur position estimée à la vraie - **activée** — c'est le seul repère commun à tous les robots ; sans elle, RViz n'en affiche aucun tant que la cartographie ou la localisation n'a pas démarré * - cartographier, naviguer, explorer - **désactivée** — sinon elle contredit la position calculée par la cartographie ou la localisation ``./scripts/ratbot up`` l'**active** par défaut. Pour la désactiver, l'ajouter en fin de commande : .. code-block:: bash ./scripts/ratbot up rooms 2 ground_truth_tf:=false Elle se choisit **au lancement de la simulation** : pour passer d'un usage à l'autre, arrêter la simulation (``Ctrl+C``) et la relancer. Simulation et robots réels : le domaine ROS ------------------------------------------- Le PC (``~/.bashrc``) comme le conteneur Docker (``compose.yaml``) sont réglés sur le domaine **77**, celui des robots réels. Une simulation qui y démarre pendant que des robots sont allumés porterait les mêmes noms qu'eux (``ratbot_1``…) : leurs topics se mélangeraient, et des ordres destinés au robot simulé pourraient atteindre le vrai. ``./scripts/ratbot up`` écoute donc le domaine 77 pendant deux secondes avant de démarrer. Si un robot y répond, il refuse : .. code-block:: text /!\ domaine 77 : des robots repondent deja (ratbot_1) /!\ une simulation porterait les memes noms et s'y melangerait ==> pour simuler a cote, dans un autre domaine : ==> ROS_DOMAIN_ID=0 ./scripts/ratbot up rooms 2 Pour simuler pendant que des robots tournent, passer **chaque terminal** de la simulation (lancement, pilotage, RViz, cartographie) dans un autre domaine : .. code-block:: bash export ROS_DOMAIN_ID=0 Piloter, plusieurs robots, arrêter ---------------------------------- Ces sujets sont communs à la simulation et au robot réel : voir :doc:`pilotage`, :doc:`flotte` et :doc:`arrets`.