Créer votre première map avec slam_toolbox – French ROS2 Tutorial

Créer votre première map avec slam_toolbox – French ROS2 Tutorial


Cours: ROS2 Basics in 5 Days C++: https://app.theconstructsim.com/courses/133

Le but de ce tutoriel est d’apprendre à utiliser slam_toolbox pour créer des maps, les sauvegarder et les réutiliser avec map_server. slam_toolbox est un package regroupant un ensemble d’outils pour la localisation et la cartographie simultanées (SLAM) en robotique, permettant la création de cartes en temps réel et le suivi de la position. La cartographie est essentielle en robotique pour la navigation, la planification efficace de la trajectoire et l’évitement des obstacles. Elle améliore l’autonomie et la précision des robots dans les environnements dynamiques.

Prérequis: Utiliser une installation ROS2 avec Gazebo, turtlebot3 et slam_toolbox

Installation ROS2

Vous pouvez vous connecter au site TheConstruct pour accéder à des machines virtuelles préconfigurées avec une installation ROS2. Pour lancer et tester le code, vous devez lancer la simulation du turtlebot3 sur gazebo. Pour faire cela, entez les commandes suivantes dans le terminal:

# Declare le model de turtlebot3 à simuler
export TURTLEBOT3_MODEL=waffle_pi
# Lance la simulation du turtlebot dans gazebo
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

Une fois la simulation du turtlebot3 lancée, celle-ci va publier les tf du turtlebot3 et les données obtenues avec son laserscan sur le topic /scan que nous allons utiliser durant le tutoriel. Après avoir exécuté ces commandes, appuyez sur le bouton de l’interface gazebo et sélectionnez Open Gazebo.

Vous devriez obtenir le résultat suivant:
alternative text
Si vous voulez effectuer le tutoriel sur votre installation local, vous devez avoir ROS2 installé (https://docs.ros.org/en/humble/Installation.html), avoir configuré un workspace (https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html) et avoir installé le turtlebot3.
# pour installer tous les packages du turtlebot3
# remplacez humble par votre distro ROS2cd ~/ros2_ws
sudo apt-get install ros-humble-turtlebot3*
# n'oubliez pas d'exporter le modèle de Turtlebot3 que vous souhaitez utiliser
export TURTLEBOT3_MODEL=waffle_pi

Installer slam_toolbox

Vous pouvez installer slam_toolbox avec la commande suivante:

# Pour install slam_toolbox
sudo apt-get install ros-humble-slam-toolbox

Partie 1: Configurer son package

Nous allons commencer par créer un package ROS2 pour stocker les fichiers launch et yaml necessaires:

cd ros2_ws/src/
# Créer le package
ros2 pkg create slam_setup_tutorial
cd slam_setup_tutorial
# Créer les dossiers pour stocker les launch et params files
mkdir launch
mkdir params

Nous allons maintenant éditer le Cmakelist.txt:

cmake_minimum_required(VERSION 3.8)
project(slam_setup_tutorial)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)

# On declare les dossiers launch et params dans les installs
install(DIRECTORY
  launch
  params
  DESTINATION share/${PROJECT_NAME}/
)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

Vous pouvez build votre workspace pour verifier si la configuration du CmakeList.txt fonctionne:

cd ~/ros2_ws
colcon build
source install/setup.bash

Partie 2: Setup slam_toolbox

Les maps générées par slam_toolbox sont au format “occupancy grid”. Ce format représente l’environnement en une grille régulière de cellules, où chaque cellule correspond à une petite zone de l’espace. Voici une map au format occupancy grid:

image pgm map

  • Résolution : La résolution de la carte indique la taille de chaque cellule en mètres par pixel.
  • Valeurs des cellules : Chaque cellule de la grille contient une valeur indiquant le niveau d’occupation :
    • 0 représente un espace libre (en blanc sur la représentation de la map).
    • 100 représente un obstacle (en noir).
    • -1 indique une cellule inconnue ou non explorée (en gris).
  • TF de référence : La carte est associée à un transform de référence global, souvent nommé “map”, qui permet de situer les cellules dans l’espace réel. Cette représentation permet aux robots de naviguer et de planifier des trajectoires en évitant les obstacles et en se déplaçant à travers les espaces libres détectés par leurs capteurs.

Pour pouvoir utiliser slam_toolbox, les tf du robot doivent être configurées en respectant les conventions du REP105 : Coordinate Frames for Mobile Platforms. Une explication plus pratique de cette configuration est décrite dans la documentation de Nav2 sur la configuration des transforms. Ces notions sont paraticulièrement importantes si vous voulez effectuer du slam sur un robot custom. Dans ce tutoriel nous allons utiliser le turtlebot3 qui possède déjà une implementation compléte de ses TF locales. Vous pouvez visuliser le TF tree du robot en appelant le node view_frames du package tf2_tools:

ros2 run tf2_tools view_frames

Ce node va génerer deux fichiers à l’emplacement où vous avez executé la commande: frames_date_hour.pdf and frames_date_hour.gv. En ouvrant le fichier pdf, vous pourrez voir le tf tree du turtlebot3 executé en simulation:

Robot tf_tree

Vous devriez avoir les frames suivantes:

  • La frame odom est la frame de réference pour la localisation locale du robot.
  • La frame base_link represente la frame principale du robot, c’est relativement à celle ci que les differentes treansforms des capteurs et autres links du robot sont déclarées.
  • Les frames des differents capteurs définis relativement à base_link

Le package slam_toolbox va generer une nouvelle frame map qui va servir de réference globale pour la localisation du robot par rapport à l’espace. Si la localisation du robot dans la frame odom est sujet à une dérive et une accumulation d’erreurs à cause de la nature de ses capteurs (odometry visuelle ou via roues codeuses, accélerometre) qui ne possède que des informations relatives, la localisation du robot dans la frame map va souvent être effectuée avec la fusion des sources de localisations “globales”. Dans le cas des robots d’exterieurs, le GPS fait souvent office de reference globale. Pour les robots d’interieurs les lidars vont souvent fournir cette information.

Nous allons utiliser le package crée dans la partie précedante. On va d’abord créer le fichier yaml qui va contenir les parametres pour slam_toolbox:

cd ~/ros2_ws/src/slam_setup_tutorial/
cd params
touch slam_toolbox_params.yaml

Une fois le fichier créer, ouvrez le dans votre éditeur de code et copiez y la configuration suivante:

