1.C++实现

功能包 cpp01_launch 下,创建 launch 目录。launch 文件可以是 python 文件、xml 文件或 yaml 文件,不同类型的launch 文件可以直接存储在 launch 目录下,或者为了方便管理,我们也可以在launch 目录下新建 py、xml 和 yaml三个文件夹分别存储对应类型的 launch 文件,并且建议不同格式的 launch 文件命名时分别使用_launch.py、_launch.xml、_launch.yaml或.launch.py、.launch.xml、.launch.yaml 作为后缀名。

1.1Python 文件:py00_base.launch.py

from launch import LaunchDescriptionfrom launch_ros.actions import Node

def generate_launch_description():
	turtle1 = Node(package="turtlesim", executable="turtlesim_node", name="t1")
	turtle2 = Node(package="turtlesim", executable="turtlesim_node", name="t2")
	return LaunchDescription([turtle1, turtle2])

1.2XML 文件:xml00_base.launch.xml

<launch>
    <node pkg="turtlesim" exec="turtlesim_node" name="t1"/>
    <node pkg="turtlesim" exec="turtlesim_node" name="t2"/>
</launch>

1.3YAML 文件:yaml00_base.launch.yaml

launch:
  - node:
      pkg: "turtlesim"
      exec: "turtlesim_node"
      name: "t1"
  - node:
      pkg: "turtlesim"
      exec: "turtlesim_node"
      name: "t2"

1.4.编辑配置文件

CMakeLists.txt 中添加语句

install(DIRECTORY launch DESTINATION share/${PROJECT_NAME})

2.Python实现

2.1编译配置文件

编辑 setup.py 文件,需要在 data_files 属性中,添加相关 launch 文件的路径,修改后的内容如下:

from setuptools import setupfrom glob import glob
package_name = 'py01_launch'
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']),
# launch 文件相关配置
#将当前包 launch/py/ 目录下所有后缀为 .launch.py 的 Python 类型 launch 文件,安装到 share/包名/ 目录下。
#同理,后两行分别处理 launch/xml/ 目录下的 .launch.xml 文件和 launch/yaml/ 目录下的 .launch.yaml 文件
('share/' + package_name, glob("launch/py/*.launch.py")),
('share/' + package_name, glob("launch/xml/*.launch.xml")),
('share/' + package_name, glob("launch/yaml/*.launch.yaml"))
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='ros2',
maintainer_email='ros2@todo.todo',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)

2.2节点设置

from launch import LaunchDescription 
from launch_ros.actions import Node
import os
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
    turtle1=Node(
        package="turtlesim",
        executable="turtlesim_node",
        respawn=True,
        exec_name="my_label",
        ros_arguments=["--remap","__ns:=/t2"]
        )
    turtle2=Node(
        package="turtlesim",
        executable="turtlesim_node",
        name="tur",
        respawn=True,
        parameters=[os.path.join(get_package_share_directory("cpp01_launch"),"config","haha.yaml")]
        )
    return LaunchDescription([turtle2])

参数:
package:功能包;
executable:可执行文件;
namespace:命名空间;
name:节点名称;
exe_name:流程标签;
respawn:设置为 True 时,关闭节点后,可以自动重启

2.3执行指令

from launch import LaunchDescription 
from launch_ros.actions import Node
from launch.actions import ExecuteProcess
import os
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
    turtle=Node(
        package="turtlesim",
        executable="turtlesim_node"
    )
    cmd= ExecuteProcess(
        # cmd=["ros2 topic echo /turtle1/pose"],
        cmd=["ros2 topic", "echo ","/turtle1/pose"],
        output="both",
        shell=True
    )
    return LaunchDescription([turtle,cmd])

cmd:被执行的命令;
output:设置为 both 时,日志会被输出到日志文件和终端,默认为 log,日志只输出到日志文件。
shell:如果为 True,则以 shell 的方式执行命令。

2.4参数设置

参数设置主要涉及到参数的声明与调用两部分,其中声明被封装为launch.actions.DeclareLaunchArgument,调用则被封装为 launch.substitutions import
LaunchConfiguration。

