ROS2教程 10 launch

本文涉及的产品
资源编排,不限时长
简介: 这篇文章是关于ROS2(Robot Operating System 2)的launch文件的详细教程,包括如何创建和使用launch文件来启动ROS2节点,以及如何通过参数、命名空间和条件判断等高级特性来控制节点的启动行为。

常见的launch文件:
我们将节点的启动方式、名称、参数、输出等信息都通过 Node 类来描述,并将这个Node类添加到 LaunchDescription 实例中。
可以先单独生成不同节点的Node类实例,再将这些Node示例作为 LaunchDescription实例的参数

# turtlesim/launch/multisim.launch.py

from launch import LaunchDescription  # launch包中的一个类,用于描述和启动 ROS2节点和相关组件
import launch_ros.actions  # Node 是 ROS 2 中 launch_ros 包中的一个类,用于启动 ROS 2 节点
# 通常使用 from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            namespace= "turtlesim1", package='turtlesim', executable='turtlesim_node', output='screen'),
        launch_ros.actions.Node(
            namespace= "turtlesim2", package='turtlesim', executable='turtlesim_node', output='screen'),
    ])

常见的详细点儿的launch文件:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='turtlesim',
            namespace='turtlesim1',
            executable='turtlesim_node',
            name='sim'
        ),
        Node(
            package='turtlesim',
            namespace='turtlesim2',
            executable='turtlesim_node',
            name='sim'
        ),
        Node(
            package='turtlesim',
            executable='mimic',
            name='mimic',
            remappings=[
                ('/input/pose', '/turtlesim1/turtle1/pose'),
                ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
            ]
        )
    ])

在package.xml中添加依赖

<exec_depend>ros2launch</exec_depend>

包结构

src/
  package_name/
    launch/
    package.xml
    package_name/
    resource/
    setup.cfg
    setup.py
    test/

Inside your launch directory, create a new launch file called my_script_launch.py.

在 setup.py 中,package_data 和 data_files 都是用于描述软件包中包含的数据文件的参数。它们的区别在于:

package_data 参数用于包含软件包中特定包或模块下的数据文件。通常情况下,这些数据文件是与软件包中的某个 Python 模块或程序相关联的,例如配置文件、资源文件等。在使用 setuptools 打包 Python 软件包时,package_data 参数可以帮助将这些文件打包到软件包中,并在安装时将它们安装到指定的路径中。例如,package_data={
   'my_package': ['config/*', 'data/*']} 表示将软件包中 my_package 包中的 config 和 data 文件夹中的所有文件打包到软件包中。

data_files 参数用于包含软件包中非 Python 模块的数据文件。这些文件可以是软件包中的启动文件、仿真描述文件等与 Python 代码无关的文件。在使用 setuptools 打包 Python 软件包时,data_files 参数可以帮助将这些文件打包到软件包中,并在安装时将它们安装到指定的路径中。例如,data_files=[(os.path.join('share', package_name), glob('launch/*.launch.py'))] 表示将软件包中 launch 文件夹中所有扩展名为 .launch.py 的文件打包到软件包中。

因此,总的来说,package_data 适用于将软件包中与 Python 模块相关的数据文件打包到软件包中,而 data_files 适用于将与 Python 代码无关的数据文件打包到软件包中。在使用 setuptools 打包 Python 软件包时,这两个参数可以帮助你更好地管理软件包中的数据文件,并将它们正确地安装到指定路径下。

文件格式

import launch
import launch_ros.actions

def generate_launch_description():
    return launch.LaunchDescription([
        launch_ros.actions.Node(
            package='demo_nodes_cpp',
            executable='talker',
            name='talker'),
  ])

给定参数

# args that can be set from the command line or a default will be used
    background_r_launch_arg = DeclareLaunchArgument(
        "background_r", default_value=TextSubstitution(text="0")
    )

include另一个launch

   # include another launch file
    launch_include = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(
                get_package_share_directory('demo_nodes_cpp'),
                'launch/topics/talker_listener.launch.py'))
    )