slam_toolbox:
  ros__parameters:
    # Le robot est lancé en simulation, synchroniser le temps du robot avec la clock de la simulation
    use_sim_time: true
    # Fréquence de mise à jour du SLAM en Hz
    update_rate: 1.0
    # Période de publication de la carte en secondes
    publish_period: 0.1
    # Résolution de la carte créée, en mètres/pixel
    resolution: 0.05
    # Portée maximale considérée pour les valeurs du laser scan
    max_laser_range: 8.0
    # Topic sur lequel le robot publie les données du laser scan
    scan_topic: /scan
    # Frame de référence pour la localisation locale (souvent "odom" par convention)
    odom_frame: odom
    # Frame de référence attachée au robot (souvent "base_link" par convention)
    base_frame: base_link
    # Mode d'opération de slam_toolbox (mapping ou localisation)
    mode: mapping
    # Activer les logs de debug
    debug_logging: true

    # Intervalle de mise à jour de la carte en secondes
    map_update_interval: 5.0
    # Seuil maximal d'occupation pour considérer une cellule comme occupée
    max_occupied_threshold: 0.65
    # Seuil minimal pour considérer une cellule comme libre
    min_free_threshold: 0.196
    # Intervalle de temps minimal entre deux mises à jour de pose en secondes
    minimum_time_interval: 0.5
    # Période de publication des transformations en secondes
    transform_publish_period: 0.02
    # Distance minimale parcourue pour déclencher une mise à jour en mètres
    linear_update: 0.1
    # Rotation minimale effectuée pour déclencher une mise à jour en radians
    angular_update: 0.1
    # Taille du buffer pour les scans laser
    scan_buffer_size: 10
    # Distance maximale des scans stockés dans le buffer en mètres
    scan_buffer_maximum_scan_distance: 8.0
    # Timeout pour la recherche de transformation en secondes
    lookup_transform_timeout_sec: 0.5
    submap:
      # Nombre de cellules dans chaque sous-carte
      number_of_cells: 3500

Cette configuration est adaptée pour le turtlebot3 dans un environemment indoor, pour des en fonction des contraintes de votre plateforme (capteurs, puissance de calcul…) vous devrez optimiser les parametres. Tous les parametres du node slam_toolbox sont listés sur la documentation que vous pouvez trouver ici. Maintenant que nous avons les parametres, nous devons écrire un launch file pour executer le node:

cd ~/ros2_ws/src/slam_setup_tutorial/
cd launch
touch start_slam_toolbox.launch.py
import os

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import (DeclareLaunchArgument)
from launch.substitutions import (LaunchConfiguration)
from launch_ros.actions import LifecycleNode

def generate_launch_description():
    use_sim_time = LaunchConfiguration('use_sim_time')
    slam_params_file = LaunchConfiguration('slam_params_file')

    declare_use_sim_time_argument = DeclareLaunchArgument(
        'use_sim_time',
        default_value='true',
        description='Use simulation/Gazebo clock')
    # Déclare comme parametre le fichier yaml que nous avons créé precedemment
    declare_slam_params_file_cmd = DeclareLaunchArgument(
        'slam_params_file',
        default_value=os.path.join(get_package_share_directory("slam_setup_tutorial"),
                                   'params', 'slam_toolbox_param.yaml'),
        description='Full path to the ROS2 parameters file to use for the slam_toolbox node')

    # Déclare le node slam_toolbox
    start_async_slam_toolbox_node = LifecycleNode(
        parameters=[
          slam_params_file,
          {
            'use_sim_time': use_sim_time
          }
        ],
        package='slam_toolbox',
        executable='async_slam_toolbox_node',
        name='slam_toolbox',
        output='screen',
        namespace=''
    )

    ld = LaunchDescription()
    ld.add_action(declare_use_sim_time_argument)
    ld.add_action(declare_slam_params_file_cmd)
    ld.add_action(start_async_slam_toolbox_node)

    return ld

On peut maintenant compiler le package avec les commandes suivantes:

cd ~/ros2_ws
colcon build --symlink-install
source install/setup.bash

Vous pouvez maintenant lancer le node avec la commande suivante:

ros2 launch slam_setup_tutorial start_slam_toolbox.launch.py

Vous pouvez ouvrir rviz2 avec le fichier à la racine du projet avec la commande suivant:

rviz2 -d ~/ros2_ws/slam_toolbox_rviz_config.rviz

En ouvrant rviz2 avec la configuration à la racine du tutoriel vous devriez avoir ce visuel:

Image de map incomplete dans rviz

Le robot peut commencer à mapper son environnement en utilisant sa localisation et les valeurs de ses données, c’est ce cycle de localization couplé au mapping que l’on appelle SLAM (Simultaneous Localization And Mapping). Le node de slam_toolbox publie également la tf map utilisée pour la référence de localisation globale qui est une frame parente de la frame odom:

Image tf tree avec la frame map

Partie 3: Sauvegarder la map et la réutiliser

Maintenant que l’on a démarré slam_toolbox, on peut effectuer le mapping de la zone. Pour faire cela vous devez déplacer le robot pour lui permettre de mapper toute la zone. Vous pouvez téléopérer le robot avec la commande suivante:

ros2 run turtlebot3_teleop teleop_keyboard

Une fois la zone totalement explorée par le robot, vous devriez avoir le résultat suivant dans rviz2:

map dans rviz2 completée

Maintenant que nous avons mapper la zone, la prochaine étape est de sauvegarder cette carte pour pouvoir la réutiliser. Pour sauvegarder la carte, vous pouvez appeler le service /slam_toolbox/save_map qui est une wrapper simplifié de map_saver en effectuant la commande suivante:

ros2 service call /slam_toolbox/save_map slam_toolbox/srv/SaveMap "name: {data: 'my_map'}"

Cette commande subscribe sur le topic map et crée des fichiers my_map.pgm et my_map.yaml qui vont être utilisé pour décrire notre map. Le fichier my_map.pgm est une image qui représente l’environnement:

image pgm map

Le fichier my_map.yaml est le fichier de configuration suivant:

