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

2023-05-16

        简介:接触过ROS1的同学对launch肯定不陌生,在ROS1中,我们常用launch实现node和master同时启动、多节点同时启动配置等功能,ROS2中的launch也是用于多节点启动、配置功能,但是在使用方法上有了很多不同,ROS1只支持xml格式的.launch文件配置,ROS2在兼容xml的基础上,还支持yaml和python格式,而python格式的launch是我的学习重点,因为相对于另外两种配置方式,使用python更加灵活:

  • python拥有众多的函数库,可以在启动文件中使用;
  • ROS2通用启动特性和特定启动特性是用Python编写的,因此可以访问XML和YAML可能没有公开的启动特性;

        注:ROS1到ROS2的启动文件迁移,可以参考官方文档相关教程。

        接下来,我们先学习launch常规简单的用法。


目录

1、创建launch文件启动多个节点

2、为每个节点创建自己的launch文件

2.1 单节点启动文件

2.2 多节点启动文件

3、启动文件的其他配置功能

3.1 节点参数配置

3.1.1 在启动文件中设置

3.1.2 在启动文件中加载yaml配置文件

3.2 主题的重映射

3.3 环境变量引用


1、创建launch文件启动多个节点

        与ROS1类似,我们可以把多个节点启动配置直接写到同一个launch文件内直接启动,例如同时启动duckiebot和control两个节点:

$ cd ~/ros2_ws
$ mkdir launch
$ touch launch/both_launch.py

        编辑both_launch.py文件内容如下:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='duckiebot',
            namespace='duckietown',
            executable='duckiebot_node',
            name='duckiebot_node1'
        ),
        Node(
            package='control',
            namespace='duckietown',
            executable='control_node',
            name='control_node1'
        )
    ])

        该文件配置启动了两个节点,同时设定了一些配置,其中package和executable我们对比ros2 run命令来理解:

$ ros2 run <package> <executable>

        namespace和name我们用一个实际例子来理解,保存上述文件,配置环境变量,通过ros2 launch命令启动该文件:

$ source install/setup.bash
$ ros2 launch launch/both_launch.py

        启动后,可以通过方向键控制小车行走,可以通过tab键切换地图,可以通过W/A/D键实现直行、左转与右转,这些都是我们之前完成的功能。

        然后新开一个终端,执行几个命令:

$ ros2 node list

$ ros2 node info /duckietown/duckiebot_node1

        由以上测试可知,namespace就是在节点的名称、主题、服务、动作原有名称之前增加了一个字段,这个功能可以用来区分多个相同功能的节点,例如在同一个域内有若干台相同的机器人,那么每个机器人都应该有自己的namespace,否则就乱套了;而name就是重新指定了节点运行时的名称,会覆盖代码中的设定。

2、为每个节点创建自己的launch文件

        上文介绍了一个launch文件启动多个节点的方法,但是在大型项目中,一般不会使用上述方法,原因是可维护性太差,大型项目功能节点会比较多,每个功能节点都可能有自己的特殊配置,而且节点的实现可能来自于多个开发人员,由一个启动文件来启动配置所有节点就不太方便了,所以一般的做法是每个节点都维护自己启动文件,然后用一个启动文件统一调用各节点的启动文件。

2.1 单节点启动文件

        先以duckiebot节点为例,在节点包内创建launch目录,在目录下新建duckiebot_node_launch.py文件,一般文件名以_launch结尾(非必要,只是为了方便在setup.py中配置):

编辑该文件内容如下:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
   return LaunchDescription([
      Node(
         package='duckiebot',
         executable='duckiebot_node',
         name='duckiebot_node'
      ),
   ])

修改setup.py,添加以下代码:

import os
from glob import glob
(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.py'))),

完整配置文件如下图:

返回工作空间编译并重新设置环境变量,然后通过ros2 launch命令启动该节点:

$ ros2 launch duckiebot duckiebot_node_launch.py

同样的方法为control节点创建启动文件并编译配置。

        注:单节点启动文件中可以直接指定namespace,也可以在多节点启动文件中统一配置,二者冲突,所以单节点launch文件中不进行配置,留到多节点启动文件中统一配置。

2.2 多节点启动文件

        在工作空间目录下的launch目录下新建all_launch.py,编辑内容如下:

import os

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


def generate_launch_description():
   duckiebot_node = IncludeLaunchDescription(
      PythonLaunchDescriptionSource([os.path.join(
         get_package_share_directory('duckiebot'), 'launch'),
         '/duckiebot_node_launch.py'])
      )
   control_node = IncludeLaunchDescription(
      PythonLaunchDescriptionSource([os.path.join(
         get_package_share_directory('control'), 'launch'),
         '/control_node_launch.py'])
      )
   
   return LaunchDescription([
      duckiebot_node,
      control_node
   ])

        通过all_launch.py启动两个节点,这种情况下,节点本身的配置可以写在自己的启动文件内,群体启动文件内不需要关心节点自身的启动配置参数。

$ ros2 launch launch/all_launch.py

如果要统一命名空间,在all_launch.py中添加以下代码:

from launch.actions import GroupAction
from launch_ros.actions import PushRosNamespace
def generate_launch_description():
    ......
    node_with_namespace = GroupAction(
     actions=[
         PushRosNamespace('duckietown'),
         duckiebot_node,
         control_node,
      ]
   )
   #返回值由node_with_namespace代替之前的节点
   return LaunchDescription([
      node_with_namespace
   ])

3、启动文件的其他配置功能

        上文我们只介绍了启动文件中package、namespace、executable和name的配置,而在实际应用中还会有其他需求,常用的比如配置参数的加载、主题的重映射等,另外还有一些复杂的用法,详细内容请参考官方文档。

3.1 节点参数配置

        节点参数的使用是在line_detect节点中实现的,之前如果要修改默认配置,需要修改源码或者通过命令行加载已有参数配置,当节点通过launch文件启动时,修改默认配置就有了新的方法。

3.1.1 在启动文件中设置

        假设现在需要在节点启动时,默认显示黄色道路识别结果,line_detect节点的启动文件应该这么写:

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

def generate_launch_description():
   color_select_launch_arg = DeclareLaunchArgument(
      'color_select', default_value=TextSubstitution(text='yellow')
   )
   return LaunchDescription([
      color_select_launch_arg,
      Node(
         package='line_detect',
         executable='line_detect_node',
         name='line_detect_node',
         parameters=[{
            'color_select': LaunchConfiguration('color_select'),
         }]
      ),
   ])

        同时修改setup.py文件,然后在all_launch.py中添加修改以下内容:

 line_detect_node = IncludeLaunchDescription(
      PythonLaunchDescriptionSource([os.path.join(
         get_package_share_directory('line_detect'), 'launch'),
         '/line_detect_node_launch.py'])
      )
   
   node_with_namespace = GroupAction(
     actions=[
         PushRosNamespace('duckietown'),
         duckiebot_node,
         control_node,
         line_detect_node,
      ]
   )

        编译配置后启动all_launch.py,可以看到新节点默认显示黄色道路识别结果,同样方法也可以直接设定各种颜色的分量数值。

3.1.2 在启动文件中加载yaml配置文件

        在参数功能讲解中,我们将调试过的参数进行导出保存为yaml格式文件,导出的参数(也可以是手动配置参数)也可以通过启动文件加载,参数配置文件我们一般放在config目录下,在节点包内新建config目录,将导出参数文件放到config目录下,参数文件line_detect_node.yaml内容如下:

/duckietown/line_detect_node:
  ros__parameters:
    color_select: red
    red_h_high: 10
    red_h_low: 156
    red_s_high: 255
    red_s_low: 43
    red_v_high: 255
    red_v_low: 46
    use_sim_time: false
    white_h_high: 180
    white_h_low: 0
    white_s_high: 50
    white_s_low: 0
    white_v_high: 255
    white_v_low: 100
    yellow_h_high: 34
    yellow_h_low: 26
    yellow_s_high: 255
    yellow_s_low: 43
    yellow_v_high: 255
    yellow_v_low: 46

修改line_detect_node_launch.py:

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():
   config = os.path.join(
      get_package_share_directory('line_detect'),
      'config',
      'line_detect_node.yaml'
      )
   return LaunchDescription([
      Node(
         package='line_detect',
         executable='line_detect_node',
         name='line_detect_node',
         parameters=[config]
      ),
   ])

修改setup.py,在data_files中添加以下代码:

(os.path.join('share', package_name, 'config'), glob(os.path.join('config', '*.yaml'))),

重新编译配置启动all_launch.py,可以看到直接显示红色道路识别结果。

3.2 主题的重映射

        在功能更新、节点话题命名重复、临时调试等情况下,节点内的主题可能需要临时或者永久修改名称,直接修改源码并不是很友好的办法,这种情况就可以用启动文件内的主题重映射来实现,我们以修改control节点中的action主题为例来说明使用方法,直接看启动文件配置:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
   return LaunchDescription([
      Node(
         package='control',
         executable='control_node',
         name='control_node',
         remappings=[
            ('/duckietown/control_node/action', '/duckietown/control_node1/control_action'),
         ]
      ),
   ])

重新编译配置启动all_launch.py,查看topic list:

3.3 环境变量引用

        启动文件中调用环境变量的方式可以用来定义或推送名称空间,以区分不同计算机或机器人上的节点。

还是以control节点为例:

from launch import LaunchDescription
from launch_ros.actions import Node

from launch.actions import DeclareLaunchArgument
from launch.substitutions import EnvironmentVariable, LaunchConfiguration

def generate_launch_description():
   return LaunchDescription([
      DeclareLaunchArgument(
            'node_prefix',
            default_value=[EnvironmentVariable('USER'), '_'],
            description='prefix for node name'
      ),
      Node(
         package='control',
         executable='control_node',
         name=[LaunchConfiguration('node_prefix'), 'control_node']
      ),
   ])

        编译运行查看节点列表:

        另外,也可以用在多节点启动文件中,统一命名namespace,用法如下:

import os

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 GroupAction
from launch_ros.actions import PushRosNamespace

from launch.actions import DeclareLaunchArgument
from launch.substitutions import EnvironmentVariable, LaunchConfiguration

def generate_launch_description():
   duckiebot_node = IncludeLaunchDescription(
      PythonLaunchDescriptionSource([os.path.join(
         get_package_share_directory('duckiebot'), 'launch'),
         '/duckiebot_node_launch.py'])
      )
   control_node = IncludeLaunchDescription(
      PythonLaunchDescriptionSource([os.path.join(
         get_package_share_directory('control'), 'launch'),
         '/control_node_launch.py'])
      )
   
   line_detect_node = IncludeLaunchDescription(
      PythonLaunchDescriptionSource([os.path.join(
         get_package_share_directory('line_detect'), 'launch'),
         '/line_detect_node_launch.py'])
      )
   
   node_with_namespace = GroupAction(
     actions=[
         DeclareLaunchArgument(
            'namespace',
            default_value=[EnvironmentVariable('USER'),'_robot'],
            description='prefix for node name'
         ),
         PushRosNamespace(LaunchConfiguration('namespace')),
         duckiebot_node,
         control_node,
         line_detect_node,
      ]
   )
   
   return LaunchDescription([
      node_with_namespace
   ])

编译运行查看节点列表:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS2学习笔记(十)-- ROS2 launch启动文件 的相关文章

  • 天地飞接收机输出信号解析

    今天测试了下天地飞8通道的接收机的pwm输出 接收机的输出信号 xff0c 可以按照50HZ的pwm信号来解析 xff0c 在stm32中 xff0c 使用外部高地电平触发中断的方式 xff0c 来记录一个脉宽的时间 用示波器实际查看信号的
  • Linux-TCP之深入浅出send和recv

    概念 先明确一个概念 xff1a 每个TCP socket在内核中都有一个发送缓冲区和一个接收缓冲区 xff0c TCP的全双工的工作模式以及TCP的滑动窗口便是依赖于这两个独立的buffer以及此buffer的填充状态 接收缓冲区把数据缓
  • popen使用方法及场景

    1 popen的应用场景 popen应用于执行shell命令 xff0c 并读取此命令的返值 xff0c 或者与执行的命令进行交互 2 popen的实现 popen 函数通过创建一个管道 xff0c 调用fork 产生一个子进程 xff0c
  • sscanf函数使用详解

    一 描述 sscanf通常被用来解析并转换字符串 xff0c 其格式定义灵活多变 xff0c 可以实现很强大的字符串解析功能 sscanf的原型 include lt stdio h gt int sscanf const char str
  • Linux通过系统函数设置系统时间

    一 描述 通过settimeofday 函数来设置系统时间 xff0c 这个函数设置的精度可以精确到微秒 include lt time h gt int settimeofday const struct timeval tv const
  • 用Eclipse完成C语言编程的几个简单步骤

    Eclipse是一款被广泛应用的开发工具 xff0c 最初它是为编写Java程序而设计的 xff0c 但由于它良好的架构并作为开源软件来发行 xff0c 有很多的公司和个人以它为基础开发了插件 xff0c 使得Eclipse有了越来越丰富的
  • 最适合程序员转行的10大职业

    三十而立 xff0c 源自 论语 为政 xff0c 说的是人到了30岁就应该去面对生活中的一切困难 而对于软件开发领域的从业者来说 xff0c 30岁 xff0c 却是一道槛 30岁以后 xff0c 适合程序员的工作到底是什么 专家和大家一
  • ROS2学习笔记(二)-- 多机通讯原理简介及配置方法

    在ROS1中由主节点 master 负责其它从节点的通信 xff0c 在同一局域网内通过设置主节点地址也可以实现多机通讯 xff0c 但是这种多机通讯网络存在一个严重的问题 xff0c 那就是所有从节点强依赖于主节点 xff0c 一旦运行主
  • C语言--“.”与“->”有什么区别?

    这虽然是个小问题 xff0c 但有时候很容易让人迷惑 xff0c 因为有的时候用混淆了 xff0c 程序编译不通过 下面说说我对它们的理解 一般情况下用 xff0c 只需要声明一个结构体 格式是 xff0c 结构体类型名 43 结构体名 然
  • C语言--函数指针的用法总结

    函数指针的由来 一个函数在编译时被分配一个入口地址 xff0c 这个入口地址就称为函数的指针 函数名代表函数的入口地址 xff0c 这一点和数组一样 我们可以用一个指针变量来存放这个入口地址 xff0c 然后通过该指针变量调用函数 如 xf
  • std::mutex 用法详解

    Mutex 又称互斥量 xff0c C 43 43 11中与 Mutex 相关的类 xff08 包括锁类型 xff09 和函数都声明在 lt mutex gt 头文件中 xff0c 所以如果你需要使用 std mutex xff0c 就必须
  • 成功解决TypeError: a bytes-like object is required, not 'str'

    解决问题 TypeError a bytes like object is required not 39 str 39 解决思路 问题出在python3 5和Python2 7在套接字返回值解码上有区别 python bytes和str两
  • 计算机网络笔记:字节序与比特序

    1 字节序 所谓字节序是指多字节数据在内存中的存储顺序 xff0c 通常有两种 xff1a 小端字节序 大端字节序 xff1b 小端字节序 xff1a 低位字节存放在低位地址 xff0c 高位字节存放在高位地址 xff1b 大端字节序 xf
  • 全网最全的Postman接口自动化测试!(菜鸟级攻略)

    一 背景 该篇文章针对已经掌握 Postman 基本用法的读者 xff0c 即对接口相关概念有一定了解 已经会使用 Postman 进行模拟请求的操作 当前环境 xff1a Window 7 64Postman 版本 xff08 免费版 x
  • 接口测试之Postman使用全指南(原来使用 Postman测试API接口如此简单)

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 Postman背景介绍 用户在开发或者调试网络程序或者是网页B S模式的程序的时候是需要一些方法来跟踪网页请求的 xff0c 用户可以使用一些网络的监视工具比如
  • 常用Qt类的继承图

  • extern “C”{}的含义及解决的问题

    C 与C 43 43 程序连接问题 它们之间的连接问题主要是因为c c 43 43 编绎器对函数名译码的方式不能所引起的 xff0c 考虑下面两个函数 c int strlen char string c 43 43 int strlen
  • ROS2学习笔记(四)-- 用方向键控制小车行走

    简介 xff1a 在上一节的内容中 xff0c 我们通过ROS2的话题发布功能将小车实时视频信息发布了出来 xff0c 同时使用GUI工具进行查看 xff0c 在这一节内容中 xff0c 我们学习一下如何订阅话题并处理话题消息 xff0c
  • C++实现简单的HTTP客户端(阻塞方式)

    项目中用到的HTTP请求功能 xff0c 自己简单写了个客户端 xff0c 实现了POST方式 xff0c GET方式实现应该也很简单 xff08 空接口已经写好 xff1a 61 xff09 应该支持多线程 xff08 这个很重要 xff
  • WSAWaitForMultipleEvents()

    简述 xff1a 只要指定事件对象中的一个或全部处于有信号状态 xff0c 或者超时间隔到 xff0c 则返回 include lt winsock2 h gt DWORD WSAAPI WSAWaitForMultipleEvents D

随机推荐

  • WSAEnumNetworkEvents()

    WSAEnumNetworkEvents 简述 xff1a 检测所指定的套接口上网络事件的发生 include lt winsock2 h gt int WSAAPI WSAEnumNetworkEvents SOCKET s WSAEVE
  • WSASend()

    WSASend 简述 xff1a 在一个已连接的套接口上发送数据 include lt winsock2 h gt int WSAAPI WSASend SOCKET s LPWSABUF lpBuffers DWORD dwBufferC
  • 临界区

    本文假定您熟悉 Win32 C 43 43 和多线程处理 下载本文的代码 xff1a CriticalSections exe 415KB 摘要 临界区是一种防止多个线程同时执行一个特定代码节的机制 xff0c 这一主题并没有引起太多关注
  • glBegin()用法小结

    glBegin 用法小结 1 在glBegin 和glEnd 之间可调用的函数 函数 函数意义 glVertex 设置顶点坐标 glColor 设置当前颜色 glIndex 设置当前颜色表 glNormal 设置法向坐标 glEvalCoo
  • C++中的显式构造函数

    以两个C 43 43 的小例子来说明怎样通过使用显式构造函数来防止隐式转换 有如下一个简单的复数类 xff1a class ClxComplex public ClxComplex double dReal 61 0 0 double dI
  • 类中的static关键字

    面向对象的static关键字 xff08 类中的static关键字 xff09 1 静态数据成员 在类内数据成员的声明前加上关键字static xff0c 该数据成员就是类内的静态数据成员 先举一个静态数据成员的例子 可以看出 xff0c
  • VS2005 常用快捷键

    2007 04 10 15 32 VS2005 常用快捷键 仁者无敌 2006 08 02 20 20 16 Shift 43 Alt 43 Enter 切换全屏编辑 Ctrl 43 B T Ctrl 43 K K 切换书签开关 Ctrl
  • const

    面向对象是C 43 43 的重要特性 但是c 43 43 在c的基础上新增加的几点优化也是很耀眼的 就const直接可以取代c中的 define 以下几点很重要 学不好后果也也很严重 const 1 限定符声明变量只能被读 const in
  • ROS2学习笔记(五)-- ROS2命令行操作常用指令总结(一)

    简介 xff1a 在前面的章节中 xff0c 我们先简单学习了ROS2的话题发布和订阅 xff0c 两种操作都是通过python代码实现的 xff0c 而在实际应用过程中 xff0c 我们会经常用到命令行操作来辅助调试 xff0c 更进一步
  • Ubuntu16.04配置Carla第三方egg库

    背景 CARLA软件是英特尔公司主导的 xff0c 基于虚幻4游戏引擎 xff0c 用于自动驾驶仿真的一款开源仿真软件 xff0c 该软件可以模拟激光雷达 xff0c 摄像头等等自动驾驶中常用的传感器的行为以及获取传感器数据 xff0c 从
  • 串口通信校验方式(even,odd,space,mark)

    无校验 xff08 no parity xff09 奇校验 xff08 odd parity xff09 xff1a 如果字符数据位中 34 1 34 的数目是偶数 xff0c 校验位为 34 1 34 xff0c 如果 34 1 34 的
  • 更改Ubuntu默认python版本的两种方法

    更改Ubuntu默认python版本的两种方法 没找到原文地址 xff0c 作者写的很实用的方法 xff0c 赞一个 当你安装 Debian Linux 时 xff0c 安装过程有可能同时为你提供多个可用的 Python 版本 xff0c
  • Franka+Realsense D435i Ubuntu 20.04-easyHandeye 手眼标定

    使用Panda 43 realsense D435i 43 easyhandeye 43 ROS neotic 全流程记录 安装环节 安装ros安装libfranka安装moveit panda moveit config 安装 visp安
  • CMake教程Step2(添加库)

    CMake官方文档 参考官方cmake3 24教程翻译 https cmake org cmake help v3 24 guide tutorial index html https gitlab kitware com cmake cm
  • ROS rplidar_ros package使用相关说明

    rplidar ros wiki http wiki ros org rplidar ros SDK详解 xff0c 参考blog xff1a https blog csdn net qq 16775293 article details
  • wireshark能抓到数据,调试工具却收不到数据问题

    网上查找原因 xff0c 有各种说法 xff0c 其中有说关闭防火墙的 xff0c 抱着试一试的心态 xff0c 结果成功了 wireshark有数据 xff1a 关闭防火墙 xff1a NetAssist收到数据 xff1a
  • RTKLIB之RTKRCV

    1 options file option file can be saved from rtknavi exe modify the options file to fit for ubuntu system remember to ch
  • 连接跟踪子系统之AF_INET协议族钩子函数

    如笔记连接跟踪子系统之AF INET初始化所述 xff0c 为了支持连接跟踪子系统 xff0c AF INET协议族在4个HOOK点共注册了8个钩子函数 xff0c 每个HOOK点有两个 这些钩子函数可分为入口 xff08 PRE ROUT
  • UML建模详解(9)—Rose将C++代码自动生成UML类图详解

    一 类图 nbsp class diagram nbsp 即 c 中的 class 聚合 nbsp Aggregation nbsp 即我们c 中的引用 表现为 class 头文件中的一个或多个指针成员 组合 nbsp Compositio
  • ROS2学习笔记(十)-- ROS2 launch启动文件

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