ExecuteProcess是ROS为launch文件提供的一个非常有用的工具,在前面已经说明过launch_ros.action.node.Node是继承自ExecuteProcess,它其实是launch其他工具基础,很多launch工具与Node一样,都是继承自ExecuteProcess,而且ExecuteProcess是更加底层的一个launch工具接口,它可以实现更加灵活的功能,不再简单限定于节点启动,目前的资料较少提及ExecuteProcess,关于它的使用方式就更加少,下面对其进行介绍。
ExecuteProcess的继承关系与物理位置
ExecuteProcess是一个类,位于launch这个package中,具体位置为launch/action/execute_process.py中。在execute_process.py中,ExecuteProcess类的声明如下图所示:
这说明ExecuteProcess类继承自ExecuteLocal类,ExecuteLocal类位于executal_local.py中。所以ExecuteProcess类与execute_process.py和executal_local.py有关。
ExecuteLocal类又继承自Action类
Action类又继承自LaunchDescriptionEntity类
LaunchDescriptionEntity类不再有继承关系,也就是它是最内核的类。
所以ExecuteProcess类在最底层与action.py和launch_description_entity.py文件有关。
在外层与action文件夹中的execute_process.py和executal_local.py有关。
要查看ExecuteProcess类中的主要参数,就要看一下它的定义了,由于ExecuteProcess类继承自ExecuteLocal类,所以这两类的定义都需要看一下。在ExecuteProcess类中最基本的参数是cmd。
使用ExecuteProcess实现节点启动
下面通过一个实例说明使用ExecuteProcess类实现节点启动的过程。
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions importExecuteProcess
def generate_launch_description():
turtle_node = ExecuteProcess(
cmd=[[
'ros2 run turtlesim turtlesim_node'
]],
shell=True
)
return LaunchDescription([
turtle_node
])
执行的结果如下图所示:
通过terminal的显示结果可以看到,节点的启动方式是通过“ros2 run turtlesim turtlesim_node”这个命令启动的,实际上就是cmd参数的值。这说明cmd这个参数就是可以把原来普通的ROS命令封装到ExecuteProcess这个类中,这实际上大大扩展了ROS使用的灵活性,可以把多个ROS命令分别进行封装,然后放到一个launch文件中,这样就可以起到脚本文件的作用,大大提高ROS使用的方便性。
从这里也可以看出使用launch文件实现节点的启动,可以有2种方式:
(1) 使用Node类实现节点启动,在启动过程中还可以赋予节点name、namespace、arguments、parameters、remappings等设置项;
(2) 使用ExecuteProcess类实现节点启动,其中过程的实质就是运行ROS的命令,既然ExecuteProcess类的实质是运行ROS命令,那么使用ExecuteProcess类就可以其他的其他的ROS命令功能,其实ExecuteProcess类的功能还包括实现Linux系统命令的功能,这大大拓展了ROS使用的方便性。
使用ExecuteProcess进阶实现ROS功能
实例1:
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import ExecuteProcess
def generate_launch_description():
turtle_node = ExecuteProcess(
cmd=[
'ros2 run turtlesim turtlesim_node'
],
name='execute_test_node',
shell=True
)
spawn_turtle = ExecuteProcess(
cmd=[[
'ros2 service call ',
'/spawn ',
'turtlesim/srv/Spawn ',
'"{x: 2, y: 2, theta: 0.2}"'
]],
shell=True
)
change_background_r = ExecuteProcess(
cmd=[['ros2 param set ',
'/turtlesim ',
'background_r ','240'
]],
shell=True
)
return LaunchDescription([
turtle_node,
spawn_turtle,
change_background_r
])
运行的结果:
通过这个实例可以看到,使用ExecuteProcess实现了service的调用和parameter的设置,实际上,凡是ros命令都可以放到ExecuteProcess中进行执行,这拓展launch文件的使用的场合。
使用ExecuteProcess实现Linux命令
ExecuteProcess除了可以执行ros命令之外,还可以执行linux命令。
实例:
from launch_ros.actions import Node
from launch import LaunchDescription
from launch.actions import ExecuteProcess
def generate_launch_description():
t_ns = 'turtle_ns'
turtle_node = ExecuteProcess(
cmd=[
'tree','-L 1'
],
shell=True,
output='screen'
)
return LaunchDescription([
turtle_node
])
运行的结果:
这里应注意的是,在使用ExecuteProcess类执行Linux命令的时候,如果不指定output时,则不会显示结果,指定output参数为“screen”或“both”时,会把Linux命令执行的结果显示出来。