编写ros2框架launch文件的注意事项和多种方式

一、在setup.py文件中添加配置

1-data_files列表

对于通过python构建的ros2功能包,ros2自带编译器会把data_files这一python列表的元素所对应的文件复制到工作空间install文件夹下。所以,添加launch文件夹并加入launch.py文件时,需要将这一launch文件对应路径添加到data_files列表。先介绍一下data_files列表。

from setuptools import setup

package_name = 'launch_test'

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='ros2_mobile',
    maintainer_email='ros2_mobile@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
        ],
    },
)

以上是原始的setup.py文件,注意到data_files列表是setup元组中的一个元素。

data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ]

data_files列表的每一个元素都是一个元组。元组的第一个元素是源文件被编译器复制后的目标位置,第二个元素是一个列表,该列表的各个元素即为所要复制的源文件的位置。注意,前者的相对位置是install目录下对应功能包位置;后者的相对位置是src目录下的对应功能包位置。

如,package.xml的绝对路径为

your_workspace/src/launch_test

最终它会被复制到如下的目录中

your_worksapce/install/launch_test/share/launch_test

(其中,your_worksapce是工作空间名称,launch_test是功能包名称)

2-将launch文件添加到data_files列表里

按照date_files元组的规范,将launch文件的依赖添加进去

data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        ('share/'+package_name+'/launch',['launch' + '/testlaunch.launch.py'])
    ]

假设我们在launch文件夹里的launch.py文件名称为testlaunch.launch.py,那么应该按照如上的方式添加。注意,尽管我们只添加了一个元素,但必须把它放在一个列表里,构成一个单元素的列表。因为上层元组的第二个元素被规定为列表

data_files里的源文件位置和目标位置必须为相对位置

launch/testlaunch.launch.py

 即为相对位置,如果加一个/

/launch/testlaunch.launch.py

就是绝对位置了。

3-使用通配符

如果有多个launch文件,显然一个一个写会很麻烦。

引入python模块glob实现通配,会大大简化我们的操作

from glob import glob

glob.glob()函数输入参数为文件地址的通配形式,如

launch/*.launch.py

 返回值是一个列表,把所有匹配元素的地址一一列出

所以,data_files列表的描述还可以写为

    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        ('share/'+package_name+'/launch',glob('launch/*.launch.py'))
    ]

4-更加优雅地写出文件的路径

文件路径的字符串总会写错?借用os.path.join函数解决这个!

引入python的os模块实现自动配置路径

import os

os.path.join的输入参数为'share' package_name 和 ''launch'时,会自动返回对应路径!

    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        (os.path.join('share',package_name,'launch'),glob(os.path.join('launch','*.launch.py')))
    ]

注意,虽然是用os.path.join自动生成的路径,但首位是不能带着/,否则就会变成绝对路径!

对于os.path.join函数,首个参数以'/'开头,则会返回绝对路径

二、launch文件的基本框架

from launch import LaunchDescription
 
def generate_launch_description():
    return LaunchDescription([
        # add your actions here...
    ])

 以上是python文件的基本框架。主干是generate_launch_description函数,返回值类型是LaunchDescription类。而这个类的构造函数之参数为一个列表。所有,关键在于,把所有需要启动的节点信息添加到这个列表中。

三、直接启动Node

列表的各个元素分别描述各个节点的启动信息。各个节点的描述信息被封装为Node类。

用这一行代码将Node类引入

from launch_ros.actions import Node

Node类的构造函数有许多参数,可以配置节点的启动信息。其中最关键的是package_name和executable,分别是启动节点的功能包和节点名称。注意,功能包应当在ros2的环境变量里或者在launch文件所在功能包的package.xml文件里添加了相关依赖!

以下是启动turtlesim的一个示例:

from launch import LaunchDescription
from launch_ros.actions import Node
 
def generate_launch_description():
    
    turtlesim_node=Node(
        package='turtlesim',
        executable='turtlesim_node',
        name='sim'
    )

    return LaunchDescription([
        turtlesim_node
    ])

Node类的常用参数如下:

  • package (必需): 要启动节点的包名。
  • executable (必需): 要启动的节点可执行文件的名称。
  • name (可选): 节点的名称。如果未指定,将自动生成一个名称。
  • namespace (可选): 节点的命名空间。
  • parameters (可选): 节点的参数,可以是字典或字典列表。如果是列表,则表示多个参数文件。
  • remappings (可选): 节点的重映射规则,用于更改节点的输入和输出主题等。这是一个字典,将原始名称映射到新名称。
  • output (可选): 节点的输出选项,可以是 'screen''log''both'。默认是 'screen',即在屏幕上输出节点的标准输出和错误输出。
  • arguments (可选): 传递给节点可执行文件的附加参数列表

其中,argument参数是通过命令行传递的,就好像我们在命令行运行某个可执行文件所附带的参数:

./a.out [arguments]

 四、launch文件指令输入——ExecuteProcess

ExecuteProcess 是 ROS 2 Launch 中用于执行外部进程的动作。它通常用于启动系统中的其他程序或者执行一些外部命令。这个动作的构造函数通常是这样的:

launch.actions.ExecuteProcess(
    cmd: List[str],
    *,
    name: Optional[str] = None,
    output: str = 'log',
    shell: bool = False,
    emulate_tty: bool = False,
    cwd: Optional[str] = None,
    env: Optional[Dict[str, str]] = None,
    respawn: bool = False,
    respawn_delay: float = 1.0,
    sigkill_on_shutdown: bool = True
)
  • cmd (必需): 要执行的命令及其参数,以列表形式提供。
  • name (可选): 执行进程的名称。
  • output (可选): 进程的输出选项,可以是 'log''screen''both'。默认是 'log',即将输出记录到日志文件中。
  • shell (可选): 是否使用 shell 运行命令。默认为 False
  • emulate_tty (可选): 是否模拟终端 TTY。默认为 False
  • cwd (可选): 执行进程的当前工作目录。
  • env (可选): 执行进程时使用的环境变量字典。
  • respawn (可选): 是否在进程退出后重新启动。默认为 False
  • respawn_delay (可选): 重新启动进程的延迟时间(以秒为单位)。默认为 1.0
  • sigkill_on_shutdown (可选): 是否在关闭 Launch 文件时发送 SIGKILL 信号以终止进程。默认为 True

需要引用下面这个模块才行:

from launch.actions import ExecuteProcess

下面是一个例子:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess
 
def generate_launch_description():
    
    turtlesim_start=ExecuteProcess(
        cmd=['ros2', 'run', 'turtlesim', 'turtlesim_node']
    )

    return LaunchDescription([
        turtlesim_start
    ])

但是,launch启动文件无法从终端获取用户输入。

五、调用类方法添加节点

LaunchDescription有类方法add_action,可以把Node对象和ExecuteProcess对象添加进入已经创建的LaunchDescription类对象实例中。

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess
 
 
def generate_launch_description():
    ld = LaunchDescription()
    
    turtlesim_node = Node(
            package='turtlesim',
            executable='turtlesim_node',
            name='sim'
        )
    
    ld.add_action(turtlesim_node)
    return ld

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值