Utiliser des substitutions

Objectif : En savoir plus sur les substitutions dans les fichiers de lancement de ROS 2.

Niveau du didacticiel : Intermédiaire

Durée : 15 minutes

Arrière-plan

Les fichiers de lancement sont utilisés pour démarrer des nœuds, des services et exécuter des processus. Cet ensemble d’actions peut avoir des arguments qui affectent leur comportement. Des substitutions peuvent être utilisées dans les arguments pour offrir plus de flexibilité lors de la description de fichiers de lancement réutilisables. Les substitutions sont des variables qui ne sont évaluées que lors de l’exécution de la description de lancement et peuvent être utilisées pour acquérir des informations spécifiques comme une configuration de lancement, une variable d’environnement ou pour évaluer une expression Python arbitraire.

Ce didacticiel montre des exemples d’utilisation de substitutions dans les fichiers de lancement ROS 2.

Conditions préalables

Ce tutoriel utilise le package turtlesim. Ce didacticiel suppose également que vous êtes familiarisé avec creating packages.

Comme toujours, n’oubliez pas de sourcer ROS 2 dans chaque nouveau terminal que vous ouvrez.

Utiliser des substitutions

1 Créer et configurer le package

Créez un nouveau package de build_type ament_python appelé launch_tutorial :

ros2 pkg create launch_tutorial --build-type ament_python

À l’intérieur de ce package, créez un répertoire appelé launch :

mkdir launch_tutorial/launch

Enfin, assurez-vous d’ajouter des modifications au setup.py du package afin que les fichiers de lancement soient installés :

import os
from glob import glob
from setuptools import setup

package_name = 'launch_tutorial'

setup(
    # Other parameters ...
    data_files=[
        # ... Other data files
        # Include all launch files.
        (os.path.join('share', package_name), glob('launch/*launch.[pxy][yma]*'))
    ]
)

2 Fichier de lancement parent

Créons un fichier de lancement qui appellera et transmettra des arguments à un autre fichier de lancement. Pour ce faire, créez un fichier example_main.launch.py dans le dossier launch du package launch_tutorial.

from launch_ros.substitutions import FindPackageShare

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import PathJoinSubstitution, TextSubstitution


def generate_launch_description():
    colors = {
        'background_r': '200'
    }

    return LaunchDescription([
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource([
                PathJoinSubstitution([
                    FindPackageShare('launch_tutorial'),
                    'example_substitutions.launch.py'
                ])
            ]),
            launch_arguments={
                'turtlesim_ns': 'turtlesim2',
                'use_provided_red': 'True',
                'new_background_r': TextSubstitution(text=str(colors['background_r']))
            }.items()
        )
    ])

Dans le fichier example_main.launch.py, la substitution FindPackageShare est utilisée pour trouver le chemin vers le package launch_tutorial. La substitution PathJoinSubstitution est ensuite utilisée pour joindre le chemin à ce chemin de package avec le nom de fichier example_substitutions.launch.py.

PathJoinSubstitution([
    FindPackageShare('launch_tutorial'),
    'example_substitutions.launch.py'
])

Le dictionnaire launch_arguments avec les arguments turtlesim_ns et use_provided_red est passé à l’action IncludeLaunchDescription. La substitution TextSubstitution est utilisée pour définir l’argument new_background_r avec la valeur de la clé background_r dans le dictionnaire colors.

launch_arguments={
    'turtlesim_ns': 'turtlesim2',
    'use_provided_red': 'True',
    'new_background_r': TextSubstitution(text=str(colors['background_r']))
}.items()

3 Fichier de lancement d’exemple de substitutions

Créez maintenant un fichier example_substitutions.launch.py dans le même dossier.

from launch_ros.actions import Node

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess, TimerAction
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, PythonExpression


def generate_launch_description():
    turtlesim_ns = LaunchConfiguration('turtlesim_ns')
    use_provided_red = LaunchConfiguration('use_provided_red')
    new_background_r = LaunchConfiguration('new_background_r')

    turtlesim_ns_launch_arg = DeclareLaunchArgument(
        'turtlesim_ns',
        default_value='turtlesim1'
    )
    use_provided_red_launch_arg = DeclareLaunchArgument(
        'use_provided_red',
        default_value='False'
    )
    new_background_r_launch_arg = DeclareLaunchArgument(
        'new_background_r',
        default_value='200'
    )

    turtlesim_node = Node(
        package='turtlesim',
        namespace=turtlesim_ns,
        executable='turtlesim_node',
        name='sim'
    )
    spawn_turtle = ExecuteProcess(
        cmd=[[
            'ros2 service call ',
            turtlesim_ns,
            '/spawn ',
            'turtlesim/srv/Spawn ',
            '"{x: 2, y: 2, theta: 0.2}"'
        ]],
        shell=True
    )
    change_background_r = ExecuteProcess(
        cmd=[[
            'ros2 param set ',
            turtlesim_ns,
            '/sim background_r ',
            '120'
        ]],
        shell=True
    )
    change_background_r_conditioned = ExecuteProcess(
        condition=IfCondition(
            PythonExpression([
                new_background_r,
                ' == 200',
                ' and ',
                use_provided_red
            ])
        ),
        cmd=[[
            'ros2 param set ',
            turtlesim_ns,
            '/sim background_r ',
            new_background_r
        ]],
        shell=True
    )

    return LaunchDescription([
        turtlesim_ns_launch_arg,
        use_provided_red_launch_arg,
        new_background_r_launch_arg,
        turtlesim_node,
        spawn_turtle,
        change_background_r,
        TimerAction(
            period=2.0,
            actions=[change_background_r_conditioned],
        )
    ])