给定命名空间启动节点

# start a turtlesim_node in the turtlesim1 namespace
    turtlesim_node = Node(
            package='turtlesim',
            namespace='turtlesim1',
            executable='turtlesim_node',
            name='sim'
        )

给定命名空间并给定参数值

   # and use args to set parameters
    turtlesim_node_with_parameters = Node(
            package='turtlesim',
            namespace='turtlesim2',
            executable='turtlesim_node',
            name='sim',
            parameters=[{
   
                "background_r": LaunchConfiguration('background_r'),
                "background_g": LaunchConfiguration('background_g'),
                "background_b": LaunchConfiguration('background_b'),
            }]
        )

节点末尾

    return LaunchDescription([
        background_r_launch_arg,
        background_g_launch_arg,
        background_b_launch_arg,
        chatter_ns_launch_arg,
        launch_include,
        launch_include_with_namespace,
        turtlesim_node,
        turtlesim_node_with_parameters,
        forward_turtlesim_commands_to_second_turtlesim_node,
    ])

基本格式

launch文件需要有generate_launch_description()函数以及它返回的launch.LaunchDescription(),这使得它能被ros2 launch命令使用。

import launch
import launch_ros.actions

def generate_launch_description():
    return launch.LaunchDescription([
        launch_ros.actions.Node(
            package='demo_nodes_cpp',
            executable='talker',
            name='talker'),
  ])

修改setup.py

为了使Colcon编译工具能找到launch文件,需要设置setup()的data_files参数来通知Python中使用launch文件的 setuptools。
在setup.py文件中:

import os
from glob import glob
from setuptools import setup

package_name = 'py_launch_example'

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

为Launch文件添加依赖

当包中有launch文件时,在package.xml中添加

<exec_depend>ros2launch</exec_depend>

编译

colcon build --symlink-install

运行Launch文件

ros2 launch <package_name> <launch_file_name>

1

上面的所有启动文件都启动了一个包含三个节点的系统,全部来自turtlesim包。该系统的目标是启动两个 turtlesim 窗口,让一只乌龟模仿另一只乌龟的动作。

启动两个 turtlesim 节点时,它们之间的唯一区别是它们的命名空间值。唯一的命名空间允许系统启动两个节点而不会出现节点名称或主题名称冲突。该系统中的两只海龟都接收关于同一主题的命令,并在同一主题上发布它们的姿势。使用唯一的命名空间,可以区分发往不同海龟的消息。

最后一个节点也来自turtlesim包,但不同的可执行文件:mimic. 此节点以重新映射的形式添加了配置详细信息。 mimic的/input/pose主题被重新映射到/turtlesim1/turtle1/pose并且它的/output/cmd_vel主题是/turtlesim2/turtle1/cmd_vel。这意味着mimic将订阅/turtlesim1/simpose 主题并将其重新发布为/turtlesim2/sim要订阅的 velocity command 主题。换句话说,turtlesim2会模仿turtlesim1的动作。

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='turtlesim',
            namespace='turtlesim1',
            executable='turtlesim_node',
            name='sim'
        ),
        Node(
            package='turtlesim',
            namespace='turtlesim2',
            executable='turtlesim_node',
            name='sim'
        ),
        Node(
            package='turtlesim',
            executable='mimic',
            name='mimic',
            remappings=[
                ('/input/pose', '/turtlesim1/turtle1/pose'),
                ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
            ]
        )
    ])

Reference : The Disign of Launch in ROS2
Reference : ROS2 Launch Documentation

嵌套启动的主启动文件案例

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

条件判断

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

launch_ros和launch中Node类的区别
在 ROS 2 中,launchlaunch_ros 模块中都有 Node 类,它们的主要区别在于提供的参数不同。

launch 模块中的 Node 类提供了一些常用的参数,例如节点名称、命名空间、要运行的可执行文件路径、节点参数等。例如,以下是使用 launch 模块中的 Node 类启动 ROS 节点的示例代码:

from launch import LaunchDescription
from launch.actions import Node