from pkg_resources import declare_namespace
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
def generate_launch_description():
    bg_r=DeclareLaunchArgument("backg_r",default_value="255")
    bg_b=DeclareLaunchArgument("backg_b",default_value="255")
    bg_g=DeclareLaunchArgument("backg_g",default_value="255")
    turtle=Node(
        package="turtlesim",
        executable="turtlesim_node",
        parameters=[{"background_r":LaunchConfiguration("backg_r"),
                     "background_b":LaunchConfiguration("backg_b"),
                     "background_g":LaunchConfiguration("backg_g")}]
    )
    return LaunchDescription([bg_r,bg_g,bg_b,turtle])

name:参数名称;
default_value:默认值。

2.5文件包含

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from ament_index_python import get_package_share_directory
import os
def generate_launch_description():
    include=IncludeLaunchDescription(
        launch_description_source=PythonLaunchDescriptionSource(launch_file_path=os.path.join(
            get_package_share_directory("cpp01_launch"),
            "launch/py",
            "py04_args_launch.py"
            )
            ),launch_arguments=[("backg_r","80"),("backg_g","180"),("backg_b","10")]
    )
    return LaunchDescription([include]) 

aunch_description_source:用于设置被包含的 launch 文件;
launch_arguments:元组列表,每个元组中都包含参数的键和值。

2.6分组设置

在 launch 文件中,为了方便管理可以对节点分组,分组相关 API 为:launch.actions.GroupAction
和 launch_ros.actions.PushRosNamespace。

from launch import LaunchDescription
from launch_ros.actions import Node
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
def generate_launch_description():
    turtle1 = Node(package="turtlesim",executable="turtlesim_node",name="t1")
    turtle2 = Node(package="turtlesim",executable="turtlesim_node",name="t2")
    turtle3 = Node(package="turtlesim",executable="turtlesim_node",name="t3")
    g1=GroupAction(actions=[PushRosNamespace(namespace="g1"),turtle1,turtle2])
    g2=GroupAction(actions=[PushRosNamespace(namespace="g2"),turtle3])
    return LaunchDescription([g1,g2])

在 GroupAction 对象中,使用的参数为:
actions:action 列表,比如被包含到组内的命名空间、节点等。
在 PushRosNamespace 对象中,使用的参数为:
namespace:当前组使用的命名空间。

2.7添加事件

节点在运行过程中会触发不同的事件,当事件触发时可以为之注册一定的处理逻辑。事件使用相关
的 API 为:launch.actions.RegisterEventHandler、launch.event_handlers.OnProcessStart、
launch.event_handlers.OnProcessExit。

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess, RegisterEventHandler,LogInfo
from launch.substitutions import FindExecutable
from launch.event_handlers import OnProcessStart, OnProcessExit
def generate_launch_description():
    turtle = Node(package="turtlesim",executable="turtlesim_node",name="t1")
    spawn=ExecuteProcess(
        cmd=["ros2 service call /spawn turtlesim/srv/Spawn \"{'x':8.0,'y':3.0}\""],
        output="both",
        shell=True
    )
    start_event = RegisterEventHandler(
        event_handler=OnProcessStart(
        target_action = turtle,
        on_start = spawn
        )
    )
    exit_event = RegisterEventHandler(
        event_handler=OnProcessExit(
        target_action = turtle,
        on_exit = [LogInfo(msg = "turtlesim_node 退出!")]
        )
    )
    return LaunchDescription([turtle,start_event,exit_event])

对象 RegisterEventHandler 负责注册事件,其参数为:
event_handler:注册的事件对象。

OnProcessStart 是启动事件对象,其参数为:
target_action:被注册事件的目标对象;

on_start:事件触发时的执行逻辑。

OnProcessExit 是退出事件对象,其参数为:
target_action:被注册事件的目标对象;

on_exit:事件触发时的执行逻辑。

LogInfo 是日志输出对象,其参数为:
msg:被输出的日志信息。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