跳到正文

Wiki

Launch

約 25 分鐘閱讀

本文由簡體中文內容確定性轉換,並受版本化術語表保護。

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_檔案包含