我们知道,ros2 launch是用来同时启动多个节点的指令,与之配套的有一个,文件,在ROS2系统,该流程非常简单。
因为凡是在ros2下编译通过的包,在ros2下都有注册,因此,无需特别指定launch文件到底在哪个路径,你可以任意一个地方建立启动文件:如~/turtlesim_mimic_launch.py
粘贴下面语句:
from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='turtlesim',namespace='turtlesim1',executable='turtlesim_node',name='sim'),Node(package='turtlesim',namespace='turtlesim2',executable='turtlesim_node',name='sim'),Node(package='turtlesim',executable='mimic',name='mimic',remappings=[('/input/pose', '/turtlesim1/turtle1/pose'),('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),])])
1)启动的一般格式:
ros2 launch
2)在当前目录执行:
ros2 launch turtlesim_mimic_launch.py
3)再执行发布指令:
ros2 topic pub -r 1 /turtlesim1/turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}"
可以看到,打开两个不同的终端,并行展示出两个乌龟画面。
# example.launch.pyimport osfrom ament_index_python import get_package_share_directoryfrom launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.actions import GroupAction
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch.substitutions import TextSubstitution
from launch_ros.actions import Node
from launch_ros.actions import PushRosNamespacedef generate_launch_description():# args that can be set from the command line or a default will be usedbackground_r_launch_arg = DeclareLaunchArgument("background_r", default_value=TextSubstitution(text="0"))background_g_launch_arg = DeclareLaunchArgument("background_g", default_value=TextSubstitution(text="255"))background_b_launch_arg = DeclareLaunchArgument("background_b", default_value=TextSubstitution(text="0"))chatter_ns_launch_arg = DeclareLaunchArgument("chatter_ns", default_value=TextSubstitution(text="my/chatter/ns"))# include another launch filelaunch_include = IncludeLaunchDescription(PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('demo_nodes_cpp'),'launch/topics/talker_listener.launch.py')))# include another launch file in the chatter_ns namespacelaunch_include_with_namespace = GroupAction(actions=[# push-ros-namespace to set namespace of included nodesPushRosNamespace(LaunchConfiguration('chatter_ns')),IncludeLaunchDescription(PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('demo_nodes_cpp'),'launch/topics/talker_listener.launch.py'))),])# start a turtlesim_node in the turtlesim1 namespaceturtlesim_node = Node(package='turtlesim',namespace='turtlesim1',executable='turtlesim_node',name='sim')# start another turtlesim_node in the turtlesim2 namespace# and use args to set parametersturtlesim_node_with_parameters = Node(package='turtlesim',namespace='turtlesim2',executable='turtlesim_node',name='sim',parameters=[{"background_r": LaunchConfiguration('background_r'),"background_g": LaunchConfiguration('background_g'),"background_b": LaunchConfiguration('background_b'),}])# perform remap so both turtles listen to the same command topicforward_turtlesim_commands_to_second_turtlesim_node = Node(package='turtlesim',executable='mimic',name='mimic',remappings=[('/input/pose', '/turtlesim1/turtle1/pose'),('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),])return LaunchDescription([background_r_launch_arg,background_g_launch_arg,background_b_launch_arg,chatter_ns_launch_arg,launch_include,launch_include_with_namespace,turtlesim_node,turtlesim_node_with_parameters,forward_turtlesim_commands_to_second_turtlesim_node,])
1)我们通过一个包含头文件
包含 | 用意 |
---|---|
from ament_index_python import get_package_share_directory | 用组件的依赖库 |
from launch import LaunchDescription | 必不可少的项 |
from launch.actions import DeclareLaunchArgument | 有action,且有launch参数必用 |
from launch.actions import IncludeLaunchDescription | 有action,且有include其它launch |
from launch.actions import GroupAction | action组 |
from launch.launch_description_sources import PythonLaunchDescriptionSource | 用python的描述 |
from launch.substitutions import LaunchConfiguration | 有launch配置 |
from launch.substitutions import TextSubstitution | 文本替换,或字符串参数赋值 |
from launch_ros.actions import Node | 节点必须的项 |
from launch_ros.actions import PushRosNamespace | 命名空间 |
2) 参数如何初始化
background_r_launch_arg = DeclareLaunchArgument(
"background_r", default_value=TextSubstitution(text="0")
)
3)包含其它的launch文件
# include another launch file
launch_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(
get_package_share_directory('demo_nodes_cpp'),
'launch/topics/talker_listener.launch.py'))
)
4)跨命名空间的包含
# include another launch file in the chatter_ns namespace
launch_include_with_namespace = GroupAction(
actions=[
# push-ros-namespace to set namespace of included nodes
PushRosNamespace(LaunchConfiguration('chatter_ns')),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(
get_package_share_directory('demo_nodes_cpp'),
'launch/topics/talker_listener.launch.py'))
),
]
)
5)启动节点并且消息重映射
# perform remap so both turtles listen to the same command topic
forward_turtlesim_commands_to_second_turtlesim_node = Node(
package='turtlesim',
executable='mimic',
name='mimic',
remappings=[
('/input/pose', '/turtlesim1/turtle1/pose'),
('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
]
)
6)总返回:将上面的定义、映射等全算上放到list中
return LaunchDescription([
background_r_launch_arg,
background_g_launch_arg,
background_b_launch_arg,
chatter_ns_launch_arg,
launch_include,
launch_include_with_namespace,
turtlesim_node,
turtlesim_node_with_parameters,
forward_turtlesim_commands_to_second_turtlesim_node,
])