ROS2编程基础课程--Launch
Launching/monitoring multiple nodes with Launch
使用Launch启动/监听多个节点
ROS 2 launch system ROS 2 launch启动系统
The launch system in ROS 2 is responsible for helping the user describe the configuration of their system and then execute it as described. The configuration of the system includes what programs to run, where to run them, what arguments to pass them, and ROS specific conventions which make it easy to reuse components throughout the system by giving them each different configurations. It is also responsible for monitoring the state of the processes launched, and reporting and/or reacting to changes in the state of those processes.
ROS 2中的启动系统负责协助用户描述其系统的配置,然后按照描述执行。系统的配置包括运行哪些程序、运行它们的位置、传递它们的参数以及ROS特定约定,这些约定使得通过为每个不同的配置提供组件,可以轻松地在整个系统中重用组件。它还负责监控已启动的流程的状态,并报告和/或响应这些流程的状态变化。
The ROS 2 Bouncy release includes a framework in which launch files, written in Python, can start and stop different nodes as well as trigger and act on various events. The package providing this framework is launch_ros, which uses the non-ROS-specific launch framework underneath.
ROS 2 Bouncy及之后版本包含一个框架,其中用Python编写的launch文件可以启动和停止不同的节点,以及触发和处理各种事件。提供此框架的launch_ros包使用下面的非ROS特定launch框架。
The design document (in review) details the goal of the design of ROS 2’s launch system (not all functionality is currently available).
这个设计文件(综述)详细描述ROS 2的launch启动系统的设计目标(不是所有的功能是目前可用)。
Example of ROS 2 launch concepts
ROS 2 launch启动概念的例子
The launch file in this example launches two nodes, one of which is a node with a managed lifecycle (a “lifecycle node”). Lifecycle nodes launched through launch_ros automatically emit events when they transition between states. The events can then be acted on through the launch framework, e.g. by emitting other events (such as requesting another state transition, which lifecycle nodes launched through launch_ros automatically have event handlers for) or triggering other actions (e.g. starting another node).
此示例中的启动文件启动两个节点,其中一个节点是具有托管生命周期的节点(“生命周期节点”)。生命周期节点通过launch_ros在状态之间转换时自动发出事件来启动。然后可以通过启动框架对事件进行操作,例如通过发出其他事件(例如请求另一个状态转换,生命周期节点通过launch_ros自动启动事件处理程序)或触发其他操作(例如,启动另一个节点)。
In the aforementioned example, various transition requests are requested of the talker lifecycle node, and its transition events are reacted to by, for example, launching a listener node when the lifecycle talker reaches the appropriate state.
在前述示例中,请求talker生命周期节点的各种转换请求,并且通过例如listener在生命周期发布器达到适当状态时启动节点来响应其转换事件。
Usage 用法
While launch files can be written as standalone scripts, the typical usage in ROS is to have launch files invoked by ROS 2 tools.
虽然启动文件可以作为独立脚本编写,但ROS中的典型用法是使用ROS 2工具调用启动文件。
For example, this launch file has been designed such that it can be invoked by ros2 launch:
例如,此启动文件的设计使其可以通过以下方式调用:ros2 launch
ros2 launch demo_nodes_cpp add_two_ints.launch.py
"""Launch a add_two_ints_server and a (synchronous) add_two_ints_client."""
import launch
import launch_ros.actions
def generate_launch_description():
server = launch_ros.actions.Node(
package='demo_nodes_cpp', node_executable='add_two_ints_server', output='screen')
client = launch_ros.actions.Node(
package='demo_nodes_cpp', node_executable='add_two_ints_client', output='screen')
return launch.LaunchDescription([
server,
client,
# TODO(wjwwood): replace this with a `required=True|False` option on ExecuteProcess().
# Shutdown launch when client exits.
launch.actions.RegisterEventHandler(
event_handler=launch.event_handlers.OnProcessExit(
target_action=client,
on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],
)),
])
Documentation 文档
The launch documentation provides more details on concepts that are also used in launch_ros.
启动文档提供了有关其中使用的概念的更多详细信息launch_ros。
Additional documentation/examples of capabilities are forthcoming. See the source code in the meantime.
其他文档/功能示例即将发布。在此期间查看源代码。
Migrating launch files from ROS 1 to ROS 2
将启动文件从ROS 1迁移到ROS2
This tutorial describes how to write XML launch files for an easy migration from ROS 1.
本教程描述了如何编写XML启动文件以便从ROS 1轻松迁移到ROS 2。
(仅用于ROS 1复习)
Background 背景
A description of the ROS 2 launch system and its Python API can be found in Launch System tutorial.
可以在Launch System教程中找到有关ROS 2启动系统及其Python API的说明。
Migrating tags from ROS1 to ROS2
从ROS1迁移标签ROS2
launch 启动
- launch is the root element of any ROS 2 launch XML file.
launch 是任何ROS 2启动XML文件的根元素。
node 节点
- Launches a new node.
启动一个新节点。
Differences from ROS 1: 与ROS 1的区别:
- type attribute is now executable.
type属性现在executable。
- The following attributes aren’t available: machine, respawn, respawn_delay, clear_params.
下面的属性是不可用:machine,respawn,respawn_delay,clear_params。
<launch>
<node pkg="demo_nodes_cpp" exec="talker"/>
<node pkg="demo_nodes_cpp" exec="listener"/>
</launch>
from launch import LaunchDescription
import launch_ros.actions
def generate_launch_description():
return LaunchDescription([
launch_ros.actions.Node(
node_namespace= "ros2", package='demo_nodes_cpp', node_executable='talker', output='screen'),
launch_ros.actions.Node(
node_namespace= "ros2", package='demo_nodes_cpp', node_executable='listener', output='screen'),
])
param 参数
- Used for passing a parameter to a node.
用于将参数传递给节点。
There’s no global parameter concept in ROS 2. For that reason, it can only be used nested in a node tag. Some attributes aren’t supported in ROS 2: type, textfile, binfile, executable, command.
ROS 2中没有全局参数概念。因此,它只能嵌套在node标签中。某些属性不支持ROS 2:type、textfile、 binfile、executablecommand。
<launch>
<node pkg="demo_nodes_cpp" exec="parameter_event">
<param name="foo" value="5"/>
</node>
</launch>
Here are some examples of how to write parameters:
以下是如何编写参数的一些示例:
<node pkg="my_package" exec="my_executable" name="my_node">
<!--A string parameter with value "1"-->
<param name="a_string" value="'1'"/>
<!--A integer parameter with value 1-->
<param name="an_int" value="1"/>
<!--A float parameter with value 1.0-->
<param name="a_float" value="1.0"/>
<!--A string parameter with value "asd"-->
<param name="another_string" value="asd"/>
<!--Another string parameter, with value "asd"-->
<param name="string_with_same_value_as_above" value="'asd'"/>
<!--Another string parameter, with value "'asd'"-->
<param name="quoted_string" value="\'asd\'"/>
<!--A list of strings, with value ["asd", "bsd", "csd"]-->
<param name="list_of_strings" value="asd, bsd, csd" value-sep=", "/>
<!--A list of ints, with value [1, 2, 3]-->
<param name="list_of_ints" value="1,2,3" value-sep=","/>
<!--Another list of strings, with value ["1", "2", "3"]-->
<param name="another_list_of_strings" value="'1';'2';'3'" value-sep=";"/>
<!--A list of strings using an strange separator, with value ["1", "2", "3"]-->
<param name="strange_separator" value="'1'//'2'//'3'" value-sep="//"/>
</node>
In ROS 2, param tags are allowed to be nested. For example:
在ROS 2中,param标签允许嵌套。例如:
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param name="group1">
<param name="group2">
<param name="my_param" value="1"/>
</param>
<param name="another_param" value="2"/>
</param>
</node>
That will create two parameters:
这将创建两个参数:
- A group1.group2.my_param of value 1, hosted by node /an_absolute_ns/my_node.
一个group1.group2.my_param的值1,由节点/an_absolute_ns/my_node托管。
- A group1.another_param of value 2 hosted by node /an_absolute_ns/my_node.
一个group1.another_param的值2,由节点/an_absolute_ns/my_node托管。
It’s also possible to use full parameter names:
也可以使用完整的参数名称:
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param name="group1.group2.my_param" value="1"/>
<param name="group1.another_param" value="2"/>
</node>
rosparam
- Loads parameters from a yaml file.
从yaml文件加载参数。
- It has been replaced with a from atribute in param tags.
它已从from属性替换param标签。
<node pkg="my_package" exec="my_executable" name="my_node" ns="/an_absoulute_ns">
<param from="/path/to/file"/>
</node>
remap 重映射
- Used to pass remapping rules to a node.
用于将重映射规则传递给节点。
- It can only be used within node tags.
它只能在node标签中使用。
<launch>
<node pkg="demo_nodes_cpp" exec="talker">
<remap from="chatter" to="my_topic"/>
</node>
<node pkg="demo_nodes_cpp" exec="listener">
<remap from="chatter" to="my_topic"/>
</node>
</launch>
include 包括
- Allows including another launch file.
允许包含另一个启动文件。
Differences from ROS 1: 与ROS 1的区别:
- Available in ROS 1, included content was scoped. In ROS 2, it’s not. Nest includes in group tags to scope them.
在ROS 1中可用,包含的内容是作用域。但在ROS 2中,它不是。Nest包含group标记以限定它们。
- ns attribute is not supported. See example of push_ros_namespace tag for a workaround.
ns属性不受支持。有关push_ros_namespace标记替换方法,请参考示例。
- arg tags nested in an include tag don’t support conditionals (if or unless).
arg标记嵌套在include标记中,不支持条件(if或unless)。
- There is no support for nested env tags. set_env and unset_env can be used instead.
不支持嵌套env标记。 set_env并且unset_env可以替代使用。
- Both clear_params and pass_all_args attributes aren’t supported.
这两个clear_params和pass_all_args属性不被支持。
See Replacing an include tag. 请参考替换包含标记。
arg
- arg is used for declaring a launch argument, or to pass an argument when using include tags.
arg用于声明启动参数,或在使用include标记时传递参数。
Differences from ROS 1: 与ROS 1的区别:
- value attribute is not allowed. Use let tag for this.
value属性是不允许的。使用let标签。
- doc is now description.
doc现在是description。
- When nested within an include tag, if and unless attributes aren’t allowed.
当嵌套在一个include标签的范围内,if和unless属性是不允许的。
<launch>
<arg name="topic_name" default="chatter"/>
<node pkg="demo_nodes_cpp" exec="talker">
<remap from="chatter" to="$(var topic_name)"/>
</node>
<node pkg="demo_nodes_cpp" exec="listener">
<remap from="chatter" to="$(var topic_name)"/>
</node>
</launch>
Passing an argument via the command line 通过命令行传递参数
See ROS 2 launch tutorial. 请参考ROS 2 launch启动教程。
env
- Sets an environment variable.
设置环境变量。
- It has been replaced with env, set_env and unset_env:
它已被替换为env,set_env和unset_env:
- env can only be used nested in a node or executable tag. if and unless tags aren’t supported.
env只能嵌套在一个node或executable标签中使用。 不支持if和unless标签。
-
- set_env can be nested within the root tag launch or in group tags. It accepts the same attributes as env, and also if and unless tags.
set_env可以嵌套在根标签launch或group标签中。它接受与env,if以及unless标签相同的属性。
- unset_env unsets an environment variable. It accepts a name attribute and conditionals.
unset_env取消设置环境变量。它接受name属性和条件。
<launch>
<set_env name="MY_ENV_VAR" value="MY_VALUE" if="CONDITION_A"/>
<set_env name="ANOTHER_ENV_VAR" value="ANOTHER_VALUE" unless="CONDITION_B"/>
<set_env name="SOME_ENV_VAR" value="SOME_VALUE"/>
<node pkg="MY_PACKAGE" exec="MY_EXECUTABLE" name="MY_NODE">
<env name="NODE_ENV_VAR" value="SOME_VALUE"/>
</node>
<unset_env name="MY_ENV_VAR" if="CONDITION_A"/>
<node pkg="ANOTHER_PACKAGE" exec="ANOTHER_EXECUTABLE" name="ANOTHER_NODE"/>
<unset_env name="ANOTHER_ENV_VAR" unless="CONDITION_B"/>
<unset_env name="SOME_ENV_VAR"/>
</launch>
group
- Allows limiting the scope of launch configurations. Usually used together with let, include and push_ros_namespace tags.
允许限制启动配置的范围。通常与let,include和push_ros_namespace标签一起使用。
Differences from ROS 1: 与ROS 1的区别:
- There is no ns attribute. See the new push_ros_namespace tag as a workaround.
没有ns属性。将新push_ros_namespace标记视为替代方法。
- clear_params attribute isn’t available.
clear_params 属性不可用。
- It doesn’t accept remap nor param tags as children.
它不接受remap和param标签作子标签。
launch-prefix configuration affects both executable and node tags’ actions. This example will use time as a prefix if use_time_prefix_in_talker argument is 1, only for the talker.
launch-prefix配置会影响标记executable和node标记的操作。此示例将time用作use_time_prefix_in_talker参数的前缀1,仅用于发布器。
<launch>
<arg name="use_time_prefix_in_talker" default="0"/>
<group>
<let name="launch-prefix" value="time" if="$(var use_time_prefix_in_talker)"/>
<node pkg="demo_nodes_cpp" exec="talker"/>
</group>
<node pkg="demo_nodes_cpp" exec="listener"/>
</launch>
machine
It is not supported at the moment. 暂不支持。
test
It is not supported at the moment. 暂不支持。
New tags in ROS 2 ROS 2中的新标签
set_env and unset_env set_env和unset_env
See env tag decription. 请参考env标签说明。
push_ros_namespace
include and group tags don’t accept an ns attribute. This action can be used as a workaround:
include和group标签不接受ns属性。此操作可用作解决方法:
<!-Other tags-->
<group>
<push_ros_namespace namespace="my_ns"/>
<!--Nodes here are namespaced with "my_ns".-->
<!--If there is an include action here, its nodes will also be namespaced.-->
<push_ros_namespace namespace="another_ns"/>
<!--Nodes here are namespaced with "another_ns/my_ns".-->
<push_ros_namespace namespace="/absolute_ns"/>
<!--Nodes here are namespaced with "/absolute_ns".-->
<!--The following node receives an absolute namespace, so it will ignore the others previously pushed.-->
<!--The full path of the node will be /asd/my_node.-->
<node pkg="my_pkg" exec="my_executable" name="my_node" ns="/asd"/>
</group><!--Nodes outside the group action won't be namespaced.--><!-Other tags-->
let
It’s a replacement of arg tag with a value attribute. 它是使用value属性arg标记的替换。
<let var="foo" value="asd"/>
executable
It allows running any executable. 它允许运行任何可执行文件
<executable cmd="ls -las" cwd="/var/log" name="my_exec" launch-prefix="something" output="screen" shell="true">
<env name="LD_LIBRARY" value="/lib/some.so"/>
</executable>
Replacing an include tag 替换包含标记
To have exactly the same behavior as Available in ROS 1, include tags must be nested in a group tag.
要与ROS 1中的“可用”具有完全相同的行为,include标记必须嵌套在group标记中。
<group>
<include file="another_launch_file"/>
</group>
To replace the ns attribute, push_ros_namespace action must be used:
要替换ns属性,必须使用push_ros_namespace操作:
<group>
<push_ros_namespace namespace="my_ns"/>
<include file="another_launch_file"/>
</group>
Substitutions 替换
Documentation about ROS 1’s substitutions can be found in roslaunch XML wiki. Substitutions syntax hasn’t changed, i.e. it still follows the $(substitution-name arg1 arg2 ...) pattern. There are, however, some changes w.r.t. ROS 1:
有关ROS 1替换的文档可以在roslaunch XML wiki中找到。替换语法没有改变,即它仍然遵循$(substitution-name arg1 arg2 ...)模式。但是,ROS 1有一些变化:
- env and optenv tags have been replaced by the env tag. $(env <NAME>) will fail if the environment variable doesn’t exist. $(env <NAME> '') does the same as ROS 1’s $(optenv <NAME>). $(env <NAME> <DEFAULT>) does the same as ROS 1’s $(env <NAME> <DEFAULT>) or $(optenv <NAME> <DEFAULT>).
env和optenv标签已被标签env取代。 如果环境变量$(env <NAME>)不存在,则会失败。 $(env <NAME> '') 与ROS 1$(optenv <NAME>)相同。 $(env <NAME> <DEFAULT>)与ROS 1$(env <NAME> <DEFAULT>)或 $(optenv <NAME> <DEFAULT>)相同。
- find has been replaced with find-pkg.
find已被find-pkg取代。
- There is a new exec-in-pkg substitution. e.g.: $(exec-in-pkg <package_name> <exec_name>).
有一个新的exec-in-pkg替代品。例如:$(exec-in-pkg <package_name> <exec_name>)。
- There is a new find-exec substitution.
有一个新的find-exec替代品。
- arg has been replaced with var. It looks at configurations defined either with arg or let tag.
arg已被var取代。它查看之前使用arg或let标记定义的配置。
- eval and dirname substitutions haven’t changed.
eval和dirname替换没有改变。
- anon substitution is not supported.
anon 不支持替换。
Type inference rules 类型推断规则
The rules that were shown in Type inference rules subsection of param tag applies to any attribute. For example:
标签param子部分Type inference rules中显示的规则适用于任何属性。例如:
<!--Setting a string value to an attribute expecting an int will raise an error.-->
<tag1 attr-expecting-an-int="'1'"/>
<!--Correct version.-->
<tag1 attr-expecting-an-int="1"/>
<!--Setting an integer in an attribute expecting a string will raise an error.-->
<tag2 attr-expecting-a-str="1"/>
<!--Correct version.-->
<tag2 attr-expecting-a-str="'1'"/>
<!--Setting a list of strings in an attribute expecting a string will raise an error.-->
<tag3 attr-expecting-a-str="asd, bsd" str-attr-sep=", "/>
<!--Correct version.-->
<tag3 attr-expecting-a-str="don't use a separator"/>
Some attributes accept more than a single type, for example value attribute of param tag. It’s usual that parameters that are of type int (or float) also accept an str, that will be later substituted and tried to convert to an int (or float) by the action.
某些属性接受多个类型,例如param标记的value属性。通常,int类型(或float类型)的参数也接受 str,稍后将替换并尝试通过操作转换为int(或float)。
文章来源: zhangrelay.blog.csdn.net,作者:zhangrelay,版权归原作者所有,如需转载,请联系作者。
原文链接:zhangrelay.blog.csdn.net/article/details/100773599
- 点赞
- 收藏
- 关注作者
评论(0)