ros2 launch 用法以及一些基础功能函数的示例

前言

ros2 launch文件中最主要的概念是action,ros2 launch把每一个要执行的节点,文件,脚本,功能等全部抽象成action,用统一的接口来控制其启动,最主要的结构是:

def generate_launch_description():return LaunchDescription([action_1,action_2,...action_n])

要启动的节点或其他launch文件全部都传入LaunchDescription()函数中,该函数中接受一个或多launch.actionslaunch_ros.actions类型的对象,以下列举一下常用的action:

launch_ros.actions.Node· 此函数功能是启动一个ros2节点;
launch_ros.actions.PushRosNamespace· 此函数功能是给一个节点或组设置命名空间;
launch.actions.IncludeLaunchDescription· 此函数功能是直接引用另一个launch文件;
launch.actions.SetLaunchConfiguration· 此函数功能是在launch文件内声明一个参数,并给定参数值;
launch.actions.SetEnvironmentVariable· 此函数功能是声明一个环境变量并给定环境变量的值;
launch.actions.AppendEnvironmentVariable· 此函数将对一个环境变量追加一个值,如果不存在则创建;
launch.actions.DeclareLaunchArgument· 此函数功能是声明一个启动描述参数,该参数具有名称、默认值和文档;
launch.actions.TimerAction· 此函数功能是在一段时间后执行一个或多个action;
launch.actions.GroupAction· 此函数功能是将action分组,同组内的action可以统一设定参数方便集中管理;
launch.actions.ExecuteProcess· 此函数功能是根据输入执行一个进程或脚本;
launch.actions.EmitEvent· 此函数功能是发出一个事件,触发以注册的事件函数被调用;
launch.actions.RegisterEventHandler· 此函数功能是注册一个事件;
launch.actions.UnregisterEventHandler· 此函数功能是删除一个注册过的事件;
  1. 启动一个节点的launch示例

    from launch import LaunchDescription
    from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')])
    

    或者:

    from launch import LaunchDescription
    from launch_ros.actions import Nodedef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')return LaunchDescription([action_1])
    

    launch文件名为test.launch.py,调用launch文件启动节点:

    ros2 launch ros2_test test.launch.py
    
  2. launch文件中添加节点的namespace

    from launch import LaunchDescription
    from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen',namespace='my_ros2_test')])
    

    设置了namespace后,此节点的话题前会加上namespace的前缀,例如原来的话题名称’/test’,设置后变为’/my_ros2_test/test’

    注意,有以下情况namespace无效:

    • 节点本来就已经有了namespace了,后续会介绍将节点分组,整组节点可以设置统一的namespace,此时如果有个节点已经设置过namespace,则在此设置不会生效;
    • 定义发布节点的时候,topic名字的前面加上了符号/
  3. launch文件中的话题名称映射

    话题映射的字段是remappings,语法示例如下:

    remappings=[('src1', 'dest1'),('src2', 'dest2'),...
    ]
    

    如果需要话题名称映射的话要将该字段加入到节点的函数内,假如节点内有个test1话题要映射到test2,示例如下:

    from launch import LaunchDescription
    from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",remappings=[("test1", "test2")])])
    
  4. launch文件中向节点内传入命令行参数

    参数字段是arguments,语法示例如下:

    arguments=['arg1', 'arg2', ...]
    

    如果需要向ros2_test_publisher_node节点中传入命令行参数,示例如下:

    from launch import LaunchDescription
    from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",arguments=['arg1', 'arg2'])])
    

    传入的参数可以从节点启动时main函数中的argc参数获取到参数个数,argv参数获取到参数内容,详情参考c++的命令行参数获取;

  5. launch文件中向节点内传入rosparam

    字段是parameter,语法示例如下:

    parameters=[{'port': '/dev/ttyUsb0'},...
    ]
    

    如果需要在launch文件中发布某个节点空间下的parameter,示例如下:

    from launch import LaunchDescription
    from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",parameter=[{'port': '/dev/ttyUSB0'}])])
    

    如果需要参数的值可以从外部调用launch文件时灵活更改,则可以使用变量的形式作为参数的值,在文件中给定默认值,若外部给定则以外部给定的值为准,若外部不给则以默认值为准:

    port_var = LaunchConfiguration('port', default='/dev/ttyS1')

    同时还可以使用DeclareLaunchArgument函数增加对参数的描述,增加描述后可以通过ros2 launch的命令行工具展示出每个launch文件中有哪些rosparam以及他的默认值和具体含义:

    DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'
    )
    

    如果文件中加入了参数介绍则可以通过以下指令看到launch文件中有哪些可以自定义的参数以及参数含义:

    ros2 launch ros2_test test.launch.py --show-args

    所以如果launch文件中存在可配置参数,应该在LaunchDescription中添加DeclareLaunchArgument,让其他使用者明白变量名,以及他的含义是什么;

    完整的launch文件如下:

    from launch import LaunchDescription
    from launch_ros.actions import Node
    from launch.substitutions import LaunchConfigurationdef generate_launch_description():port_var = LaunchConfiguration('port', default='/dev/ttyS1')return LaunchDescription([DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",parameter=[{'port': port_var}])])
    

    此时我们可以把参数通过调用launch的时候传入到节点中:

    ros2 launch ros2_test test.launch.py port_var:=/dev/ttyUSB2
    

    在ros2_test_publisher_node节点中如果要想获取该参数,需要先声明parameter,然后再进行get:

    this->declare_parameter<std::string>("port");
    string port_str;
    this->get_parameter_or<std::string>("port", port_str, "null");
    if (port_str != "null") RCLCPP_INFO(this->get_logger(), "get ros2param port value : %s", port_str.c_str());
    
  6. 在launch文件中使用条件变量

    字段是condition,语法示例如下:

    condition=IfCondition(variable)

    IfCondition(variable)函数内只接受true, false, 0, 1参数,如果节点启动的描述中加入该字段并且参数值为false或0则节点不启动

    完整的launch文件如下:

    from launch import LaunchDescription
    from launch_ros.actions import Node
    from launch.substitutions import LaunchConfiguration
    from launch.conditions import IfConditiondef generate_launch_description():variable = LaunchConfiguration('start_flag', default='true')return LaunchDescription([DeclareLaunchArgument('start_flag',default_value=variable,description='This is the ros2_test_publisher_node start flag'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",condition=IfCondition(variable))])
    

    此时

    运行:ros2 launch ros2_test test.launch.py 节点会正常启动

    运行:ros2 launch ros2_test test.launch.py start_flag:=false 节点不会启动

    进阶的IfCondition函数使用方式:

    由于LaunchConfiguration()函数的返回是一个对象,所以我们不可以拿来直接做运算,但是可以使用PythonExpression()做参数的表达式运算,语法如下:

    PythonExpression([variable, '== 1']) 或
    PythonExpression([variable, '+ 1 == 2']) 或
    PythonExpression([variable, "== 'test'"]) 等等
    

    完整的launch文件如下:

    from launch import LaunchDescription
    from launch_ros.actions import Node
    from launch.substitutions import LaunchConfiguration
    from launch.conditions import IfConditiondef generate_launch_description():port_var = LaunchConfiguration('port', default='/dev/ttyS1')return LaunchDescription([DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",condition=IfCondition(PythonExpression([port_var, "== '/dev/ttyUSB0'"])))])
    

    此时

    运行:ros2 launch ros2_test test.launch.py 节点不会启动

    运行:ros2 launch ros2_test test.launch.py port_var:=/dev/ttyUSB0 节点正常启动

  7. action的分组

    GroupAction()函数可以将一个或多个action加入到一个组中,组内可以共用参数,控制整组节点全部启动或全部不启动等,方便action的管理,需要接受的部分参数有:

    • actions:接受一个list, [action_1, action_2,…],列表中装要执行的action

    • condition:条件变量参数

    • launch_configuration:参数

    完整的launch文件如下:

    from launch import LaunchDescription
    from launch_ros.actions import Node
    from launch.actions import GroupAction
    from launch_ros.actions import PushRosNamespacedef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen',namespace='my_ros2_test')action_2 = Node(package='ros2_test',executable='ros2_test_subscriber_node',name='ros2_test_subscriber_node',output='screen')test_group = GroupAction(actions=[PushRosNamespace("my_group_test"),action_1, action_2])return LaunchDescription([test_group])
    

    示例代码中PushRosNamespace()函数的作用是向test_group中设置组内的namespace,但是action_1中已经设置过了namespace,所以此时不会生效,该namespace只会在action_2中生效;

  8. action的启动延时控制

    TimerAction()函数可以在指定的时间后执行一个action,需要接受参数有

    • period:接受一个float, 延迟的时间
    • actions:接受一个list, [action_1, action_2,…],列表中装要执行的action

    完整的launch文件如下:

    from launch import LaunchDescription
    from launch_ros.actions import Node
    from launch.actions import TimerActiondef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')return LaunchDescription([TimerAction(period=5.0, actions=[action_1])])
    
  9. 在launch文件中调用另一个launch文件

    在launch文件中调用其他launch需要调用PythonLaunchDescriptionSource()函数,参数是被调用launch的路径,示例如下:

    import os
    from ament_index_python import get_package_share_directory
    from launch import LaunchDescription
    from launch.launch_description_sources import PythonLaunchDescriptionSource
    from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen'),PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('ros2_test'),'launch/test_subscriber.launch.py'))])
    

    还可以更复杂一点的写法,可以像启动节点一样,加入条件以及参数等,示例如下:

    from launch.launch_description_sources import PythonLaunchDescriptionSource
    from launch.substitutions import ThisLaunchFileDir
    from launch.conditions import IfCondition
    from launch.substitutions import LaunchConfiguration
    from launch.actions import IncludeLaunchDescriptiondef generate_launch_description():inlucde_other_file = LaunchConfiguration('inlucde_other_file', default='true')test_var = LaunchConfiguration('test_var', default='test_var_2')return launch.LaunchDescription([IncludeLaunchDescription(PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/test_subscriber.launch.py']),condition=IfCondition(inlucde_other_file),launch_arguments={'test_var': test_var}.items())])
    
  10. 在launch文件中运行脚本

    from launch import LaunchDescription
    from launch.actions import ExecuteProcessdef generate_launch_description():return LaunchDescription([ExecuteProcess(cmd=['ros2', 'run', 'ros2_test', 'ros2_test_publisher_node'],output="screen")])
    

    以上脚本同样可实现启动ros2_test_publisher_node节点,同时ExecuteProcess()函数还支持condition、additional_env等参数的设置;

  11. 在launch文件中设置环境变量或读取环境变量

    SetEnvironmentVariable(var_name, var_value)函数用于设置环境变量,接受两个参数分别是要设置的环境变量名称和环境变量的值;

    EnvironmentVariable(var_name)函数用于获取环境变量的值,返回值类型是一个对象,输入参数是要获取的环境变量名称;

    完整的launch文件如下:

    from launch import LaunchDescription
    from launch.actions import SetEnvironmentVariable, ExecuteProcess
    from launch.substitutions import EnvironmentVariabledef generate_launch_description():return LaunchDescription([SetEnvironmentVariable('PRODUCT_MODEL', 'spray_robot'),ExecuteProcess(cmd=['echo', EnvironmentVariable('PRODUCT_MODEL')],output='screen')])
    

    运行以上脚本会看到如下输出:

    [INFO] [echo-1]: process started with pid [195168]
    [echo-1] spray_robot
    [INFO] [echo-1]: process has finished cleanly [pid 195168]
    

至此,ros2 launch 的基础功能介绍结束;

ros2 launch 用法以及一些基础功能函数的示例相关推荐

  1. python基础函数及用法意思_Python基础之函数基本用法与进阶详解

    本文实例讲述了Python基础之函数基本用法与进阶.分享给大家供大家参考,具体如下: 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数 ...

  2. PCL common中常见的基础功能函数

    这里将分享我使用PCL库的遇到的一些坑,以及总结的技巧,当然也需要各位能够多多分享,将公众号的文章或者知识星球的文章转发到朋友圈. pcl_common中主要是包含了PCL库常用的公共数据结构和方法, ...

  3. 面试-重写基础功能函数

    重写基础函数 1. 字符串拷:strcpy() 函数strcpy的原型是char* strcpy(char* des , const char* src),des 和 src 所指内存区域不可以重叠且 ...

  4. C语言基础-fscanf函数使用示例

    fscanf()函数 头文件:stdio.h 函数定义:int fscanf(FILE * stream, const char *format, [argument-]); stream:文件指针 ...

  5. python中使用函数的优点_Python基础之函数基本用法与进阶详解

    本文实例讲述了Python基础之函数基本用法与进阶.分享给大家供大家参考,具体如下: 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数 ...

  6. python中symbols函数用法_Python基础之函数用法实例详解

    本文以实例形式较为详细的讲述了Python函数的用法,对于初学Python的朋友有不错的借鉴价值.分享给大家供大家参考之用.具体分析如下: 通常来说,Python的函数是由一个新的语句编写,即def, ...

  7. MATLAB三维绘图基础meshgrid函数的用法解析

    MATLAB三维绘图基础meshgrid函数的用法解析   MATLAB中meshgrid函数是用来生成网格的,函数用法是:   [X,Y] = meshgrid(x,y);这种是最常用的一种用法.x ...

  8. python中字符串函数的作用_python 基础学习笔记(2)---字符串功能函数

    **上一篇写到了,基本的数据类型,今天重点来讲一下字符串的功能函数** 回顾一下上篇的内容: 一.int 整型,在python 3 中与long型合并 可以达到 -922337203685477580 ...

  9. mysql中sql语句中常见的group_concat()函数意思以及用法,oracle中与其一样的功能函数是wmsys.wm_concat()

    1.group_concat(),手册上说明:该函数返回带有来自一个组的连接的非NULL值的字符串结果.比较抽象,难以理解. 通俗点理解,其实是这样的:group_concat()会计算哪些行属于同一 ...

  10. ROS2学习笔记(十)-- ROS2 launch启动文件

    简介:接触过ROS1的同学对launch肯定不陌生,在ROS1中,我们常用launch实现node和master同时启动.多节点同时启动配置等功能,ROS2中的launch也是用于多节点启动.配置功能 ...

最新文章

  1. P4588 [TJOI2018]数学计算(线段树维护区间乘和单点修改)
  2. 回归插补法_用均值替换、 回归插补及多重插补进行插补
  3. python3用什么系统好_学python用什么系统【怎么学好python】
  4. [BUUCTF-pwn]——others_shellcode
  5. 真正爱你的女人是这样的
  6. JavaIO流加解密,AES对字符串加解密
  7. 全局安装python_python pip 安装与使用
  8. 2020 BrandZ全球品牌价值排行榜100强发布 TikTok首次上榜
  9. 五子棋 鼠标 C语言,c语言写的鼠标操作的五子棋游戏,欢迎观赏!
  10. 引入阿里icon库的方法(font-class 引用)
  11. 禁止Unity3D中的物体碰撞后旋转
  12. 开源好项目|码市 AndroidiOS App 源码开源
  13. 水果店做生意不好怎么办,水果店生意不好如何做好
  14. 深度神经网络为什么有效,神经网络处理什么问题
  15. 内存泄漏导致的浏览器崩溃
  16. W ndoWs电脑上的线怎么接,win7一台电脑两个显示器的连接方法介绍
  17. 深入理解CDC原理与Debezium数据接入流程和原理
  18. word文档参考文献如何自动编号
  19. JS逆向:【硬干货】手把手实战某条_signature参数破解(下)——WebSocket与JS函数
  20. hyper-v 无法移除问题

热门文章

  1. 花老湿学习OpenCV:Shi-Tomasi角点检测
  2. android版本下载京东,手机京东历史版本
  3. 不可不知的设计师接活报价公式
  4. 当硅谷码农还在吃着火锅唱着歌,工作已经快没了
  5. 使用geohash实现查找附近的人
  6. linux ftp client安装,Linux 离线安装 FTP客户端
  7. 【富文本】2.windows或office原版镜像怎么下载,msdn.itellyou上面列的项目的详细解读
  8. 我爱 Ruby 的三十七个理由
  9. 数字万用表各指标含义:准确度(精度)分辨力(分辨率)测量范围--转
  10. 陇原战“疫“2021网络安全大赛 Re