def generate_launch_description():
    ld = LaunchDescription()

    node = Node(
        package='my_package',
        executable='my_node',
        name='my_node',
        parameters=[{
   'my_parameter': 123}]
    )
    ld.add_action(node)

    return ld

在这个例子中,我们使用 launch 模块中的 Node 类创建了一个 ROS 节点,并指定了节点名称、要运行的可执行文件路径以及节点参数。

launch_ros 模块中的 Node 类提供了一些 ROS 特定的参数,例如节点名称、命名空间、节点命名空间、发布者和订阅者的 QoS 配置等。例如,以下是使用 launch_ros 模块中的 Node 类启动 ROS 节点的示例代码:

from launch import LaunchDescription
from launch_ros.actions import Node
from rclpy.qos import qos_profile_default

def generate_launch_description():
    ld = LaunchDescription()

    node = Node(
        package='my_package',
        executable='my_node',
        name='my_node',
        namespace='my_namespace',
        node_namespace='/my_namespace',
        parameters=[{
   'my_parameter': 123}],
        remappings=[('my_topic', 'my_renamed_topic')],
        qos_profile=qos_profile_default
    )
    ld.add_action(node)

    return ld

在这个例子中,我们使用 launch_ros 模块中的 Node 类创建了一个 ROS 节点,并指定了节点名称、命名空间、节点命名空间、节点参数、重映射规则以及发布者和订阅者的 QoS 配置。

总之,launch 模块中的 Node 类提供了一些常用的参数,适用于大多数 ROS 节点的启动;而 launch_ros 模块中的 Node 类提供了一些 ROS 特定的参数,适用于一些需要定制化的 ROS 节点的启动。你可以根据具体需求选择使用哪个类。

同样的对于launch和launch_ros模块来说
在 ROS 2 中,launch 和 launch_ros 是两个不同的 Python 模块,用于启动 ROS 2 节点。它们的主要区别在于功能和提供的类不同。

launch 模块提供了一些通用的功能,例如加载和运行 launch 文件、设置环境变量、启动 ROS 节点、启动进程等。此外,launch 模块还提供了一些常用的类,例如 LaunchDescription 类和 Node 类。LaunchDescription 类用于描述整个启动文件,包括要启动的节点、参数、重映射规则等;Node 类用于启动 ROS 节点,提供了一些常用的参数,例如节点名称、命名空间、要运行的可执行文件路径、节点参数等。

launch_ros 模块提供了一些 ROS 特定的功能,例如设置 ROS 2 命名约定、发布者和订阅者的 QoS 配置、加载参数文件等。此外,launch_ros 模块还提供了一些 ROS 特定的类,例如 Node 类和 LifecycleNode 类。Node 类用于启动 ROS 节点,提供了一些 ROS 特定的参数,例如节点名称、命名空间、节点命名空间、发布者和订阅者的 QoS 配置等;LifecycleNode 类用于启动 ROS 2 生命周期节点,提供了一些 ROS 生命周期相关的参数和方法。

综上所述,launch 模块提供了一些通用的功能和类,适用于大多数的启动文件;而 launch_ros 模块提供了一些 ROS 特定的功能和类,适用于一些需要定制化的 ROS 节点的启动。

变量的声明:
使用 DeclareLaunchArgument 类声明了一个名为 node_name 的启动参数,并设置了默认值和描述信息。接下来,我们使用 Node 类创建了一个 ROS 2 节点,并使用 LaunchConfiguration 类将启动参数值传递给节点的名称。这意味着,节点的名称将从启动文件中的 node_name 参数中读取,并在启动时传递给节点。这样,你就可以通过修改启动文件中的参数值来更改节点的名称,而无需修改 Python 代码。

总之,LaunchConfiguration 类是 ROS 2 启动文件的参数类,用于从启动文件的参数中读取值,例如节点的名称、参数值、命名空间等。你可以在 Node 类或其他操作中使用 LaunchConfiguration 类将参数值传递给节点或其他操作。

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration

def generate_launch_description():
    ld = LaunchDescription()

    # Declare a launch argument for the node name
    node_name = DeclareLaunchArgument(
        'node_name',
        default_value='my_node',
        description='Name of the ROS node'
    )
    ld.add_action(node_name)

    # Create the ROS 2 node with the given name
    node = Node(
        package='my_package',
        executable='my_node',
        name=LaunchConfiguration('node_name')
    )
    ld.add_action(node)

    return ld
相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
目录
相关文章
|
18天前
|
Ubuntu 机器人 Linux
|
3月前
|
机器人 C++ Python
ROS2教程 02 功能包
本文是关于ROS2(机器人操作系统2)中功能包(package)管理的教程,介绍了如何检查功能包的依赖、创建新功能包、列出可执行文件、列出所有功能包、查询功能包的位置和描述信息,以及为C++和Python功能包配置必要的文件。
91 0
|
18天前
|
传感器 数据可视化 机器人
【ROS速成】半小时入门机器人ROS系统简明教程之可视化系统(三)
半小时入门机器人ROS系统简明教程之可视化系统
|
18天前
|
机器人
【ROS速成】半小时入门机器人ROS系统简明教程之安装测速(二)
半小时入门机器人ROS系统简明教程之安装测速
|
3月前
|
XML 存储 网络安全
ROS入门(二):launch文件解析
该文章是关于ROS入门的第二篇教程,详细解析了ROS中的launch文件,包括其运行方式、XML格式规范、标签使用、参数替代、条件属性以及通过简单和复杂案例来演示launch文件的使用,最后介绍了如何在参数服务器上设置参数。
ROS入门(二):launch文件解析
|
3月前
|
存储 自然语言处理 机器人
ROS2教程06 ROS2行动
这篇文章是关于ROS2(Robot Operating System 2)行动(Action)通信机制的教程,包括行动的概念、特点、命令行工具的使用,以及如何编写行动的客户端和服务器代码,并介绍了如何测试行动通信。
107 4
ROS2教程06 ROS2行动
|
3月前
|
机器人 Shell Python
ROS2教程05 ROS2服务
这篇文章是关于ROS2(Robot Operating System 2)服务的教程,涵盖了服务的概念、特性、命令行工具的使用,以及如何编写服务的服务器和客户端代码,并提供了测试服务通信机制的示例。
71 4
ROS2教程05 ROS2服务
|
3月前
|
传感器 算法 数据可视化
ROS2教程04 ROS2话题
这篇文章是关于ROS2(Robot Operating System 2)的教程,主要介绍了ROS2中话题的概念、特性、使用方式,以及如何编写发布者和订阅者的代码。
73 3
ROS2教程04 ROS2话题
|
3月前
|
存储 Ubuntu 安全
ROS2教程02 ROS2的安装、配置和测试
本文是关于ROS2(机器人操作系统2)的安装、配置和测试的教程。内容包括使用一键安装脚本快速安装ROS2 Humble版,手动安装步骤,设置语言环境、添加软件源、更新软件包、安装ROS2桌面版和开发工具,配置ROS2环境,创建工作空间,配置ROS2领域以避免网络冲突,以及如何删除ROS2。此外,还包括了测试ROS2是否安装成功的两个案例:基本的Topic通信测试和使用Turtlesim演示程序。适用于Ubuntu 22.04操作系统。
203 1
ROS2教程02 ROS2的安装、配置和测试
|
3月前
|
传感器 存储 Ubuntu
Azure Kinect DK + ROS1 Noetic使用教程
本文是Azure Kinect DK在Ubuntu20.04下配合ROS1 Noetic使用的教程,内容包括一键安装脚本、硬件介绍、安装SDK相关软件包、设置Udev规则、SDK基本测试、DK ROS基本测试,以及存在的一些重要缺陷和相关参考文献。教程详细指导了如何配置和使用Azure Kinect DK,提供了安装步骤和解决常见问题的方法。
123 1
Azure Kinect DK + ROS1 Noetic使用教程

推荐镜像

更多