# Fichier de l'image de la map
image: my_map.pgm
mode: trinary
# Resolution de la carte en metre/pixel
resolution: 0.05
# origin de la carte dans le referentiel de la frame map
origin: [-2.95, -2.58, 0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25

Maintenant que notre map est sauvegardée, nous pouvons la republier sur le topic map en utilisant le node map_server. Ce node va cette fois publier la map comme une static map, les points du laserscan ne vont plus mettre à jour la carte. Pour localiser le robot sur cette carte déjà crée, nous allons utiliser le package AMCL pour localiser le robot par rapport à la static map et à publier la map frame à la place slam_toolbox. Le package amcl (Adaptive Monte Carlo Localization) permet à un robot de se localiser dans un environnement connu. Voici comment il fonctionne :

  • Initialisation : Utilise une carte déjà définie comme celle que nous avons créé avec slam_toolbox.
  • Particules : Génère des hypothèses de pose (position + orientation) sous forme de particules.
  • Mise à jour des capteurs : Compare les mesures des capteurs (lidar) avec la carte pour évaluer la pertinence des particules.
  • Resampling : Renforce les particules pertinentes et élimine les autres pour affiner la position estimée.
  • Estimation de la position : Calcule la position moyenne pondérée des particules.
  • Boucle continue : Répète ce processus pour une localisation précise et continue. amcl utilise des fitres à particules et des données de capteurs pour localiser un robot sur une carte connue.

Vous pouvez utiliser lancer le node map_server et amcl avec le fichier launch suivant:

cd ~/ros2_ws/src/slam_setup_tutorial/
cd launch
touch start_map_server_amcl.launch.py
import os

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node


def generate_launch_description():

    map_file = os.path.join(get_package_share_directory(
        'slam_setup_tutorial'), 'params', 'my_map.yaml')
    
    amcl_file = os.path.join(get_package_share_directory(
        'slam_setup_tutorial'), 'params', 'amcl.yaml')

    return LaunchDescription([
        Node(
            package='nav2_map_server',
            executable='map_server',
            name='map_server',
            output='screen',
            parameters=[{'use_sim_time': True},
                        {'yaml_filename': map_file}]
        ),
        Node(
                package='nav2_amcl',
                executable='amcl',
                name='amcl',
                parameters=[amcl_file],
        ),
        Node(
            package='nav2_lifecycle_manager',
            executable='lifecycle_manager',
            name='lifecycle_manager_localization',
            output='screen',
            parameters=[{'use_sim_time': True},
                        {'autostart': True},
                        {'node_names': ['amcl','map_server']}]
        )
    ])

Il faut également créer le fichier de parametres amcl.yaml dans le fichier params:

amcl:
  ros__parameters:
    # Utiliser le temps de simulation au lieu du temps réel
    use_sim_time: True
    # Coefficients pour les bruits de mouvement
    alpha1: 0.2
    alpha2: 0.2
    alpha3: 0.2
    alpha4: 0.2
    alpha5: 0.2
    # Identifiant de la frame de base du robot
    base_frame_id: "base_footprint"
    # Distance seuil pour ignorer les faisceaux de laser
    beam_skip_distance: 0.5
    # Seuil d'erreur pour ignorer les faisceaux de laser
    beam_skip_error_threshold: 0.9
    # Seuil pour commencer à ignorer les faisceaux de laser
    beam_skip_threshold: 0.3
    # Activer ou désactiver le saut de faisceaux
    do_beamskip: false
    # Identifiant de la frame globale (carte)
    global_frame_id: "map"
    # Paramètre lambda pour le modèle de faisceau court
    lambda_short: 0.1
    # Distance maximale pour considérer les probabilités de faisceau laser
    laser_likelihood_max_dist: 2.0
    # Portée maximale du laser
    laser_max_range: 100.0
    # Portée minimale du laser
    laser_min_range: -1.0
    # Type de modèle de laser utilisé
    laser_model_type: "likelihood_field"
    # Nombre maximal de faisceaux laser utilisés
    max_beams: 60
    # Nombre maximal de particules
    max_particles: 2000
    # Nombre minimal de particules
    min_particles: 500
    # Identifiant de la frame odométrique
    odom_frame_id: "odom"
    # Erreur maximale permise pour le filtre particulaire
    pf_err: 0.05
    # Confiance dans les mesures de position
    pf_z: 0.99
    # Paramètre de récupération rapide pour le filtre particulaire
    recovery_alpha_fast: 0.0
    # Paramètre de récupération lente pour le filtre particulaire
    recovery_alpha_slow: 0.0
    # Intervalle de rééchantillonnage des particules
    resample_interval: 1
    # Type de modèle de mouvement du robot
    robot_model_type: "nav2_amcl::DifferentialMotionModel"
    # Fréquence de sauvegarde de la pose estimée (en secondes)
    save_pose_rate: 0.5
    # Écart type pour le modèle de capteur "hit"
    sigma_hit: 0.2
    # Activer ou désactiver la diffusion des transformations
    tf_broadcast: true
    # Tolérance pour la transformation des coordonnées (en secondes)
    transform_tolerance: 1.0
    # Seuil minimal de rotation pour mettre à jour la pose
    update_min_a: 0.2
    # Seuil minimal de translation pour mettre à jour la pose
    update_min_d: 0.25
    # Poids du modèle de capteur "hit"
    z_hit: 0.5
    # Poids du modèle de capteur "max"
    z_max: 0.05
    # Poids du modèle de capteur "rand"
    z_rand: 0.5
    # Poids du modèle de capteur "short"
    z_short: 0.05
    # Topic fournissant les données du scan laser
    scan_topic: scan
    # Topic sur lequel la carte est publiée
    map_topic: map
    # Utiliser seulement la première carte reçue
    first_map_only: false
    # Permet de définir la pose initiale avec le paramètre initial_pose
    set_initial_pose: true
    # Pose initiale du robot
    initial_pose:
      x: -2.0
      y: -0.5
      z: 0.0
      yaw: 0.0

Vous pouvez trouver la documentation de amcl avec la liste des paramètre ici: https://docs.nav2.org/configuration/packages/configuring-amcl.html. Vous pouvez réutiliser le fichier de configuration rviz2 du projet pour visualiser les résultats:

rviz2 -d ~/ros2_ws/slam_toolbox_rviz_config.rviz

Une fois rviz lancé pour visualiser la carte, vous pouvez build le package et executer le launch file pour voir la map crée précédemment:

cd ~/ros2_ws 
colcon build --symlink-install 
source install/setup.bash 
ros2 launch slam_setup_tutorial start_slam_tool_box.launch.py

Vous devriez maintenant voir la map que nous avons généré dans rviz avec le robot positionné dessus:

alternative text

La TF map est republiée et la pose du robot sur la frame map est publiée sur le topic /amcl_pose. Nous avons donc vu comment générer une static map avec slam_toolbox et comment la réutiliser en utilisant map_server et amcl.

Feedback

Cet article vous a plu ? Avez-vous des questions sur ce qui est expliqué ? Quoi qu’il en soit, n’hésitez pas à laisser un commentaire dans la section des commentaires ci-dessous, afin que nous puissions interagir et apprendre les uns des autres.

Si vous souhaitez en savoir plus sur d’autres sujets liés à ROS, faites le nous savoir dans l’espace commentaires et nous ferons une vidéo ou un article à ce sujet.
Topics: ROS Q&A | ros2

This tutorial is created by Robotics Ambassador Enzo.

Video Tutorial

Comment utiliser ROSlibjs avec ROS2 – French ROS2 Tutorial

Comment utiliser ROSlibjs avec ROS2 – French ROS2 Tutorial

This tutorial is created by Robotics Ambassador 023 Enzo

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/
Cours: ROS2 Basics in 5 Days C++: https://app.theconstructsim.com/courses/133

Dans ce tutoriel, nous allons voir comment utiliser ROSLibjs avec ROS2 pour tirer parti de la puissance de ROS dans des applications web et JavaScript. Nous allons mettre en place un exemple simple d’une page HTML utilisant ROSLibjs pour communiquer avec un système ROS2. L’objectif du tutoriel sera d’utiliser un publisher et un subscriber depuis notre page web pour interagir avec un turtlebot3 simulé dans Gazebo.

Prérequis: Utiliser une installation ROS2 avec Gazebo

ROS2

Vous pouvez vous connecter au site TheConstruct pour acceder à des machines virtuelles préconfigurées avec une installation ROS. Ce tutoriel est realisé avec ROS Humble.

Si vous voulez effectuer le tutoriel sur votre installation local, vous devez avoir ROS2 installé (https://docs.ros.org/en/humble/Installation.html), avoir configuré un workspace (https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html) et avoir installé le turtlebot3.

# pour installer tous les packages du turtlebot3
# remplacez humble par votre distro ROS2
cd ~/ros2_ws
colcon build
source install/setup.bash
sudo apt-get install ros-humble-turtlebot3*
# n'oubliez pas d'exporter le modèle de Turtlebot3 que vous souhaitez utiliser
export TURTLEBOT3_MODEL=waffle_pi

Nous allons ensuite lancer la simulation du turtlebot3 dans gazebo. Le turtlebot3 va publier les topics que nous allons utiliser dans le tutoriel.

Partie 1: Concepts

rosbridge_suite (https://github.com/RobotWebTools/rosbridge_suite) avec le node rosbridge-server fournit un serveur WebSocket qui donne accès aux fonctionnalités de ROS pour des programmes non-ROS. WebSocket est un protocole de communication qui permet une communication bidirectionnelle entre les clients et les serveurs à travers une connexion unique et durable. Des clients roslib ont été développés dans differents languages de programmation (Python, Rust, Java, Javascript). rosbridge_server permet donc une intégration entre ROS avec un large éventail de technologies, notamment des applications Web, des appareils mobiles, des environnements de simulation. Dans ce tutoriel nous allons apprendre à utiliser roslibjs qui permet d’interagir avec l’ecosystème ROS en utilisant Javascript. Nous allons créer ensemble une interface web simple permettant d’interagir avec un robot simulé sur Gazebo.

Partie 2: Implémentation

Nous allons dans un premier temps créer une page web index.html dans le dossier webpage_ws. Cette page web html execute du javascript pour utiliser ROSlibjs et déclarer notre publisher et notre subscriber:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ROS2 ROSLIBjs example</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <h1>ROS2 ROSLIBjs example</h1>
    <div class="container">

        <!-- Inputs pour publier le message Twist sur le topic cmd_vel -->
        <div>
            <label for="linearSpeed">Linear Speed:</label>
            <input type="number" id="linearSpeed" step="0.1" value="0">
            <label for="angularSpeed">Angular Speed:</label>
            <input type="number" id="angularSpeed" step="0.1" value="0">
            <!-- Appelle la fonction submitInputsTwist qui va publier un Twist message -->
            <button onclick="submitInputsTwist()">Publish Twist</button>
        </div>

        <!-- Zone de texte pour afficher les messages reçu par le subscriber d'odom -->
        <div>
            <h2>Received Odometry</h2>
            <textarea id="odometryData" readonly></textarea>
        </div>
        
        <!-- Joystick pour controler le robot en publiant sur cmd_vel -->
        <div id="joyDiv" style="width:200px;height:200px;margin-bottom:20px;"></div>
    </div>
    
    
    <!-- Pour importer roslibjs -->
    <script src="https://s3.eu-west-1.amazonaws.com/rosject.io/js/roslib.min.js"></script>

    <!-- La repository github du joystick https://github.com/bobboteck/JoyStick -->
    <script src="https://github.com/bobboteck/JoyStick/releases/download/v2.0.0/joy.min.js"></script>

    <!-- Javascript -->
    <script>

        // On déclare notre client
        var ros = new ROSLIB.Ros();

        var rosbridgeUrl = 'ws://localhost:9090'; // Remplacer localhost:9090 par l'url rosbridge_server URL (et ne pas ajouter:port)

        // Connecte au ROS2 environment
        ros.on('connection', function () {
            console.log('Connected to ROS1 environment.');
        });

        // Gérer les cas de déconnection
        ros.on('error', function (error) {
            console.error('Error connecting to ROS1 environment:', error);
        });

        ros.on('close', function () {
            console.log('Connection to ROS1 environment closed.');
        });

        // Déclare les variable qui permettent d'interagir avec les topics ROS
        var twistTopic = new ROSLIB.Topic({
            ros: ros,
            name: '/cmd_vel',
            messageType: 'geometry_msgs/Twist'
        });

        var odometryTopic = new ROSLIB.Topic({
            ros: ros,
            name: '/odom',
            messageType: 'nav_msgs/Odometry'
        });
        
        // Subscribe au topic odom et définit la fonction callback
        odometryTopic.subscribe(function (message) {
            console.log(message)
            // Change la valeur de la texte area avec le message reçu depuis le topic
            document.getElementById('odometryData').value = JSON.stringify(message, null, 2);
        });

        function publishTwist(linearSpeed, angularSpeed) {
            
            // Declare le Twist message pour pouvoir publier les valeurs en entrée de la fonction
            var twist = new ROSLIB.Message({
                linear: {
                    x: linearSpeed,
                    y: 0,
                    z: 0
                },
                angular: {
                    x: 0,
                    y: 0,
                    z: angularSpeed
                }
            });
            // Publie le Twist message sur le topic cmd_vel
            twistTopic.publish(twist);
        }

        // Connecte au ROS2 environment
        ros.connect(rosbridgeUrl);

        
        // La fonction appellée lorsque Publish Twist est cliqué
        function submitInputsTwist() {

            // Récupère les valeurs des inputs pour linearSpeed et angularSpeed
            var linearSpeed = parseFloat(document.getElementById('linearSpeed').value);
            var angularSpeed = parseFloat(document.getElementById('angularSpeed').value);
            
            publishTwist(linearSpeed, angularSpeed);
        }

        
        
        // Declare le joystick pour publier les données sur cmd_vel
        var Joy1 = new JoyStick('joyDiv', {}, function(stickData) {
            
            // Récupère les valeurs des axes du joysticks
            let angularSpeed = -stickData.x/50;
            let linearSpeed = stickData.y/50;
            
            // Declare le Twist message pour pouvoir le publier
            var twist = new ROSLIB.Message({
                linear: {
                    x: linearSpeed,
                    y: 0,
                    z: 0
                },
                angular: {
                    x: 0,
                    y: 0,
                    z: angularSpeed
                }
            });
            
            // Publie le Twist message sur le topic cmd_vel
            twistTopic.publish(twist);
        });
        
    </script>
</body>
</html>

Pour résumer le code ci-dessus:

  • On écrit notre page HTML qui va servir d’interface utilisateur.
  • Dans notre Javascript, on crée le client websocket ROSLib et on crée les fonctions qui seront appelées pour differents évenements de la websocket (connection, error, close).
  • On déclare ensuite les variables qui vont nous permettre d’interagir avec les topics.
  • On subscribe au topic /odom et on modifie la valeur du textarea odometryData dans le callback.
  • On crée la fonction publishTwist qui est appelée lorsque le bouton Publish Twist est appelé, elle permet de publier les valeurs.
  • On déclare le joystick et on appelle la fonction publishTwist pour publier sur le topic cmd_vel les valeurs des axes du joysticks.

Vous pouvez également ajouter le fichier CSS style.css:

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f5f5f5;
    color: #333;
}

h1 {
    text-align: center;
    margin-top: 20px;
}

.container {
    max-width: 600px;
    display: flex;
    flex-direction: column;
    margin: 20px auto;
    background-color: #fff;
    border-radius: 10px;
    padding: 20px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    
    text-align: center;
}

label {
    display: inline-block;
    width: 120px;
    margin-bottom: 10px;
}

input[type="number"] {
    width: 80px;
    padding: 5px;
    border-radius: 5px;
    border: 1px solid #ccc;
    margin-right: 10px;
}

button {
    padding: 8px 16px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}

textarea {
    width: 100%;
    height: 150px;
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #ccc;
    resize: none;
} 

Voici le visuel de la page web:

Nous allons voir dans la partie suivante comment l’ouvrir en utilisant notre environnement de développement.

Partie 3: Tester le système

Pour tester l’interface exemple du tutoriel, vous devez dans un premier temps lancer la simulation du turtlebot3 avec la commande suivante dans un premier terminal:

export TURTLEBOT3_MODEL=waffle_pi
ros2 launch turtlebot3_gazebo turtlebot3_house.launch.py

Vous devez ensuite lancer rosbridge_server dans un second terminal:

ros2 launch rosbridge_server rosbridge_websocket_launch.xml

Les prochaines étapes sont seulement pour faire fonctionner l’exemple dans un rosject de theConstuct. Dans un nouveau terminal, vous devez lancer un server python pour hoster la page web via l’installation de theConstruct:

python3 -mhttp.server 7000

Ouvrez un terminal et lancez les commandes suivantes:

# pour obtenir l'url de la page web html
webpage_address
# pour obtenir l'adresse de la websocket fournit par l'installation theConstruct
rosbridge_address

Vous devrez utiliser l’adresse websocket rosbridge_address dans la variable rosbridgeUrl du code.

Si vous effectuez le tutoriel sur votre machine locale, vous pouvez ouvrir directement votre page html avec votre navigateur et l’adresse de la websocket ws://0.0.0.0:9090 (port par defaut utilisé par le node rosbridge_server).

Vous pouvez maintenant ouvrir l’interface créée precedemment en ouvrant le ficher index.html dans votre navigateur. Vous devriez obtenir le résultat suivant:

Dans la textarea, vous pouvez voir l’odometry du robot mis à jour à chaque message reçu. Vous devriez pouvoir également pouvoir déplacer le turtlebot3 en utilisant les textes inputs ou le joystick pour publier sur le cmd_vel.

Feedback

Cet article vous a plu ? Avez-vous des questions sur ce qui est expliqué ? Quoi qu’il en soit, n’hésitez pas à laisser un commentaire dans la section des commentaires ci-dessous, afin que nous puissions interagir et apprendre les uns des autres.

Si vous souhaitez en savoir plus sur d’autres sujets liés à ROS, faites-le nous savoir dans l’espace commentaires et nous ferons une vidéo ou un article à ce sujet.
Topics: ROS Q&A | ros2

 

Video Tutorial

Comment utiliser OpenCV avec ROS2 en C++ et Python – French ROS Tutorial

Comment utiliser OpenCV avec ROS2 en C++ et Python – French ROS Tutorial

This tutorial is created by Robotics Ambassador 023 Enzo

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)
Cours: ROS2 Basics in 5 Days C++: https://app.theconstructsim.com/courses/133
Cours: ROS2 Basics in 5 Days Python: https://app.theconstruct.ai/courses/ros2-basics-in-5-days-humble-python-132

Introduction

Le but de ce tutoriel est d’apprendre à utiliser la library OpenCV dans vos nodes C++ et Python. OpenCV (Open Source Computer Vision Library) est une bibliothèque de traitement d’images open source. Elle offre des fonctionnalités avancées pour la manipulation, l’analyse et la reconnaissance d’images, y compris la détection d’objets, le suivi, la segmentation, et bien plus encore. Cette library est très répendu et peut s’averer utile pour de nombreuses applications en robotique. Nous allons donc voir ensemble comment utiliser OpenCV à l’aide de la library cv_bridge dans vos nodes ROS2 C++ et Python.

Prérequis: Utiliser une installation ROS2 avec Gazebo et OpenCV

Installation ROS2

Vous pouvez vous connecter au site TheConstruct pour accéder à des machines virtuelles préconfigurées avec une installation ROS. Pour lancer et tester le code, vous devez lancer la simulation du turtlebot3 sur gazebo. Pour faire cela, entez les commandes suivantes dans le terminal:

# Declare le model de turtlebot3 à simuler
export TURTLEBOT3_MODEL=waffle_pi
# Lance la simulation du turtlebot dans gazebo
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

Une fois la simulation du turtlebot3 lancée, celle-ci va publier sur le topic /camera/image_raw que nous allons utiliser dans les codes d’exemples.

Après avoir exécuté ces commandes, appuyez sur le bouton de l’interface gazebo et selectionnez Open Gazebo.

Vous devriez obtenir le résultat suivant:

Si vous voulez effectuer le tutoriel sur votre installation local, vous devez avoir ROS2 installé (https://docs.ros.org/en/humble/Installation.html), avoir configuré un workspace (https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html) et avoir installé le turtlebot3.

# pour installer tous les packages du turtlebot3
# remplacez humble par votre distro ROS2

sudo apt-get install ros-humble-turtlebot3*
# n'oubliez pas d'exporter le modèle de Turtlebot3 que vous souhaitez utiliser
export TURTLEBOT3_MODEL=waffle_pi

Installer OpenCV

Par défault, toutes les installations de ROS incluent OpenCV mais on peut quand même verifier:

# Pour OpenCV C++ et Python
sudo apt install libopencv-dev python3-opencv

Partie 1: Créer un node C++ utilisant OpenCV

Nous allons commencer par créer un package ROS2 pour compiler et executer les nodes Python et C++ du tutorial.

cd ros2_ws/src/
# Créer le package
ros2 pkg create cv_bridge_tutorial

Nous allons maintenant créer le ficher C++ qui va contenir notre node:

cd ~/ros2_ws/src/cv_bridge_tutorial/src
touch cvbridge_example_cpp.cpp

Une fois le fichier créer, ouvrez le dans votre éditeur de code et copiez y le code suivant:

Dans ce node exemple, on souscrit à l’image publié par le turtlebot3 sur le topic /camera/image_raw, on utilise ensuite un cv_bridge pour la convertir dans un format attendu par les méthodes de la library OpenCV. On utilise la methode cv::threshold qui applique un thresholding à l’image (https://docs.opencv.org/4.x/db/d8e/tutorial_threshold.html). On reconvertit à l’aide du cv_bridge l’image dans le format Image message de ROS et on republit cette image sur le topic /processed_image_topic_cpp.

Pour l’encodage, si vous indiquez “passthrough” dans le parametre encoding du CV_bridge, l’image de sortie aura le même encodage que l’image d’entrée. Une grande partie des fonctions d’OpenCV attendent en entrée des images possèdant un de ces deux encodages: mono8 and bgr8.

On doit ensuite éditer le CMakeList.txt pour pouvoir indiquer les dépendences necessaire à la compilation du node:

Vous pouvez build votre workspace pour verifier si la configuration du CmakeList.txt fonctionne:

cd ~/ros2_ws
colcon build
source install/setup.bash

Partie 2: Créer un node Python utilisant OpenCV

Nous allons utiliser le package crée dans la partie précedante. On va d’abord créer un dossier script et y ajouter le fichier cvbridge_example_py.py qui va contenir notre node:

cd ~/ros2_ws/src/cv_bridge_tutorial/
mkdir scripts
cd scripts
touch cvbridge_example_py.py

Une fois le fichier créer, ouvrez le dans votre éditeur de code et copiez y le code suivant:

Une fois le node python écrit, on doit modifier le CmakeLists.txt créer dans la partie précédente pour pouvoir l’executer:

On peut maintenant compiler le package avec les commandes suivantes:

cd ~/ros2_ws
colcon build
source install/setup.bash

Partie 3: Tester les nodes écrits précedemment

Les deux nodes du tutorial souscrivent au topic /camera/image_raw publié par le turtlebot3. Vous pouvez verifier que la simulation lancée durant l’introduction publie toujours ce topic avec la commande ros2 topic echo ou en lançant rviz2. Un fichier de configuration rviz2 est enregistré à la racine du workspace si vous utilisez le Rosject du tutorial. Vous pouvez lancer rviz2 avec cette configuration en utilisant la commande suivante:

rviz2 -d ~/ros2_ws/src/tutorial_config.rviz

Rviz2 devrait s’ouvrir avec l’interface suivante:
alternative text
Vous pouvez lancer les nodes avec les commandes suivantes:

source install/setup.bash
# Pour le node python
ros2 run cv_bridge_tutorial cvbridge_example_py.py

Dans un autre terminal:

source install/setup.bash
# Pour le node C++
ros2 run cv_bridge_tutorial cvbridge_example_cpp

Vous devriez pourvoir visualiser le résultat des thresholding publiés par les nodes d’exemples:

 

Video Tutorial

Comment créer des bibliothèques avec ROS2 C++ – French ROS Tutorial

Comment créer des bibliothèques avec ROS2 C++ – French ROS Tutorial

This tutorial is created by Robotics Ambassador 023 Enzo

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)
Cours: ROS2 Basics in 5 Days C++: https://app.theconstructsim.com/courses/133

Introduction

Le but de ce tutoriel est d’apprendre à créer et utiliser des bibliothèques dans les packages ROS2 C++. Lors du développement d’un projet, il est essentiel de garder son code structuré pour assurer un développement efficace. L’utilisation de bibliothèque (ou library) est indispensable pour cela car cela permet de regrouper les codes sources en fonction de leurs usages et donc de séparer des fonctionnalités distinctes. La création de bibliothèques est donc essentielle pour rendre votre code plus structuré, modulaire et réutilisable. Nous allons donc voir ensemble comment déclarer et faire appel une library dans les packages ROS2 C++. Nous allons dans un premier temps voir comment simplement utiliser un header dans un package ROS2 puis nous déclarerons la même bibliothèque dans un package indépendant et utiliserons celle ci dans un autre package.

Pré-requis

Pour lancer et tester le code, vous devez lancer la simulation du turtlebot3 sur gazebo. Pour faire cela, entez les commandes suivantes dans le terminal:

(more…)

Comment exporter des codes ROS sur votre installation locale – ROS French Tutorial

Comment exporter des codes ROS sur votre installation locale – ROS French Tutorial

This tutorial is created by Rosbotics Ambassador 023 Enzo 

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)
Cours: ROS2 Baiscs in 5 Days Python: https://app.theconstructsim.com/courses/132

Introduction

Dans cet article, vous apprendrez comment exporter le code écrit sur les plateformes TheConstruct vers votre machine locale. Que ce soit dans le cadre d’une formation ou en utilisant un Rosject pour simuler un environnement spécifique, de nombreux utilisateurs sur le forum ROS Ignite Academy se demandent comment partager, télécharger ou utiliser leur code sur leur installation locale.

Prérequis

Pour suivre le tutoriel sur votre ordinateur, vous devez configurer votre installation locale.

ROS2 installation

Avant de pouvoir tester ce tutoriel, vous devez disposer d’une installation locale de ROS2. Pour ce faire, vous pouvez suivre les instructions dans la documentation officielle: https://docs.ros.org/en/humble/Installation.html. Vous devez également configurer un espace de travail ROS2 pour stocker votre package et le construire. Pour ce faire, suivez les instructions de la documentation officielle: https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html

Turtlebot3 installation

Vous devez avoir le package Turtlebot3 installé dans votre environnement local afin de lancer la simulation Gazebo du Turtlebot3 et tester le code fourni dans le package. Pour ce faire, vous pouvez suivre les instructions de la documentation Turtlebot3 :https://emanual.robotis.com/docs/en/platform/turtlebot3/simulation/ et construire le code source sur votre machine locale, ou installer directement les packages Turtlebot3 avec cette commande :

# pour installer tous les packages du turtlebot3
$ sudo apt-get install ros-humble-turtlebot3*

# n'oubliez pas d'exporter le modèle de Turtlebot3 que vous souhaitez utiliser
$ export TURTLEBOT3_MODEL=waffle_pi

Maintenant que votre installation locale est prête, je vais vous montrer deux façons de partager vos packages entre les ROSjects ou les cours TheConstruct et votre installation locale. 

Téléchargez votre package depuis l’interface web Rosject

La première méthode consiste à télécharger le package directement depuis l’IDE de la plateforme. Pour ce faire, clique droit sur le dossier src qui contient votre package dans votre arborescence de fichier de l’IDE, puis cliquez sur on Download.

Cela devrait lancer le téléchargement dans votre navigateur.

Vous pouvez décompresser le package dans votre workspace ROS2.

Ensuite, compilez le package en utilisant les instructions suivantes dans un terminal local :

$ cd ~/ros2_ws

# compiler le package
$ colcon build

# sourcer le workspace
$ source install/setup.bash

L’avantage principal de cette méthode est sa simplicité d’utilisation. Cependant, elle peut ne pas être adaptée si vous souhaitez pouvoir continuer à faire évoluer le code ou le partager dans le cadre d’un développement collaboratif. C’est pourquoi la deuxième méthode peut être plus adaptée pour les projets.

 

Configurer un dépôt (repository) GitHub 

La deuxième méthode consiste à utiliser un dépôt sur GitHub. L’avantage principal de cette méthode est que vous pouvez versionner votre code et continuer à développer sur plusieurs installations parallèles, facilitant le partage de votre travail. Vous pouvez initialiser votre dépôt GitHub en allant sur  https://github.com/, vous connecter, aller dans “Your repository” et sélectionner “New”. Ensuite, vous pouvez créer un dépôt qui a le même nom que votre package ROS.

Pour utiliser mon dépôt sans utiliser SSH, j’ai configuré un personal access token (classic). Voici un lien qui explique comment le configurer : https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic, vous pouvez également interagir avec votre dépôt en utilisant SSH.

Une fois que le dépôt GitHub est créé, vous devez exécuter ces commandes sur le webshell ROSject :

# go to the directory of your package
$ cd ~/ros2_ws/src/tutorial_local_machine

$ git init

# entrer vos informations
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"

# ajouter tous les fichier du package dans votre commit
$ git add --all

# commit et ajouter un message pour décrire l’état d’avancement du projet
$ git commit -m "Initialize the repository"

$ git branch -M main

# lier le dépôt locale à le dépôt distante sur GitHub
$ git remote add origin https://github.com/[YourGithubUserName]/tutorial_local_machine.git

# s’identifier et utiliser le jeton d'accès personnel comme mot de passe
$ git push -u origin main

Une fois les commandes exécutées, votre code devrait être téléchargé sur votre dépôt distant sur GitHub.

Vous pouvez maintenant ouvrir un terminal sur votre machine locale et cloner votre dépôt GitHub dans votre workspace ROS2 local:

$ cd ~/ros2_ws/src/

# cloner la dépôt
$ git clone https://github.com/[YourGithubUserName]/tutorial_local_machine.git

# revenir à la racine du workspace
$ cd ..

# compiler le package
$ colcon build

# sourcer le workspace
$ source install/setup.bash

Lancer la simulation en local et exectuer le code

 

Maintenant que tout est configuré et que le package est compilé, vous devriez être en mesure d’exécuter le node. Le package du tutoriel contient un node C++ simple pour interagir avec le laserscan et le cmd_vel du Turtlebot3. Le node s’abonne au topic /scan afin de déterminer la distance entre un obstacle en face du robot et publie sur /cmd_vel pour avancer tant que la distance est supérieure à 1,0 mètre. Une fois que la distance est inférieure à 1,0 mètre, il publie une vitesse de 0 pour arrêter le robot.Vous pouvez tester le code en exécutant le fichier launch suivant:

$ cd ~/ros2_ws
$ source install/setup.bash
$ ros2 launch tutorial_local_machine start_sim_node.launch.py

Ou vous pouvez démarrer la simulation Turtlebot3 en exécutant cette commande dans un terminal sur votre machine locale:

$ ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

Ensuite, dans un deuxième terminal, exécutez le nœud:

$ cd ~/ros2_ws
$ source install/setup.bash
$ ros2 run tutorial_local_machine main_node

La simulation gazebo du Turtlebot3 et le script devraient être en cours d’exécution.

Merci d’avoir suivi ce poste.

Ressources

Feedback

Cet article vous a plu ? Avez-vous des questions sur ce qui est expliqué ? Quoi qu’il en soit, n’hésitez pas à laisser un commentaire dans la section des commentaires ci-dessous, afin que nous puissions interagir et apprendre les uns des autres.

Si vous souhaitez en savoir plus sur d’autres sujets liés à ROS, faites-le nous savoir dans l’espace commentaires et nous ferons une vidéo ou un article à ce sujet.
Topics: ROS Q&A | ros2

Video Tutorial

Comment créer des bibliothèques avec ROS2 Python – ROS French Tutorial

Comment créer des bibliothèques avec ROS2 Python – ROS French Tutorial

This tutorial is created by RA 023 Enzo

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)
Cours: ROS2 Baiscs in 5 Days Python: https://app.theconstructsim.com/courses/132

