使用替代

目标:了解 ROS 2 启动文件中的替换。

教程级别:中级

时间:15 分钟

背景

启动文件用于启动节点、服务和执行进程。 这组操作可能具有影响其行为的参数。 替换可用于参数中,以便在描述可重复使用的启动文件时提供更大的灵活性。 替换是仅在执行启动描述期间评估的变量,可用于获取特定信息,如启动配置、环境变量或评估任意 Python 表达式。

本教程展示了 ROS 2 启动文件中替换的使用示例。

先决条件

本教程使用 turtlesim 包。 本教程还假设您熟悉 creating packages

与往常一样,不要忘记在 每次打开新终端 中获取 ROS 2。

使用替换

1 创建并设置包

首先,创建一个名为 launch_tutorial 的新包:

创建 build_type 为“ament_python” 的新包:

ros2 pkg create --build-type ament_python --license Apache-2.0 launch_tutorial

在该包内,创建一个名为“launch”的目录:

mkdir launch_tutorial/launch

最后,确保安装启动文件:

对包的“setup.py”添加以下更改:

import os
from glob import glob
from setuptools import find_packages, setup

package_name = 'launch_tutorial'

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

2 父启动文件

让我们创建一个启动文件,它将调用另一个启动文件并将参数传递给它。

此启动文件可以是 Python 或 YAML。

为此,请在“launch_tutorial”包的“launch”文件夹中创建以下文件。

将完整代码复制并粘贴到“launch/example_main_launch.py​​”文件中:

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'),
                    'launch',
                    'example_substitutions_launch.py'
                ])
            ]),
            launch_arguments={
                'turtlesim_ns': 'turtlesim2',
                'use_provided_red': 'True',
                'new_background_r': TextSubstitution(text=str(colors['background_r']))
            }.items()
        )
    ])

FindPackageShare 替换用于查找 launch_tutorial 包的路径。 然后使用 PathJoinSubstitution 替换将该包路径的路径与 example_substitutions_launch.py​​ 文件名连接起来。

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

带有“turtlesim_ns”和“use_provided_red”参数的“launch_arguments”字典被传递给“IncludeLaunchDescription”操作。 “TextSubstitution”替换用于使用“colors”字典中“background_r”键的值来定义“new_background_r”参数。

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

3 替换示例启动文件

现在在同一文件夹中创建替换启动文件:

Create the file launch/example_substitutions_launch.py and insert the following code:

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],
        )
    ])

定义了 turtlesim_nsuse_provided_rednew_background_r 启动配置。 它们用于将启动参数的值存储在上述变量中​​,并将它们传递给所需的操作。 这些 LaunchConfiguration 替换允许我们在启动描述的任何部分获取启动参数的值。

DeclareLaunchArgument 用于定义可以从上述启动文件或控制台传递的启动参数。

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'
)

定义了将“namespace”设置为“turtlesim_ns”的“LaunchConfiguration”替换的“turtlesim_node”节点。

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

随后,使用相应的“cmd”参数定义名为“spawn_turtle”的“ExecuteProcess”操作。 此命令调用 turtlesim 节点的 spawn 服务。 此外,“LaunchConfiguration”替换用于获取“turtlesim_ns”启动参数的值以构造命令字符串。

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

相同的方法也用于改变 turtlesim 背景的红色参数的“change_background_r”和“change_background_r_condition”操作。 不同之处在于,只有当提供的“new_background_r”参数等于“200”并且“use_provided_red”启动参数设置为“True”时,才会执行“change_background_r_condition”操作。 “IfCondition”中的评估是使用“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 构建包

转到工作区的根目录,然后构建包:

colcon build

还要记住在构建后获取工作区。

启动示例

现在您可以使用“ros2 launch”命令启动。

ros2 launch launch_tutorial example_main_launch.py

This will do the following:

  1. 启动一个具有蓝色背景的 turtlesim 节点

  2. 生成第二只海龟

  3. 将颜色更改为紫色

  4. 如果提供的 background_r 参数为 200use_provided_red 参数为 True,则在两秒后将颜色更改为粉红色

修改启动参数

如果您想更改提供的启动参数,您可以在“example_main_launch.py​​”中的“launch_arguments”字典中更新它们,或者使用首选参数启动“example_substitutions_launch.py​​”。 要查看可能提供给启动文件的参数,请运行以下命令:

ros2 launch launch_tutorial example_substitutions_launch.py --show-args
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')

现在您可以将所需的参数传递给启动文件,如下所示:

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

文档

The launch documentation provides detailed information about available substitutions.

摘要

在本教程中,您了解了如何在启动文件中使用替换。

您了解了它们创建可重复使用的启动文件的可能性和功能。

您现在可以了解有关 在启动文件中使用事件处理程序 的更多信息,这些事件处理程序用于定义一组复杂的规则,可用于动态修改启动文件。