ros2 launch

本文详细介绍了ROS2中的Launch文件使用,包括基本格式、参数传递、节点映射、YAML类型、从命令行加载YAML参数、包含子Launch文件、LaunchConfiguration和条件替换等功能。此外,还讲解了如何重写YAML文件和从现有参数创建YAML文件。内容涵盖了ROS2开发中的关键知识点。
摘要由CSDN通过智能技术生成

ros2 design - 01 - laun file example
ros2 design - 02 - from a launch file

基本格式

返回LaunchDescription, 格式1

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    ld = LaunchDescription()
    
    talker_node = Node(
        package="demo_nodes_cpp",
        executable="talker",
    )
    
    ld.add_action(talker_node)
    return ld

返回LaunchDescription, 格式2

并列放在数组内

def generate_launch_description():
    return LaunchDescription([
    launch.actions.DeclareLaunchArgument(
            'node_prefix',
            default_value=[launch.substitutions.EnvironmentVariable('USER'), '_'],
            description='Prefix for node names'),
    
    launch_ros.actions.Node(
            package='demo_nodes_cpp', executable='talker', output='screen',
            name=[launch.substitutions.LaunchConfiguration('node_prefix'), 'talker']),
    launch_ros.actions.Node(...),
    ])

topic/service remapping

    talker_node = Node(
        package="demo_nodes_cpp",
        executable="talker",
    )
    
    listener_node = Node(
        package="demo_nodes_py",
        executable="listener",
        name="new_name",
        parameters=[
            {"background_b": 200},
            {"background_g": 200},
            {"background_r": 200}
        ],
        remappings=[
            ("chatter", "my_chatter")
        ]
    )

yaml types

  • Boolean value
  • Integer number
  • Float number
  • String
  • Array of all the 4 previous types
  • Array of bytes

load yaml from command line

把路径写全, 或者当前terminal 路径的相对路径

ros2 run ros2_tutorials test_yaml_params --ros-args --params-file ~/ros2_ws/src/ros2_tutorials/config/params.yaml

load yaml from a launch file

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
    ld = LaunchDescription()
    config = os.path.join(
        get_package_share_directory('ros2_tutorials'),
        'config',
        'params.yaml'
        )
        
    node=Node(
        package = 'ros2_tutorials',
        name = 'your_amazing_node',
        executable = 'test_yaml_params',
        parameters = [config]
    )
    ld.add_action(node)
    return ld

include child launch file

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import DeclareLaunchArgument

def generate_launch_description():
    package_prefix = get_package_share_directory('child_package')
    argument_for_child = "lala"

    return LaunchDescription([
        # Declare the launc parameter
        DeclareLaunchArgument(
            'argument_for_child',
            default_value = argument_for_child,
            description = 'Argument for child launch file'),

        # include the child launch file
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource([package_prefix, '/launch/child.launch.py'])
            launch_arguments = {'argument_for_child': argument_for_child}.items()
        ), # 参数非必须
    ])

launch.substitution

ros2 wiki
使用substitution需要外部替换参数的值,否则会引起错误,或者使用condition保护;
使用substitution功能,需要与DeclareLaunchArgument配合使用

LaunchDescription([
    launch.actions.DeclareLaunchArgument(
        "my_param",
        default_value=[""],  # default_value=[], has the same problem
        description="optional parameter"
    ),
    launch_ros.actions.Node(
        package="my_package",
        node_executable="my_node",
        arguments=[launch.substitutions.LaunchConfiguration("my_param", condition=launch.conditions.IfCondition(launch.substitutions.LaunchConfiguration("my_param"))]
    ),
])

RewrittenYaml

重新写入Yaml?
这个python 对象来自nav2_common
继承字launch.Substitution
功能是: Create our own temporary YAML files that include substitutions, 根据参数文件, 以及替换更新的部分参数,生成新的yaml 文件对象;

## 构造函数
def __init__(self,
        source_file: launch.SomeSubstitutionsType,
        param_rewrites: Dict,
        root_key: Optional[launch.SomeSubstitutionsType] = None,
        key_rewrites: Optional[Dict] = None,
        convert_types = False) -> None:
        super().__init__()
        """
        Construct the substitution
        :param: source_file the original YAML file to modify
        :param: param_rewrites mappings to replace
        :param: root_key if provided, the contents are placed under this key
        :param: key_rewrites keys of mappings to replace
        :param: convert_types whether to attempt converting the string to a number or boolean
        """

        from launch.utilities import normalize_to_list_of_substitutions  # import here to avoid loop
        self.__source_file = normalize_to_list_of_substitutions(source_file)
        self.__param_rewrites = {}
        self.__key_rewrites = {}
        self.__convert_types = convert_types
        self.__root_key = None
        for key in param_rewrites:
            self.__param_rewrites[key] = normalize_to_list_of_substitutions(param_rewrites[key])
        if key_rewrites is not None:
            for key in key_rewrites:
                self.__key_rewrites[key] = normalize_to_list_of_substitutions(key_rewrites[key])
        if root_key is not None:
            self.__root_key = normalize_to_list_of_substitutions(root_key)

source_file: string 类型, 表明yaml的全部路径
param_rewrites: 字典类型, 重新写入参数的键值对, key 为参数名, value 为LaunchConfiguration 变量对象,或者直接具体的值
convert_types: bool 类型,是否支持string 转换到bool ,int, 默认为True
key_rewrites: 字典类型,要替换的关键字 映射, 如果key 名字一样,则可为空, 如果不一样,就得搞关键字的映射了
root_key: Top-level namespace, 一般是名称空间的用法?

RewrittenYaml() 声明的对象很重要; 最后在Node对象中, 赋值给parameters 关键字

dump yaml file from existing params

ros2 param dump /your_amazing_node --print

yaml file example

第一行为node_name:
第二行为_ _ ros_parameters: (推荐缩进 2 或 4 空格)
注意,如果node_name不一致,则加载不会生效; 不会报错

your_amazing_node:
  ros__parameters:
    bool_value: True
    int_number: 5
    float_number: 3.14
    str_text: "Hello Universe"
    bool_array: [True, False, True]
    int_array: [10, 11, 12, 13]
    float_array: [7.5, 400.4]
    str_array: ['Nice', 'more', 'params']
    bytes_array: [0x01, 0xF1, 0xA2]
    nested_param:
      another_int: 7

也可以, 第一行为namespace, 后面行才是node_name

ns1:
  your_amazing_node:
    ros__parameters:
      bool_value: True
      ...

launch 文件应该也填写namespace 关键字

    node=Node(
        package = 'ros2_tutorials',
        namespace='ns1',
        name = 'your_amazing_node',
        executable = 'test_yaml_params',
        parameters = [config]
    )

ros2 代码实例化rclcpp::Node, 或者 rclcpp::LifeCycleNode 的字符串即为node_name, 与yaml 需要一致

其他语法

LaunchConfiguration is local to the launch file and scoped.

DeclareLaunchArgument allows you to expose the argument outside of your launch file. Allowing them to be listed, set, or marked as required when a user launches it from the command line (using ros2 launch) or when including it from another launch file (using IncludeLaunchDescription).

A LaunchConfiguration cannot be required to be set when launching or including and it is not possible to set it when launching from the command line. You can set a LaunchConfiguration before including another launch file, but an argument is better if you want it to be reused.

在launch 文件中, 一般用法是:
先在generate_launch_description() 函数中声明 LaunchConfiguration 变量,
再在LaunchDescription() 函数中,利用DeclareLaunchArgument() 再次声明上一步的变量,同时指明默认值和描述字符串;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值