Introduction

Le but de ce tutoriel est d’apprendre à créer et utiliser des bibliothèques dans les packages ROS2 Python. Lors du développement d’un projet, il est essentiel de garder son code structuré pour assurer un développement efficace. L’utilisation de bibliothèque (ou library) custom est indispensable pour cela car cela permet de regrouper les codes sources en fonction de leurs usages et donc de séparer des fonctionnalités distinctes. La création de bibliothèques est donc essentielle pour rendre votre code plus structuré, modulaire et réutilisable. Nous allons donc voir ensemble comment déclarer et faire appel une custom library dans les packages ROS2 Python.
Pré-requis
Pour lancer et tester le code, vous devez lancer la simulation du turtlebot3 sur gazebo. Si vous voulez effectuer le tutoriel sur votre installation local, vous devez avoir ROS2 installé (https://docs.ros.org/en/humble/Installation.html), avoir configuré un workspace (https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html) et avoir installé le turtlebot3.

# pour installer tous les packages du turtlebot3
# remplacez humble par votre distro ROS2
sudo apt-get install ros-humble-turtlebot3*
# n'oubliez pas d'exporter le modèle de Turtlebot3 que vous souhaitez utiliser
export TURTLEBOT3_MODEL=waffle_pi

Si vous effectuez ce tutoriel en utilisant un Rosject vous pouvez directement enter les commandes suivantes dans le terminal:

# Declare le model de turtlebot3 à simuler
export TURTLEBOT3_MODEL=waffle_pi
# Lance la simulation du turtlebot dans gazebo
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

Une fois la simulation du turtlebot3 lancée, celle-ci va publier sur le topic /odom que nous allons utiliser dans le code exemple.
Après avoir exécuté ces commandes, appuyez sur le bounton de l’interface gazebo et selectionnez Open Gazebo.


Vous devriez obtenir le résultat suivant.

Part 1: Créer un package qui va contenir le source code de la library

Nous allons commencer par créer le package python qui va servir de bibliothèque. Ouvrez un terminal et executez les commandes suivantes:

cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python custom_library

Maintenant que le package est initialisé, nous allons créer le fichier qui va contenir le source code de la library. Pour faire cela, ouvrez un terminal et executez les commandes suivantes:

cd ~/ros2_ws/src/custom_library/custom_library
touch odom_toolbox.py

Affichez l’éditeur de code et ouvrez le fichier odom_toolbox.py. Ajouter ensuite le code suivant:

from geometry_msgs.msg import Point
class OdometryToolbox:
    def point_from_odom_offset_init(actual_odom, init_odom):
   
        point_with_offset = Point()
        point_with_offset.x = actual_odom.pose.pose.position.x - init_odom.pose.pose.position.x
        point_with_offset.y = actual_odom.pose.pose.position.y - init_odom.pose.pose.position.y
        point_with_offset.z = actual_odom.pose.pose.position.z - init_odom.pose.pose.position.z
        return point_with_offset

Ce code d’exemple déclare une class contenant une méthode permettant de soustraire terme à terme la position d’une odom avec une autre et de retourner le point obtenu.
Vous pouvez compiler le package pour tester que tout fonctionne.

cd ~/ros2_ws
colcon build
source install/setup.bash

Part 2: Créer un package qui va utiliser la library créée précédemment

Nous allons créer un package python qui va utiliser la bibliothèque créee dans la partie une. Ouvrez un terminal et executez les commandes suivantes:

cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python my_package

Une fois le package créer, nous allons créer un fichier main.py qui contiendra le node exemple.

cd ~/ros2_ws/src/my_package/my_package
touch main.py

Collez ensuite le code ci-dessous dans le fichier main.py.

# main.py
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Point
from nav_msgs.msg import Odometry
# importer la custom library
from custom_library.odom_toolbox import OdometryToolbox
class OdomToPointNode(Node):
    def __init__(self):
        super().__init__('odom_to_point_node')
        # Initialiser le subscriber sur le topic odom du turtlebot3
        self.odom_subscription = self.create_subscription(
            Odometry,
            'odom',
            self.odom_callback,
            10
        )
        self.odom_subscription
        # Initialiser le publisher du point
        self.point_publisher = self.create_publisher(Point, 'point_topic', 10)
       
        self.odom_init = Odometry()
        self.isOdomInit = False
       
    def odom_callback(self, msg):
       
        if self.isOdomInit == False:
            # Recuperer la valeur initial de la premiere odometry
            self.odom_init = msg
            self.isOdomInit = True
       
        point_msg = Point()
        # Utilser la method declaree dans la custom_library
        point_msg = OdometryToolbox.point_from_odom_offset_init(msg, self.odom_init)
        # Publier le point obtenu
        self.point_publisher.publish(point_msg)
        print(f'Point Published: {point_msg.x}, {point_msg.y}, {point_msg.z}')
def main(args=None):
    rclpy.init(args=args)
    odom_to_point_node = OdomToPointNode()
    rclpy.spin(odom_to_point_node)
    odom_to_point_node.destroy_node()
    rclpy.shutdown()
if __name__ == '__main__':
    main()

Pour pouvoir utiliser votre library custom dans votre package, vous devez mettre à jour le setup.py du package.

# setup.py
from setuptools import setup
package_name = 'my_package'
setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=[
        'setuptools',
        # ajouter votre library dans les install_requires
        'custom_library'],
    zip_safe=True,
    maintainer='user',
    maintainer_email='user@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            # Ajouter le node dans les console_scripts
            'odom_to_point_node = my_package.main:main',
        ],
    },
)

Une fois que les fichiers suivants ont été modifiés, vous pouvez build le package.

cd ~/ros2_ws
colcon build
source install/setup.bash

Step 3: Tester le node

Pour lancer le node, lancez la simulation comme indiqué dans les prérequis. Vous devez ensuite exécuter les commandes suivantes dans un terminal:

ros2 run my_package odom_to_point_node

Maintenant que le code est en cours d’exécution, vous devriez avoir un print des coordonnées du robot en ayant pour origine la position du robot au moment du lancement le node.

Merci d’avoir suivi ce poste.

Ressources

• ROS Ignite Academy
• ROS2 Full course for beginner
• Rosject utilisé pour le poste

Feedback

Cet article vous a plu ? Avez-vous des questions sur ce qui est expliqué ? Quoi qu’il en soit, n’hésitez pas à laisser un commentaire dans la section des commentaires ci-dessous, afin que nous puissions interagir et apprendre les uns des autres.

Si vous souhaitez en savoir plus sur d’autres sujets liés à ROS, faites-le nous savoir dans l’espace commentaires et nous ferons une vidéo ou un article à ce sujet.
Topics: ROS Q&A | ros2

Video Tutorial

Pin It on Pinterest