乐于分享
好东西不私藏

机器人系统——ROS2文档(进阶)—使用替换

机器人系统——ROS2文档(进阶)—使用替换

目标:了解 ROS 2 启动文件中的替换。教程级别:中级时间: 15 分钟

目录

  • 背景
  • 前置条件
  • 使用替换
    • 创建并设置包
    • 父启动文件
    • 替换示例启动文件
    • 构建包
  • 启动示例
  • 修改启动参数
  • 布尔替换
  • 文档
  • 总结

本教程主要包括以下命令:

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

$ mkdir launch_tutorial/launch

$ colcon build
$ ros2 launch launch_tutorial example_main_launch.py
$ ros2 launch launch_tutorial example_substitutions_launch.py --show-args
$ ros2 launch launch_tutorial example_substitutions_launch.py turtlesim_ns:='turtlesim3' use_provided_red:='True' new_background_r:=200

背景

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

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

前置条件

本教程使用turtlesim包。本教程还假定您熟悉创建包。和往常一样,别忘了在打开的每个新终端中加载 ROS 2 环境。

使用替换

1创建并设置包

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

Python 包:创建一个构建类型为ament_python的新包:

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

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

$ mkdir launch_tutorial/launch

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

Python 包:在包的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('launch/*'))
]
)

2父启动文件

让我们创建一个启动文件,它将调用另一个启动文件并向其传递参数。这个启动文件可以是 YAMLXML  Python 格式。

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

Python将完整代码复制粘贴到launch/example_main_launch.py文件中:

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.substitutions import FindPackageShare
def generate_launch_description():
colors = {
'background_r': '200'
}
return LaunchDescription([
IncludeLaunchDescription(
PathJoinSubstitution([
FindPackageShare('launch_tutorial'),
'launch',
'example_substitutions_launch.py'
]),
launch_arguments={
'turtlesim_ns': 'turtlesim2',
'use_provided_red': 'True',
'new_background_r': colors['background_r'],
}.items()
)
    ])

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

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

提示:替换或字符串列表会被连接成一个字符串。这通常适用于任何支持替换的内容。例如,使用PathJoinSubstitution时,如果文件名前缀依赖于名为file的启动参数,可以使用替换和字符串列表来创建文件名:

# Make sure to import LaunchConfiguration:
# from launch.substitutions import LaunchConfiguration
PathJoinSubstitution([
FindPackageShare('launch_tutorial'),
'launch',
[LaunchConfiguration('file', default='example_substitutions'), '_launch', '.py']
])

在这种情况下,默认情况下,提供给PathJoinSubstitution的最后一个路径组件将解析为example_substitutions_launch.py,然后与其他路径组件连接。

带有turtlesim_nsuse_provided_red参数的launch_arguments字典被传递给IncludeLaunchDescription操作。

launch_arguments={
'turtlesim_ns': 'turtlesim2',
'use_provided_red': 'True',
'new_background_r': colors['background_r'],

}.items()

3替换示例启动文件

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

Python创建文件launch/example_substitutions_launch.py并插入以下代码:

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess, TimerAction
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch_ros.actions import Node
def generate_launch_description():
turtlesim_ns = LaunchConfiguration('turtlesim_ns')
use_provided_red = LaunchConfiguration('use_provided_red')
new_background_r = LaunchConfiguration('new_background_r')
return LaunchDescription([
DeclareLaunchArgument(
'turtlesim_ns',
default_value='turtlesim1'
),
DeclareLaunchArgument(
'use_provided_red',
default_value='False'
),
DeclareLaunchArgument(
'new_background_r',
default_value='200'
),
Node(
package='turtlesim',
namespace=turtlesim_ns,
executable='turtlesim_node',
name='sim'
),
ExecuteProcess(
cmd=[['ros2 service call ', turtlesim_ns, '/spawn ', 'turtlesim_msgs/srv/Spawn ', '"{x: 2, y: 2, theta: 0.2}"']],
shell=True
),
ExecuteProcess(
cmd=[['ros2 param set ', turtlesim_ns, '/sim background_r ', '120']],
shell=True
),
TimerAction(
period=2.0,
actions=[
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
),
],
)
    ])

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

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

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

定义了turtlesim_node节点,其namespace设置为turtlesim_nsLaunchConfiguration替换。

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

下一个操作ExecuteProcess使用相应的cmd参数定义,用于调用 turtlesim 节点的 spawn 服务。

此外,LaunchConfiguration替换用于在命令字符串中提供turtlesim_ns启动参数的值。

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

同样的方法用于改变 turtlesim 背景红色颜色参数的change_background_rchange_background_r_conditioned操作。不同之处在于,下一个操作仅在提供的new_background_r参数等于200use_provided_red启动参数设置为True时执行。IfCondition内部的评估使用PythonExpression替换完成。

TimerAction(
period=2.0,
actions=[
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命令进行启动。

Python

$ ros2 launch launch_tutorial example_main_launch.py

这将执行以下操作:

  1. 启动一个具有蓝色背景的 turtlesim 节点
  2. 生成第二只乌龟
  3. 将颜色更改为紫色
  4. 如果提供的background_r参数为200use_provided_red参数为True,则在两秒后将颜色更改为粉色

修改启动参数

Python如果您想更改提供的启动参数,您可以更新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':
无描述
(default: 'turtlesim1')
'use_provided_red':
无描述
(default: 'False')
'new_background_r':
无描述
(default: '200')

现在您可以按如下方式将所需参数传递给启动文件:

Python

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

布尔替换

除了$(eval <python-expression>)之外,还有一组专用的布尔替换可用于比较值和组合结果。它们可以在允许替换的任何地方使用,包括任何操作的ifunless属性。

注意:比较是在每个参数的字符串表示形式上执行的。

XML / YAML 名称

Python 

描述

$(equals A B)

EqualsSubstitution

如果 A 等于 B,则解析为 ‘true’,否则为 ‘false’

$(not-equals A B)

NotEqualsSubstitution

如果 A 不等于 B,则解析为 ‘true’,否则为 ‘false’

$(and A B)

AndSubstitution

两个布尔替换的逻辑与。

$(or A B)

OrSubstitution

两个布尔替换的逻辑或。

$(any A B ...)

AnySubstitution

如果任何参数为真,则解析为 ‘true’

$(all A B ...)

AllSubstitution

仅当每个参数都为真时才解析为 ‘true’

前一部分的if谓词也可以使用布尔替换而不是 Python 表达式来表示:

Python

from launch.conditions import IfCondition
from launch.substitutions import AndSubstitution, EqualsSubstitution, LaunchConfiguration
ExecuteProcess(
cmd=[['ros2 param set ', '/turtlesim background_r ', LaunchConfiguration('new_background_r')]],
condition=IfCondition(
AndSubstitution(
EqualsSubstitution(LaunchConfiguration('new_background_r'), '200'),
LaunchConfiguration('use_provided_red'),
)
),
)

文档

启动文档提供了有关可用替换的详细信息。

总结

在本教程中,您学习了在启动文件中使用替换的方法。您了解了它们创建可重用启动文件的可能性与能力。

现在您可以继续学习更多关于在启动文件中使用事件处理器的知识,这些处理器用于定义一组复杂的规则,可用于动态修改启动文件。

本文档完整翻译自 ROS 2 Lyrical 官方文档,仅用于学习交流。