Skip to content

Wiki

Launch

About 25 min read

An English translation is not available yet. The latest Simplified Chinese source is shown without triggering paid translation.

1.概述

rosbag2的作用是来序列化储存数据的,是一个数据库。


ros2 launch 功能包名 launch文件名

ros2 pkg create cpp01_launch --build-type ament_cmake --dependencies rclcpp

ros2 pkg create cpp01_launch --build-type ament_cmake --dependencies rclcpp

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

def generate_launch_description():
    return LaunchDescription([])

2.launch基本使用流程(C++)


配置完这个,不管我launch目录下有多少launch文件,只需要配置这一次就行了。

这样说明我们cmake配置对了

from launch import LaunchDescription
from launch_ros.actions import Node
封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

def generate_launch_description():
    return LaunchDescription([])

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

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

最好添加一个依赖

3.Launch_Python_Node

这个是标签exec_name

这俩参数传参的区别在于--ros-args的区别

在launch里写更简单

这样是等价的

{}里是yaml格式的。

有另一种更常用的方法,就是上来读取yaml文件,把数据都存在yaml里,用到的时候直接读取。

把yaml文件放到config里

ros2 param dump haha --output-dir src/cpp01_launch/config/

还需要再配置cmakelists

我们要读就读install目录下的。

直接复制路径

可以进一步优化代码

这个就是来获取某个功能包的share目录路径

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

import os

def generate_launch_description():

    # turtle1 = Node(

    #     package="turtlesim",

    #     executable="turtlesim_node",

    #     exec_name="my_label",

    #     ros_arguments=["--remap","__ns:=/t2"]

    #     )
    turtle2 = Node(
        package="turtlesim",
        executable="turtlesim_node",
        name="haha",
        parameters=[os.path.join(get_package_share_directory("cpp01_launch"),"config","haha.yaml")]
        )
    return LaunchDescription([turtle2])

建议采用第三种 动态获取路径

respawn是自动重启的意思,这样运行后的节点,你用鼠标关闭小乌龟窗口后,也会自动重启节点,再把小乌龟窗口打开一个新的。

按Ctrl+C可以终止。

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

import os

def generate_launch_description():

    # turtle1 = Node(

    #     package="turtlesim",

    #     executable="turtlesim_node",

    #     exec_name="my_label",

    #     ros_arguments=["--remap","__ns:=/t2"]

    #     )
    turtle2 = Node(
        package="turtlesim",
        executable="turtlesim_node",
        name="haha",

        # parameters=[{"background_r": 255,"background_g": 0,"background_b": 0}],

        # parameters=["/home/tungchiahui/mysource/ros2src/4.ws02_tools/install/cpp01_launch/share/cpp01_launch/config/haha.yaml"],
        parameters=[os.path.join(get_package_share_directory("cpp01_launch"),"config","haha.yaml")],
        respawn=True
        )
    return LaunchDescription([turtle2])

第一个是原话题名称,第二个是新话题名称

4.Launch_Python_执行命令

这是个列表,列表里面写我们的指令

这样是把日志既输出到终端也输出到日志,如果不写则只会输出到日志。

这样就是把命令当成终端指令来执行

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
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"],
        output = "both",
        shell = True
    )

    return LaunchDescription([turtle,cmd])

如果指令过长,可以分到多个字符串里运行。


这样也是可以运行的。

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

def generate_launch_description():
    turtle = Node(
        package="turtlesim",
        executable="turtlesim_node"
    )
    cmd = ExecuteProcess(
        cmd = [FindExecutable(name="ros2"),"topic","echo","/turtle1/pose"],
        output = "both",
        shell = True
    )

    return LaunchDescription([turtle,cmd])

5.Launch_Python_参数设置

没传值的话,乌龟红色是满的,那就是粉红色背景

也可以传值,比如传backg_r:=0

这样背景色就变的更偏蓝绿了。

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

def generate_launch_description():

    bg_r = DeclareLaunchArgument(name="backg_r",default_value="255")
    bg_g = DeclareLaunchArgument(name="backg_g",default_value="255")
    bg_b = DeclareLaunchArgument(name="backg_b",default_value="255")
    turtle = Node(
        package="turtlesim",
        executable="turtlesim_node",
        parameters=[{"background_r" : LaunchConfiguration("backg_r"),"background_g" : LaunchConfiguration("backg_g"),"background_b" : LaunchConfiguration("backg_b")}]
    )
    return LaunchDescription([bg_r,bg_g,bg_b,turtle])

6.Launch_Python_文件包含

假设我要编写一个机器人启动相关的launch文件,在这个launch文件中,我可能要启动雷达,启动IMU,启动底盘等等,我们需要把这些launch文件都包含进机器人启动的launch文件中。

这个值是由被包含的launch文件封装而来的对象。

这个对象对应的类就是PythonLaunchDescriptionSource,

类里面还得设置一个参数。

这个参数是launch_file_path就是文件路径。

建议用这个来获取路径。

也可以为其传参

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages 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","10"),("backg_b","200")]
    )
    return LaunchDescription([include])

7.Launch_Python_分组设置

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

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"
    )

    group1 = GroupAction(actions=[PushRosNamespace("g1"),turtle1,turtle2])
    group2 = GroupAction(actions=[PushRosNamespace("g2"),turtle3])

    return LaunchDescription([group1,group2])

8.Launch_Python_事件设置

第一个主要用于注册事件,第二个是开始事件,第三个是节点退出。


这个是在终端中生成新小乌龟的命令

第一个参数是针对哪个事件进行注册。

target_action是事件源,你要为哪个节点注册事件。

on_start是等到事件被触发,你要做哪些操作?

from launch import LaunchDescription
from launch_ros.actions import Node

封装终端指令相关类
from launch.actions import ExecuteProcess
from launch.substitutions import FindExecutable
参数声明与获取
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
文件包含相关
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
分组相关
from launch_ros.actions import PushRosNamespace
from launch.actions import GroupAction
事件相关
from launch.event_handlers import OnProcessStart,OnProcessExit
from launch.actions import ExecuteProcess,RegisterEventHandler,LogInfo
获取功能包下share目录或路径
from ament_index_python.packages import get_package_share_directory

def generate_launch_description():
    turtle = Node(
    package="turtlesim",
    executable="turtlesim_node",
    )
    spawn = ExecuteProcess(
        cmd=["ros2 service call /spawn turtlesim/srv/Spawn \"{'x': 8.0,'y': 3.0}\""],
        output="both",
        shell=True
    )

    event_start = RegisterEventHandler(
        event_handler=OnProcessStart(
            target_action=turtle,
            on_start=spawn
        )
    )

    event_exit = RegisterEventHandler(
        event_handler=OnProcessExit(
            target_action=turtle,
            on_exit=[LogInfo(msg="turtlesim_node:退出!")]
        )
    )
    return LaunchDescription([turtle,event_start,event_exit])

on_exit可以创建一个对象,也可以放在列表里。

可以只学Python版本的Launch,XML和Yaml版本的Launch可以了解就行,自己写就写Python版本的,当你要用到别人开源的功能包用的Launch是Xml或者yaml版本一般不影响正常使用。

9.Launch_XML_YAML_Node

10.Launch_XML_YAML_执行命令

11.Launch_XML_YAML_参数设置

12.Launch_XML_YAML_分组设置

13.Launch_XML_YAML_文件包含