布吉做网站,无锡网站制作联系方式,浦东建设网站制作,深圳代理记账多少钱一月系列文章目录
ROS2 重要概念 ament_cmake_python 用户文档 ROS2 ament_cmake 用户文档 使用 rosdep 管理 ROS 2 依赖项 文章目录 系列文章目录前言一、Launch 文件示例1.1 Python 版本1.2 XML 版本1.3 YAML 版本 二、从命令行使用 Launch 文件1. Launching2. 设置参数3. 控制海…系列文章目录
ROS2 重要概念 ament_cmake_python 用户文档 ROS2 ament_cmake 用户文档 使用 rosdep 管理 ROS 2 依赖项 文章目录 系列文章目录前言一、Launch 文件示例1.1 Python 版本1.2 XML 版本1.3 YAML 版本 二、从命令行使用 Launch 文件1. Launching2. 设置参数3. 控制海龟 三、Python、XML 或 YAML 我应该使用哪种语言四、为什么要使用 ROS 2 Launch如果觉得内容不错请点赞、收藏、关注 前言
ROS 2 launch 文件可以用 Python、XML 和 YAML 编写。本指南介绍了如何使用这些不同的格式来完成相同的任务并对何时使用每种格式进行了讨论。 一、Launch 文件示例
下面是一个用 Python、XML 和 YAML 实现的 Launch 文件。每个 Launch 文件都执行以下操作 使用默认值设置命令行参数 包含另一个 launch 文件 在另一个命名空间中包含另一个启动文件 启动节点并设置其名称空间 启动一个节点设置其名称空间并在该节点中设置参数使用参数 创建一个节点将消息从一个话题重新映射到另一个话题
1.1 Python 版本
首先介绍涉及到的几个 类 和 方法
ament_index_python.get_package_share_path(package_name, print_warningTrue)
以 pathlib.Path 的形式返回给定软件包的共享目录。
例如如果您将软件包 foo 安装到/home/user/ros2_ws/install并以 foo作为参数调用此函数那么它将返回一个代表/home/user/ros2_ws/install/share/foo的路径然后您就可以用它来构建共享文件的路径即 get_package_share_path(foo) /urdf/robot.urdflaunch.LaunchDescription
基础 LaunchDescriptionEntity
可启动系统的描述。
该描述由一系列实体组成这些实体代表了系统设计师的意图。
该描述还可能有参数参数由该启动描述中的 launch.actions.DeclareLaunchArgument 操作声明。
该描述的参数可通过 get_launch_arguments() 方法访问。参数是通过搜索此启动描述中的实体和每个实体的描述可能包括由这些实体产生的实体收集的。launch.actions.declare_launch_argument.DeclareLaunchArgument(Action)
基础 Action
声明新启动参数的 Action。
启动参数存储在同名的 启动配置 中。请参阅 launch.actions.SetLaunchConfiguration 和 launch.substitutions.LaunchConfiguration。
在 launch.LaunchDescription 中声明的任何启动参数都会在包含该启动描述时作为参数显示出来例如在 launch.actions.IncludeLaunchDescription 动作中作为附加参数或在使用 ros2 launch .... 启动时作为命令行参数。
除了名称也是参数结果的存储位置外启动参数还可能有一个默认值、一个有效值选择列表和一个描述。如果给出了默认值那么该参数就变成了可选参数默认值将被放置在启动配置中。如果没有给出默认值并且在包含启动说明时也没有给出值则会发生错误。如果给出了一个选择列表而给定值不在其中则会发生错误。
默认值可以使用 Substitutions但名称和描述只能是 Text因为它们在启动前需要一个有意义的值例如在列出命令行参数时。
需要注意的是声明启动参数必须在启动描述的某个部分而这个部分在不启动的情况下是可以描述的。例如如果你在条件组中或作为事件处理程序的回调声明了一个启动参数那么像 ros2 launch 这样的工具可能无法在启动描述之前知道该参数。在这种情况下该参数在命令行上将不可见但如果该参数在访问后未满足要求且没有默认值则可能引发异常。
换句话说访问该操作的后置条件要么是同名的启动配置设置了值要么是由于没有设置任何值且没有默认值而引发异常。但是前置条件并不能保证在条件或情况夹杂后面的参数是可见的。
例如
ld LaunchDescription([DeclareLaunchArgument(simple_argument),DeclareLaunchArgument(with_default_value, default_valuedefault),DeclareLaunchArgument(with_default_and_description,default_valuesome_default,descriptionthis argument is used to configure ...),DeclareLaunchArgument(mode,default_valueA,descriptionChoose between mode A and mode B,choices[A, B]),# other actions here, ...
])launch.actions.GroupAction
基础 Action
可产生其他操作的 Action。
此操作用于嵌套其他操作而无需包含单独的启动说明同时还可选择具有一个条件与所有其他操作一样、扩展和转发启动配置和环境变量以及/或仅为组及其产生的操作声明启动配置。
ScopedTrue 时对启动配置和环境变量的更改仅限于组操作中的操作范围。
当 scopeedTrue 和 forwardingTrue 时所有现有的启动配置和环境变量都可在作用域上下文中使用。
当 scopeTrue 和 forwardingFalse 时所有现有的启动配置和环境变量都会从作用域上下文中移除。
launch_configurations 字典中定义的任何启动配置都将在当前上下文中设置。当 scopeedFalse 时即使 GroupAction 已完成这些配置也将持续存在。当 scopedTrue 时这些配置将仅对 GroupAction 中的动作可用。当 scopeTrue 和 forwardingFalse 时launch_configurations 字典将在清除前进行评估然后在清除的 scope 上下文中重新设置。launch.actions.IncludeLaunchDescription
基础 Action
包含启动描述源并在访问时生成其实体的动作。
可以向启动描述传递参数这些参数是通过 launch.actions.DeclareLaunchArgument 动作声明的。
如果给定的参数与已声明的启动参数名称不匹配则仍会使用 launch.actions.SetLaunchConfiguration 动作将其设置为启动配置。这样做的原因是在给定的启动描述中并非总能检测到所有已声明启动参数类的实例。
另一方面如果给定的启动描述声明了启动参数但未向此操作提供其值有时会引发错误。不过只有当声明的启动参数是无条件的有时声明启动参数的操作只有在特定情况下才会被访问并且没有默认值可供选择时才会产生这种错误。
有条件包含的启动参数如果没有默认值在尽力进行参数检查后仍无法提前发现未满足的参数时最终将引发错误。launch.launch_description_sources.PythonLaunchDescriptionSource(LaunchDescriptionSource)
基础 LaunchDescriptionSource
Python 启动文件的封装可在启动过程中加载。launch.substitutions.LaunchConfiguration(Substitution)
可访问启动配置变量的替代变量。launch.substitutions.TextSubstitution(Substitution)
可对单个字符串文本进行替换。PushROSNamespace(Action)
推送 ros 命名空间的动作。
在有作用域的 GroupAction 中使用时它会自动弹出。没有其他方法可以弹出它。 XMLLaunchDescriptionSource(FrontendLaunchDescriptionSource)
封装 XML 启动文件可在启动过程中加载。YAMLLaunchDescriptionSource(FrontendLaunchDescriptionSource)
封装 YAML 启动文件可在启动过程中加载。Node(ExecuteProcess)
执行一个 ROS 节点的操作。Python 代码如下 # example_launch.pyimport osfrom ament_index_python import get_package_share_directoryfrom launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import GroupAction
from launch.actions import IncludeLaunchDescription
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 PushRosNamespace
from launch_xml.launch_description_sources import XMLLaunchDescriptionSource
from launch_yaml.launch_description_sources import YAMLLaunchDescriptionSourcedef 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_valueTextSubstitution(text0))background_g_launch_arg DeclareLaunchArgument(background_g, default_valueTextSubstitution(text255))background_b_launch_arg DeclareLaunchArgument(background_b, default_valueTextSubstitution(text0))chatter_py_ns_launch_arg DeclareLaunchArgument(chatter_py_ns, default_valueTextSubstitution(textchatter/py/ns))chatter_xml_ns_launch_arg DeclareLaunchArgument(chatter_xml_ns, default_valueTextSubstitution(textchatter/xml/ns))chatter_yaml_ns_launch_arg DeclareLaunchArgument(chatter_yaml_ns, default_valueTextSubstitution(textchatter/yaml/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 a Python launch file in the chatter_py_ns namespacelaunch_py_include_with_namespace GroupAction(actions[# push_ros_namespace to set namespace of included nodesPushRosNamespace(chatter_py_ns),IncludeLaunchDescription(PythonLaunchDescriptionSource(os.path.join(get_package_share_directory(demo_nodes_cpp),launch/topics/talker_listener_launch.py))),])# include a xml launch file in the chatter_xml_ns namespacelaunch_xml_include_with_namespace GroupAction(actions[# push_ros_namespace to set namespace of included nodesPushRosNamespace(chatter_xml_ns),IncludeLaunchDescription(XMLLaunchDescriptionSource(os.path.join(get_package_share_directory(demo_nodes_cpp),launch/topics/talker_listener_launch.xml))),])# include a yaml launch file in the chatter_yaml_ns namespacelaunch_yaml_include_with_namespace GroupAction(actions[# push_ros_namespace to set namespace of included nodesPushRosNamespace(chatter_yaml_ns),IncludeLaunchDescription(YAMLLaunchDescriptionSource(os.path.join(get_package_share_directory(demo_nodes_cpp),launch/topics/talker_listener_launch.yaml))),])# start a turtlesim_node in the turtlesim1 namespaceturtlesim_node Node(packageturtlesim,namespaceturtlesim1,executableturtlesim_node,namesim)# start another turtlesim_node in the turtlesim2 namespace# and use args to set parametersturtlesim_node_with_parameters Node(packageturtlesim,namespaceturtlesim2,executableturtlesim_node,namesim,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(packageturtlesim,executablemimic,namemimic,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_py_ns_launch_arg,chatter_xml_ns_launch_arg,chatter_yaml_ns_launch_arg,launch_include,launch_py_include_with_namespace,launch_xml_include_with_namespace,launch_yaml_include_with_namespace,turtlesim_node,turtlesim_node_with_parameters,forward_turtlesim_commands_to_second_turtlesim_node,])1.2 XML 版本
!-- example_launch.xml --launch!-- args that can be set from the command line or a default will be used --arg namebackground_r default0 /arg namebackground_g default255 /arg namebackground_b default0 /arg namechatter_py_ns defaultchatter/py/ns /arg namechatter_xml_ns defaultchatter/xml/ns /arg namechatter_yaml_ns defaultchatter/yaml/ns /!-- include another launch file --include file$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py /!-- include a Python launch file in the chatter_py_ns namespace--group!-- push_ros_namespace to set namespace of included nodes --push_ros_namespace namespace$(var chatter_py_ns) /include file$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py //group!-- include a xml launch file in the chatter_xml_ns namespace--group!-- push_ros_namespace to set namespace of included nodes --push_ros_namespace namespace$(var chatter_xml_ns) /include file$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.xml //group!-- include a yaml launch file in the chatter_yaml_ns namespace--group!-- push_ros_namespace to set namespace of included nodes --push_ros_namespace namespace$(var chatter_yaml_ns) /include file$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.yaml //group!-- start a turtlesim_node in the turtlesim1 namespace --node pkgturtlesim execturtlesim_node namesim namespaceturtlesim1 /!-- start another turtlesim_node in the turtlesim2 namespaceand use args to set parameters --node pkgturtlesim execturtlesim_node namesim namespaceturtlesim2param namebackground_r value$(var background_r) /param namebackground_g value$(var background_g) /param namebackground_b value$(var background_b) //node!-- perform remap so both turtles listen to the same command topic --node pkgturtlesim execmimic namemimicremap from/input/pose to/turtlesim1/turtle1/pose /remap from/output/cmd_vel to/turtlesim2/turtle1/cmd_vel //node
/launch1.3 YAML 版本
# example_launch.yamllaunch:# args that can be set from the command line or a default will be used
- arg:name: background_rdefault: 0
- arg:name: background_gdefault: 255
- arg:name: background_bdefault: 0
- arg:name: chatter_py_nsdefault: chatter/py/ns
- arg:name: chatter_xml_nsdefault: chatter/xml/ns
- arg:name: chatter_yaml_nsdefault: chatter/yaml/ns# include another launch file
- include:file: $(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py# include a Python launch file in the chatter_py_ns namespace
- group:- push_ros_namespace:namespace: $(var chatter_py_ns)- include:file: $(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py# include a xml launch file in the chatter_xml_ns namespace
- group:- push_ros_namespace:namespace: $(var chatter_xml_ns)- include:file: $(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.xml# include a yaml launch file in the chatter_yaml_ns namespace
- group:- push_ros_namespace:namespace: $(var chatter_yaml_ns)- include:file: $(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.yaml# start a turtlesim_node in the turtlesim1 namespace
- node:pkg: turtlesimexec: turtlesim_nodename: simnamespace: turtlesim1# start another turtlesim_node in the turtlesim2 namespace and use args to set parameters
- node:pkg: turtlesimexec: turtlesim_nodename: simnamespace: turtlesim2param:-name: background_rvalue: $(var background_r)-name: background_gvalue: $(var background_g)-name: background_bvalue: $(var background_b)# perform remap so both turtles listen to the same command topic
- node:pkg: turtlesimexec: mimicname: mimicremap:-from: /input/poseto: /turtlesim1/turtle1/pose-from: /output/cmd_velto: /turtlesim2/turtle1/cmd_vel二、从命令行使用 Launch 文件
1. Launching
上述任何启动文件都可以通过 ros2 launch 运行。要在本地试用它们可以创建一个新软件包然后使用
ros2 launch package_name launch_file_name或通过指定 launch 文件的路径直接运行该文件
ros2 launch path_to_launch_file2. 设置参数
要设置传递给启动文件的参数应使用 key:value 语法。例如可以用以下方式设置 background_r 的值
ros2 launch package_name launch_file_name background_r:255ros2 launch path_to_launch_file background_r:2553. 控制海龟
要测试重映射是否有效可以在另一个终端运行以下命令来控制海龟
ros2 run turtlesim turtle_teleop_key --ros-args --remap __ns:/turtlesim1三、Python、XML 或 YAML 我应该使用哪种语言 ROS 1 中的启动文件是用 XML 编写的因此对于来自 ROS 1 的用户来说XML 可能是最熟悉的。 对于大多数应用程序来说选择哪种 ROS 2 启动格式取决于开发人员的偏好。不过如果你的启动文件需要有 XML 或 YAML 无法实现的灵活性你可以使用 Python 来编写启动文件。由于以下两个原因使用 Python 编写 ROS 2 启动文件更为灵活 Python 是一种脚本语言因此您可以在启动文件中使用该语言及其库。 ros2/launch一般启动功能和 ros2/launch_rosROS 2 特定启动功能都是用 Python 编写的因此你可以访问 XML 和 YAML 可能无法提供的较低级别的启动功能。
尽管如此用 Python 编写的启动文件可能比 XML 或 YAML 编写的文件更复杂、更冗长。
四、为什么要使用 ROS 2 Launch
ROS 2 系统通常由运行在多个不同进程甚至不同机器上的多个节点组成。虽然每个节点都可以单独运行但很快就会变得非常麻烦。
ROS 2 中的启动系统旨在通过一条命令自动运行多个节点。它可以帮助用户描述系统配置然后按描述执行。系统配置包括运行哪些程序、在哪里运行、传递哪些参数以及 ROS 特有的约定通过为每个组件提供不同的配置可以方便地在整个系统中重复使用组件。它还负责监控已启动进程的状态并对这些进程的状态变化做出报告和/或反应。
上述所有内容都在一个启动文件中指定该文件可以用 Python、XML 或 YAML 编写。使用 ros2 launch 命令运行该启动文件后所有指定的节点都将运行。
设计文档详细介绍了 ROS 2 启动系统的设计目标目前尚未提供所有功能。 如果觉得内容不错请点赞、收藏、关注