Dans le fichier example_substitutions.launch.py, les configurations de lancement turtlesim_ns, use_provided_red et new_background_r sont définies. Ils sont utilisés pour stocker les valeurs des arguments de lancement dans les variables ci-dessus et pour les transmettre aux actions requises. Ces substitutions LaunchConfiguration nous permettent d’acquérir la valeur de l’argument de lancement dans n’importe quelle partie de la description de lancement.

DeclareLaunchArgument est utilisé pour définir l’argument de lancement qui peut être passé depuis le fichier de lancement ci-dessus ou depuis la console.

turtlesim_ns = LaunchConfiguration('turtlesim_ns')
use_provided_red = LaunchConfiguration('use_provided_red')
new_background_r = LaunchConfiguration('new_background_r')

turtlesim_ns_launch_arg = DeclareLaunchArgument(
    'turtlesim_ns',
    default_value='turtlesim1'
)
use_provided_red_launch_arg = DeclareLaunchArgument(
    'use_provided_red',
    default_value='False'
)
new_background_r_launch_arg = DeclareLaunchArgument(
    'new_background_r',
    default_value='200'
)

Le nœud turtlesim_node avec le namespace défini sur la substitution turtlesim_ns LaunchConfiguration est défini.

turtlesim_node = Node(
    package='turtlesim',
    namespace=turtlesim_ns,
    executable='turtlesim_node',
    name='sim'
)

Ensuite, l’action ExecuteProcess appelée spawn_turtle est définie avec l’argument cmd correspondant. Cette commande fait un appel au service spawn du noeud turtlesim.

De plus, la substitution LaunchConfiguration est utilisée pour obtenir la valeur de l’argument de lancement turtlesim_ns afin de construire une chaîne de commande.

spawn_turtle = ExecuteProcess(
    cmd=[[
        'ros2 service call ',
        turtlesim_ns,
        '/spawn ',
        'turtlesim/srv/Spawn ',
        '"{x: 2, y: 2, theta: 0.2}"'
    ]],
    shell=True
)

La même approche est utilisée pour les actions change_background_r et change_background_r_conditioned qui modifient le paramètre de couleur rouge de l’arrière-plan de turtlesim. La différence est que l’action change_background_r_conditioned n’est exécutée que si l’argument new_background_r fourni est égal à 200 et que l’argument de lancement use_provided_red est défini sur True. L’évaluation à l’intérieur de IfCondition est effectuée à l’aide de la substitution PythonExpression.

change_background_r = ExecuteProcess(
    cmd=[[
        'ros2 param set ',
        turtlesim_ns,
        '/sim background_r ',
        '120'
    ]],
    shell=True
)
change_background_r_conditioned = ExecuteProcess(
    condition=IfCondition(
        PythonExpression([
            new_background_r,
            ' == 200',
            ' and ',
            use_provided_red
        ])
    ),
    cmd=[[
        'ros2 param set ',
        turtlesim_ns,
        '/sim background_r ',
        new_background_r
    ]],
    shell=True
)

4 Construire le package

Accédez à la racine de l’espace de travail et créez le package :

colcon build

N’oubliez pas non plus de sourcer l’espace de travail après la construction.

Exemple de lancement

Vous pouvez maintenant lancer le fichier example_main.launch.py en utilisant la commande ros2 launch.

ros2 launch launch_tutorial example_main.launch.py

Cela fera ce qui suit :

  1. Démarrer un nœud turtlesim avec un fond bleu

  2. Faire apparaître la deuxième tortue

  3. Changer la couleur en violet

  4. Changez la couleur en rose après deux secondes si l’argument background_r fourni est 200 et l’argument use_provided_red est True

Modification des arguments de lancement

Si vous souhaitez modifier les arguments de lancement fournis, vous pouvez soit les mettre à jour dans le dictionnaire launch_arguments dans example_main.launch.py ou lancer example_substitutions.launch.py avec les arguments préférés. Pour voir les arguments qui peuvent être donnés au fichier de lancement, exécutez la commande suivante :

ros2 launch launch_tutorial example_substitutions.launch.py --show-args

Cela montrera les arguments qui peuvent être donnés au fichier de lancement et leurs valeurs par défaut.

Arguments (pass arguments as '<name>:=<value>'):

    'turtlesim_ns':
        no description given
        (default: 'turtlesim1')

    'use_provided_red':
        no description given
        (default: 'False')

    'new_background_r':
        no description given
        (default: '200')

Vous pouvez maintenant passer les arguments souhaités au fichier de lancement comme suit :

ros2 launch launch_tutorial example_substitutions.launch.py turtlesim_ns:='turtlesim3' use_provided_red:='True' new_background_r:=200

Documentation

La documentation de lancement fournit des informations détaillées sur les substitutions disponibles.

Résumé

Dans ce didacticiel, vous avez appris à utiliser des substitutions dans les fichiers de lancement. Vous avez découvert leurs possibilités et capacités pour créer des fichiers de lancement réutilisables.

Vous pouvez maintenant en savoir plus sur l’utilisation des gestionnaires d’événements dans les fichiers de lancement qui sont utilisés pour définir un ensemble complexe de règles pouvant être utilisées pour modifier dynamiquement le fichier de lancement.