LaunchConfiguration和DeclareLaunchArgument属于launch文件的高阶应用,它们需要配合使用,可以实现开发者自行定义参数通过ROS的launch命令向launch文件传递数据。这使得不需要改动launch文件就可以实现对launch文件的相关变量进行赋值,提高了launch文件的灵活性。
向launch文件传递参数初步功能实现
下面通过实例具体说明LaunchConfiguration和DeclareLaunchArgument怎么实现向launch文件传递参数。
launch文件名为:example7.laun.py
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import LogInfo
from launch.substitutions import LaunchConfiguration
def generate_launch_description():
t_ns = 'turtle_ns'
n_name_conf = LaunchConfiguration('n_name')
n_name_arg = DeclareLaunchArgument(
'n_name',
default_value='node_name'
)
turtle_node = Node(
package='turtlesim',
namespace='turtle_ns',
executable='turtlesim_node',
name=n_name_conf
)
return LaunchDescription([
n_name_arg,
turtle_node
])
执行命令:
ros2 launch pkg_test_py example7.laun.py
运行的结果如下:
下面结合代码对LaunchConfiguration和DeclareLaunchArgument的使用进行说明:
(1) 1-1的位置为赋值的DeclareLaunchArgument对象的名称,这个名称必须与1-2位置一致,也就是需要作为generate_launch_description函数的返回值之一;
(2) 2-1的位置launch文件声明的参数名;这个位置决定了LaunchConfiguration对那个参数进行设置;
(3) 3-1的位置为2-1所声明参数的默认值,从这个实例中可以看到这个位置所起的具体的作用,在后面进行说明;;
(4) 4-1的位置为赋值的LaunchConfiguration的对象名称,4-1位置的名称必须要luanch文件中所要被赋值的相关设置项所对应的变量名一致,在这个例子中,节点Node类中的name(节点名)设置项作为LaunchConfiguration被赋值设置项,因此这里4-2的位置需要与4-1的位置保持一致;
(5) 2-2位置为LaunchConfiguration所要设置的参数名,这个位置的值取决于DeclareLaunchArgument中指定的参数名,也就是2-1的位置;
前面也说过LaunchConfiguration和DeclareLaunchArgument要配对使用,从2-1和2-2的位置和对应关系也说明它们2需要配合使用。
仍然是这个实例,改变一下使用方式:
ros2 launch pkg_test_py example7.laun.py n_name:=new_name
执行的结果如下图所示:
这里使用命令的区别就在于增加了参数设置,命令中设置的参数名就是代码2-1位置所指定的参数名,后面5-1的位置为参数的值,通过这个设置后,5-2的位置变为5-1位置的值,不再为3-1位置的默认值。上面的执行方式中,没有指定参数值,所以对应的3-2位置为n_name的默认值,而这里的执行方式中指定了参数值,所以5-2的位置就变为命令中指定的参数值。
向launch传递参数的进一步应用
在上面这个实例中说明LaunchConfiguration和DeclareLaunchArgument的功能就是实现通过launch命令向launch文件传递参数。在上面实例中使用的Node类启动节点,通过LaunchConfiguration和DeclareLaunchArgument指定了节点启动是对应的设置项参数。LaunchConfiguration和DeclareLaunchArgument不只可以与Node类配合使用,还可以与ExecuteProcess配合使用,这样可以使得launch文件不只可以在节点启动过程中指定参数,还可以在其他ROS功能中指定参数。
实例:代码文件example8.laun.py
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess
from launch.substitutions import LaunchConfiguration
def generate_launch_description():
background_r_arg = DeclareLaunchArgument(
'new_background_r',
default_value='180'
)
background_r_conf = LaunchConfiguration('new_background_r')
ns_name_arg = DeclareLaunchArgument(
'ns_name_temp',
default_value='ns_name0'
)
ns_name_conf = LaunchConfiguration('ns_name_temp')
turtlesim_node = Node(
package='turtlesim',
namespace=ns_name_conf,
executable='turtlesim_node',
name='sim'
)
spawn_service = ExecuteProcess(
cmd=[[
'ros2 service call ',
ns_name_conf,
'/spawn ',
'turtlesim/srv/Spawn ',
'"{x: 2, y: 2, theta: 0.2}"'
]],
shell=True
)
change_background_r = ExecuteProcess(
cmd=[[
'ros2 param set ',
ns_name_conf,'/sim background_r ',
background_r_conf
]],
shell=True
)
return LaunchDescription([
background_r_arg ,
ns_name_arg,
turtlesim_node,
spawn_service,
change_background_r
])
执行命令:
ros2 launch pkg_test_py example8.laun.py
运行结果如下:
下面结合代码进行说明:
(1) 1-1的位置定义了new_background_r的参数变量,并且默认值为100,1-2的位置是在ExecuteProcess中,这其中是ROS设置parameter的命令,1-2的位置位于这个命令当中,对应的是parameter“background_r”的值,也就是通过参数变量使得这个命令可以自由改变background_r这个parameter的值。在这里还需额外补充关于与1-1相关的一条代码:
background_r_arg = DeclareLaunchArgument('new_background_r', default_value='180')
前面讲解过DeclareLaunchArgument要与LaunchConfiguration配合使用,这里有一点特别,new_background_r在使用的过程中对应节点中background_r这个parameter,这个parameter的类型是int型,但是在这里定义默认值的类型为字符串,这是因为ROS中launch文件在处理参数值时都是按照字符串来处理,所以这里将默认值定义为以数字构成的字符串,这一点在launch文件的参数传递过程中需要特别注意;
(2) 2-1的位置定义ns_name_temp参数变量,并且默认值为“ns_name_temp”,2-2、2-3、2-4分别位于Node、ExecuteProcess中,实现节点启动、调用service、以及设置parameter的作用。2-2设置了节点的namespace,2-3使service调用的命令可以对应节点的节点的namespace,2-4使parameter设置的命令可以对应节点的节点的namespace。
(3) 2-5的位置表示了启动节点的namespace,这里的namespace为ns_name0,也就是ns_name_temp参数变量的默认值;2-6的位置表示了调用service的结果,对应的namespace变为了ns_name0,2-7的位置表示了设置parameter的结果这里是new_background_r的默认值180。
仍然是这个实例,改变一下使用方式:
ros2 launch pkg_test_py example8.laun.py new_background_r:=10 ns_name_temp:=name_from_command
运行结果如下:
从执行结果中可以看到,命令中1-1的位置改变了节点的namespace,而命令中的2-1的位置改变了background_r这个parameter。