Launch
概述

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([])
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"


最好添加一个依赖


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

第一个是原话题名称,第二个是新话题名称
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])

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])
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])
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])
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版本一般不影响正常使用。