Avant de piloter un robot, de simuler un bras ou de relier un automate, il faut un environnement ROS 2 qui fonctionne et savoir y écrire le moindre programme. C’est exactement ce que vous allez faire ici : installer proprement ROS 2 sur une machine Ubuntu, vérifier qu’il communique, puis écrire vos deux premiers programmes — l’un qui produit des données, l’autre qui les consomme. À la fin, vous aurez un capteur de température simulé qui diffuse sa mesure et un moniteur qui réagit dès qu’elle dépasse un seuil.
🎯 Ce que vous allez apprendre
- Installer ROS 2 Jazzy sur Ubuntu 24.04 à partir des dépôts officiels, sans bricolage.
- Vérifier que l’installation communique en lançant les programmes de démonstration.
- Créer un espace de travail structuré et un paquet Python prêt à compiler.
- Écrire un nœud qui publie un flux de données et un nœud qui s’y abonne.
- Inspecter un système ROS 2 en marche avec les outils en ligne de commande.
🛠️ Ce que vous allez construire
Un petit système à deux programmes. Le premier, capteur, simule la température d’un moteur et publie cette valeur deux fois par seconde sur un canal nommé /temperature_moteur. Le second, moniteur, écoute ce canal et affiche une alerte chaque fois que la température franchit 80 °C. C’est volontairement la brique la plus simple de toute la robotique : un producteur et un consommateur de données. Tout le reste de la série n’est qu’une élaboration de ce motif.
Prérequis
- Une machine sous Ubuntu 24.04 LTS (Noble Numbat), réelle ou en machine virtuelle, avec accès administrateur.
- Une connexion réseau correcte : l’installation télécharge plusieurs centaines de mégaoctets.
- Des bases de ligne de commande Linux et un peu de Python. Test express : si vous savez ouvrir un terminal, lancer une commande avec
sudoet éditer un fichier texte, vous êtes prêt. - ⏱️ Temps estimé : 45 à 60 minutes, dont une bonne part de téléchargement.
Pourquoi Ubuntu 24.04 précisément ? Parce que la version à support long terme de ROS 2 visée ici, Jazzy Jalisco, est officiellement bâtie pour cette version d’Ubuntu. Mélanger une autre distribution ou une autre version d’Ubuntu fonctionne parfois, mais multiplie les ennuis. Pour apprendre, on suit le chemin balisé.
Étape 1 — Préparer la langue du système
ROS 2 attend un environnement configuré en UTF-8. Sur une installation Ubuntu standard c’est déjà le cas, mais une machine minimale ou un conteneur peut en manquer, ce qui provoque des erreurs obscures plus tard. On s’en assure une fois pour toutes avant de commencer.
locale # vérifier la présence d'UTF-8
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale # vérifier de nouveau
La première commande locale affiche la configuration actuelle ; la seconde, après réglage, doit montrer des lignes comme LANG=en_US.UTF-8. Si c’est le cas, le système parle bien l’UTF-8 et l’on peut continuer sereinement. Ce détail évite des plantages d’encodage quand un message contiendra un caractère accentué.
Étape 2 — Ajouter le dépôt logiciel de ROS 2
ROS 2 ne se trouve pas dans les dépôts Ubuntu par défaut. Il faut ajouter le dépôt officiel du projet et sa clé de signature, pour qu’apt sache où chercher les paquets et qu’il puisse en vérifier l’authenticité. La méthode actuelle passe par un petit paquet d’installation qui configure tout proprement.
On active d’abord le dépôt « universe » d’Ubuntu, dont ROS 2 dépend :
sudo apt install software-properties-common
sudo add-apt-repository universe
Puis on récupère et on installe le paquet qui déclare le dépôt ROS 2 et sa clé GPG :
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb"
sudo apt install /tmp/ros2-apt-source.deb
Décortiquons la deuxième ligne, qui impressionne mais reste simple : elle interroge l’API de GitHub pour trouver le numéro de la dernière version du paquet de dépôt, le stocke dans une variable, puis la troisième ligne télécharge le bon fichier .deb pour votre version d’Ubuntu (détectée automatiquement via VERSION_CODENAME). La dernière ligne l’installe. Si tout s’est bien passé, aucune erreur rouge n’apparaît et le dépôt ROS 2 est désormais connu du système.
Étape 3 — Installer ROS 2 Jazzy
Le dépôt en place, l’installation elle-même tient en quelques commandes. On rafraîchit la liste des paquets, on met le système à jour, puis on installe la variante « desktop » qui contient tout ce dont un débutant a besoin : la bibliothèque centrale, l’outil de visualisation RViz, et les programmes de démonstration.
sudo apt update
sudo apt upgrade
sudo apt install ros-jazzy-desktop
On ajoute aussi les outils de développement, indispensables dès qu’on écrira et compilera son propre code aux étapes suivantes :
sudo apt install ros-dev-tools
Cette dernière installation est la plus longue — plusieurs centaines de mégaoctets. C’est normal. À la fin, ROS 2 Jazzy est présent sur la machine, rangé sous /opt/ros/jazzy. Il ne se lance pas tout seul : il faut l’« activer » dans chaque terminal, ce qui est l’objet de l’étape suivante.
Étape 4 — Activer ROS 2 et lancer la démonstration
ROS 2 doit être chargé dans la session du terminal par un script de configuration. Cette opération, appelée « sourcer », ajoute les commandes ROS 2 à votre environnement. On le fait, puis on lance le programme de démonstration qui prouve que tout communique.
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_cpp talker
Vous devriez voir défiler des lignes du type [INFO] [talker]: Publishing: 'Hello World: 1', le compteur augmentant à chaque seconde. Ce programme publie un message. Laissez-le tourner, ouvrez un second terminal, et lancez-y l’écouteur :
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_py listener
Le second terminal doit afficher [INFO] [listener]: I heard: 'Hello World: 1', en écho au premier. Deux programmes lancés séparément, qui ne se connaissent pas, viennent de se découvrir et de s’échanger des messages tout seuls : c’est la magie de ROS 2 et de sa couche de communication. Si vous voyez cet écho, votre installation est parfaitement fonctionnelle. Arrêtez les deux avec Ctrl+C.
Pour ne pas avoir à sourcer ROS 2 manuellement à chaque ouverture de terminal, ajoutez-le à votre profil :
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
✅ Point d’étape — À ce stade, la démonstration talker/listener fonctionne dans les deux sens. Pour vérifier à tout moment que ROS 2 est bien actif dans un terminal : la commande
ros2 --helpdoit répondre. Si elle est « introuvable », c’est que le terminal n’a pas été sourcé.
Étape 5 — Créer un espace de travail et un paquet
Vos programmes ne vivent pas en vrac : ROS 2 les organise en paquets, eux-mêmes rangés dans un espace de travail que l’on compile avec l’outil colcon. Créons cette structure, qui servira de maison à tout le code de la série.
mkdir -p ~/ros2_cellule_ws/src
cd ~/ros2_cellule_ws/src
ros2 pkg create --build-type ament_python --license Apache-2.0 capteurs_demo
La commande ros2 pkg create génère un squelette de paquet Python nommé capteurs_demo : un dossier du même nom pour le code, un fichier package.xml qui décrit le paquet et ses dépendances, et un setup.py qui indique comment l’installer. C’est dans ce squelette que nous allons déposer nos deux programmes. Le --license Apache-2.0 renseigne la licence, désormais demandé à la création.
Étape 6 — Écrire le nœud capteur (le publieur)
Place au premier vrai programme. Un nœud ROS 2 est une classe qui hérite de Node. Notre capteur va, à intervalle régulier, fabriquer une mesure de température et la publier sur un canal. On crée le fichier capteur.py dans le dossier de code du paquet :
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32
import random
class Capteur(Node):
def __init__(self):
super().__init__('capteur_temperature')
# Crée un publieur de messages Float32 sur le canal 'temperature_moteur',
# avec une file d'attente de profondeur 10.
self.pub = self.create_publisher(Float32, 'temperature_moteur', 10)
# Déclenche timer_callback toutes les 0,5 seconde.
self.timer = self.create_timer(0.5, self.timer_callback)
self.base = 60.0
def timer_callback(self):
msg = Float32()
# Simule une température qui fluctue autour d'une valeur de base.
self.base += random.uniform(-1.5, 2.0)
msg.data = round(self.base, 1)
self.pub.publish(msg)
self.get_logger().info('Temperature publiee : %.1f C' % msg.data)
def main(args=None):
rclpy.init(args=args)
noeud = Capteur()
rclpy.spin(noeud) # boucle jusqu'à Ctrl+C
noeud.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Lisons ce code. Le constructeur déclare un publieur typé Float32 sur le canal temperature_moteur, puis arme un minuteur qui appelle timer_callback toutes les demi-secondes. À chaque appel, on fabrique un message, on lui donne une valeur qui dérive doucement (pour imiter un vrai capteur), on le publie, et on journalise. La fonction main initialise ROS 2, fait tourner le nœud avec rclpy.spin jusqu’à l’interruption, puis nettoie. C’est le squelette de tout nœud Python ROS 2.
Un mot sur le type Float32 : il vient du paquet std_msgs, qui fournit des messages génériques (un nombre, un booléen, une chaîne). Ils sont parfaits pour apprendre et prototyper. Pour un vrai projet, l’usage recommandé est de définir ses propres types de messages porteurs de sens (par exemple un message « TempératureMoteur » avec une unité explicite) plutôt que de transporter un nombre nu — mais c’est une étape ultérieure qui ne change rien aux concepts vus ici.
Étape 7 — Écrire le nœud moniteur (l’abonné)
Le second programme fait l’inverse : il s’abonne au canal et reçoit chaque message. Créons moniteur.py à côté du précédent :
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32
SEUIL = 80.0
class Moniteur(Node):
def __init__(self):
super().__init__('moniteur_temperature')
# S'abonne au même canal et au même type que le capteur.
self.sub = self.create_subscription(
Float32, 'temperature_moteur', self.on_message, 10)
def on_message(self, msg):
if msg.data > SEUIL:
self.get_logger().warn('ALERTE : %.1f C depasse le seuil !' % msg.data)
else:
self.get_logger().info('OK : %.1f C' % msg.data)
def main(args=None):
rclpy.init(args=args)
noeud = Moniteur()
rclpy.spin(noeud)
noeud.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Le point essentiel : l’abonné déclare exactement le même canal et le même type de message que le publieur — temperature_moteur et Float32. C’est la condition pour qu’ils se trouvent. À chaque message reçu, on_message compare la valeur au seuil et journalise une alerte ou un état normal. Si le nom du canal ou le type diffère d’un caractère, les deux nœuds tourneront sans jamais se parler — une erreur de débutant classique.
Étape 8 — Déclarer, compiler, lancer
ROS 2 doit savoir que ces deux fichiers sont des programmes exécutables. On le déclare dans setup.py, à la section entry_points, et on note les dépendances dans package.xml. Dans setup.py, repérez le bloc console_scripts et complétez-le :
entry_points={
'console_scripts': [
'capteur = capteurs_demo.capteur:main',
'moniteur = capteurs_demo.moniteur:main',
],
},
Chaque ligne associe un nom de commande (capteur) à la fonction main du fichier correspondant. Dans package.xml, ajoutez les dépendances juste avant la balise de fermeture des dépendances :
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>
Il ne reste qu’à compiler l’espace de travail et à le sourcer pour rendre les nouvelles commandes disponibles :
cd ~/ros2_cellule_ws
colcon build
source install/setup.bash
La commande colcon build doit se terminer par une ligne verte indiquant que capteurs_demo a été construit avec succès. Le source install/setup.bash ajoute vos deux programmes à l’environnement. Lancez maintenant le capteur dans un terminal :
ros2 run capteurs_demo capteur
Et le moniteur dans un second terminal (pensez à le sourcer aussi avec source ~/ros2_cellule_ws/install/setup.bash) :
ros2 run capteurs_demo moniteur
Le premier terminal annonce les températures publiées, le second les commente — et déclenche une alerte dès que la valeur simulée franchit 80 °C. Vos deux programmes communiquent. Vous venez d’écrire votre premier système ROS 2 de bout en bout.
Étape 9 — Inspecter le système en marche
ROS 2 fournit des outils pour observer ce qui circule, sans toucher au code. Gardez les deux nœuds lancés et, dans un troisième terminal sourcé, explorez :
ros2 topic list
ros2 topic echo /temperature_moteur
ros2 node list
ros2 topic list énumère les canaux actifs : vous devez y voir /temperature_moteur. ros2 topic echo affiche en direct les valeurs qui transitent, ce qui est précieux pour déboguer sans modifier le programme. ros2 node list montre les nœuds vivants : /capteur_temperature et /moniteur_temperature. Pour une vue graphique des connexions entre nœuds et canaux, lancez rqt_graph : un schéma montre le capteur, le canal et le moniteur reliés par une flèche.
✅ Point d’étape final — Si
ros2 topic echo /temperature_moteurfait défiler des valeurs et que le moniteur réagit, l’objectif est atteint : un producteur et un consommateur de données communiquent via ROS 2, et vous savez inspecter le tout.
🐞 Pièges fréquents
| Symptôme / erreur | Cause probable | Correctif |
|---|---|---|
ros2: command not found |
Le terminal n’a pas été sourcé | Lancer source /opt/ros/jazzy/setup.bash (ou rouvrir le terminal si ajouté au .bashrc) |
| Le moniteur ne reçoit rien | Nom de canal ou type de message différent entre les deux nœuds | Vérifier que les deux utilisent temperature_moteur et Float32 à l’identique |
Package 'capteurs_demo' not found |
L’espace de travail n’a pas été sourcé après compilation | Lancer source install/setup.bash depuis la racine de l’espace de travail |
| Modifications du code sans effet | Recompilation oubliée | Relancer colcon build, ou utiliser colcon build --symlink-install pour les fichiers Python |
| Deux machines ne se voient pas | ROS_DOMAIN_ID différent ou pare-feu bloquant |
Définir le même ROS_DOMAIN_ID partout, autoriser le trafic réseau |
✅ Récapitulatif
Vous êtes parti d’une machine Ubuntu nue et vous avez : installé ROS 2 Jazzy depuis les dépôts officiels, validé la communication avec la démonstration intégrée, créé un espace de travail et un paquet Python, écrit un nœud publieur et un nœud abonné, puis compilé et lancé l’ensemble avant de l’inspecter avec les outils en ligne de commande. Vous tenez le motif fondateur de ROS 2 — publication et abonnement — sur lequel reposent la simulation de robot, la lecture de capteurs industriels et la passerelle vers les automates que vous construirez ensuite.
🧾 Aide-mémoire
| Commande | Rôle |
|---|---|
source /opt/ros/jazzy/setup.bash |
Activer ROS 2 dans le terminal |
ros2 pkg create --build-type ament_python NOM |
Créer un paquet Python |
colcon build |
Compiler l’espace de travail |
ros2 run PAQUET PROGRAMME |
Lancer un programme du paquet |
ros2 topic list / echo |
Lister les canaux / afficher leur contenu |
ros2 node list |
Lister les nœuds actifs |
rqt_graph |
Visualiser le graphe nœuds/canaux |
💪 À vous de jouer
Deux extensions pour ancrer ce que vous venez d’apprendre. D’abord, ajoutez un troisième nœud qui s’abonne lui aussi à temperature_moteur et calcule une moyenne glissante des dix dernières valeurs. Ensuite, faites publier au capteur non plus un simple nombre mais deux grandeurs (température et vitesse) — ce qui vous obligera à découvrir les messages personnalisés.
Voir une piste pour le nœud de moyenne
Créez moyenne.py sur le modèle de moniteur.py. Dans le constructeur, initialisez une liste vide self.valeurs = []. Dans le callback, ajoutez la valeur reçue, gardez seulement les dix dernières avec self.valeurs = self.valeurs[-10:], puis journalisez sum(self.valeurs)/len(self.valeurs). Déclarez-le dans setup.py et recompilez. Le motif est identique à celui du moniteur : c’est tout l’intérêt d’avoir compris la brique de base.
Tutoriels frères
- Simuler un bras robotisé avec ROS 2 — la suite directe : on donne un corps au robot.
- Lire et écrire des registres en Modbus TCP avec Python — l’autre versant : dialoguer avec les automates.
Pour aller plus loin
- 🔝 Retour au guide principal : Robotique industrielle open source
- Documentation officielle d’installation et tutoriels : docs.ros.org (section Jazzy).
- Tutoriel suivant conseillé : la simulation d’un bras robotisé.
FAQ
Puis-je installer ROS 2 sur Windows ou macOS ?
C’est possible mais nettement plus laborieux, et beaucoup d’outils restent pensés pour Linux. Le plus simple est une machine virtuelle Ubuntu 24.04, ou le sous-système Windows pour Linux. Pour apprendre sans frictions, Ubuntu natif ou en machine virtuelle reste le meilleur choix.
Pourquoi Python et pas C++ ?
L’interface Python de ROS 2 (rclpy) couvre tout ce dont on a besoin pour apprendre et prototyper, avec moins de cérémonie. Le C++ devient pertinent pour les nœuds très sensibles à la latence, mais le modèle (nœuds, canaux, abonnements) est rigoureusement le même.
Dois-je recompiler à chaque modification d’un fichier Python ?
Si vous avez compilé avec colcon build --symlink-install, les fichiers Python sont liés et pris en compte sans recompiler. Sinon, relancez colcon build après chaque changement.
À quoi sert le ROS_DOMAIN_ID ?
C’est un identifiant numérique qui isole les systèmes ROS 2 sur un même réseau. Deux machines avec le même identifiant se découvrent ; avec des identifiants différents, elles s’ignorent. Pratique pour faire cohabiter plusieurs projets sans interférence.