使用Fast DDS Discovery Server作为发现协议 [社区贡献] [待校准@7319]

Goal目标: 本教程将展示如何使用Fast DDS Discovery Serverdiscovery发现协议来使用launchROS 2节点。 [待校准@7320]

Tutorial教程级别: Intermediate中级 [待校准@6713]

Time时间: 20 20分钟 [待校准@7181]

背景

从ROS 2EloquentElusor开始,Fast DDS Discovery Server协议是一个提供集中动态发现机制的特性,而不是默认情况下DDS中使用的分布式机制。本教程解释了如何使用Fast DDS Discovery Server功能作为发现通讯来运行一些ROS 2示例。 [待校准@7321]

为了获取有关可用发现配置的更多信息,请查看 “以下文档 <https:// fast-dds.docs.eprosima.com/en/v2.1.0/fastdds/discovery y.html> _ or read the `Fast DDS Discovery Server specific documentation[待校准@7322]

[需手动修复的语法] Simple Discovery ProtocolDDS standard 中定义的标准方案。然而,在某些情况下,它已经知道缺点。 [待校准@7323]

  • 它不能有效扩展,因为随着新节点的增加,交换数据包的数量显著增加。 [待校准@7324]

  • 它需要多播功能,在某些情况下可能无法可靠地工作,例如WiFi。 [待校准@7325]

[需手动修复的语法]Fast DDS Discovery Server提供了一种客户端-服务器架构,允许节点使用中间服务器相互连接。每个节点充当 * 发现客户端 *,与一个或多个 * 发现服务器 * 共享其信息,并从中接收发现信息。这减少了与发现相关的网络流量,并且不需要多播功能。 [待校准@7326]

../../_images/ds_explanation.svg

这些发现服务器可以是独立的、重复的或相互连接的,以便在网络上创建冗余并避免单点故障。 [待校准@7327]

Fast DDS Discovery Serverv2 [待校准@7328]

最新的ROS 2FoxyFitzroy版本 (2020年12月) 包括了新版本,Fast DDS Discovery Server版本2。此版本包含新的筛选器功能,可进一步减少发送的发现消息的数量。这个版本使用不同节点的话题来决定两个节点是否希望通信,或者它们是否可以保持不匹配 (即没有发现对方)。下图显示了发现消息的减少: [待校准@7329]

../../_images/ds1vs2.svg

这个建筑减少发送服务器与客户端之间剧作家调用y。在下图中,显示了 RMF Clinic demonstration 在发现阶段的网络流量减少: [待校准@7330]

../../_images/discovery_server_v2_performance.svg

为了使用此功能,可以使用 XML configuration for Participants 配置发现服务器。也可以使用 fastdds toolenvironment variable 来配置发现服务器,这是本教程中使用的方法。有关发现服务器配置的更详细说明,请访问 the Fast DDS Discovery Server documentation[待校准@7331]

先决条件

本教程假设您有一个ROS 2Foxy (或更高版本) installation 。如果您的安装使用的ROS 2版本低于Foxy,则不能使用 fastdds 工具。因此,为了使用发现服务器,您可以更新仓库以使用不同的Fast DDS版本,或者使用 Fast DDS XML QoS configuration 配置发现服务器。 [待校准@7332]

运行本教程 [待校准@7333]

[需手动修复的语法] talker-listener ROS 2例程创建一个每秒发布一次 "hello world" 消息的 talker 节点和一个监听这些消息的 listener 节点。 [待校准@7334]

通过 sourcing ROS 2 you will get access to the CLI tool fastdds. This tool gives access to the discovery tool __, 可以用于发现服务器launch。此服务器将管理连接到它的节点的发现过程。 [待校准@7335]

重要

不要忘记在每个新的航站楼都开张 source ROS 2[待校准@7336]

设置发现服务器 [待校准@7337]

开始launch成为发现服务器账号0,端口11811 (默认端口) 并侦听所有可用接口。 [待校准@7338]

打开新终端并运行: [待校准@7339]

fastdds discovery --server-id 0

Launch监听节点 [待校准@7340]

执行侦听器例程,以收听 /chatter 话题。 [待校准@7341]

在新终端中,将环境变量 ROS_DISCOVERY_SERVER 设置为发现服务器的位置。(不要忘记在每个新终端中源文件ROS 2) [待校准@7342]

export ROS_DISCOVERY_SERVER=127.0.0.1:11811

[需手动修复的语法]Launch监听节点。使用参数 “-- remap __ node:= listener_discovery y_server” 更改本教程的节点名称。 [待校准@7343]

ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_discovery_server

这将创建一个ROS 2节点,该节点将自动调用y为发现服务器创建客户端,并连接到之前创建的服务器以执行发现,而不是使用多播。 [待校准@7344]

Launch健谈者节点 [待校准@7345]

打开一个新终端,并像以前一样设置 ROS_DISCOVERY_SERVER 环境变量,以便节点启动发现客户端。 [待校准@7346]

export ROS_DISCOVERY_SERVER=127.0.0.1:11811
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_discovery_server

你现在应该看到说话者发布 "hello world" 消息,以及接收这些消息的听众。 [待校准@7347]

演示发现服务器执行情况 [待校准@7348]

到目前为止,没有证据表明这个例子和标准的说话者-听众例子运行不同。要清楚地对此进行例程,请运行另一个未连接到发现服务器的节点。在新终端中运行一个新的监听程序 (默认情况下监听 /chatter 话题),并检查它是否没有连接到已经运行的说话者。 [待校准@7349]

ros2 run demo_nodes_cpp listener --ros-args --remap __node:=simple_listener

新侦听器节点不应接收 "hello world" 消息。 [待校准@7350]

为了最终验证一切是否正常运行,可以使用简单发现协议 (默认的DDS分布式发现机制) 创建一个新的talker进行发现。 [待校准@7351]

ros2 run demo_nodes_cpp talker --ros-args --remap __node:=simple_talker

现在,您应该看到 simple_listener 节点接收来自 simple_talker 的 "hello world" 消息,而不是来自 talker_discovery_server 的其他消息。 [待校准@7352]

可视化工具 rqt_graph [待校准@7353]

可以使用 rqt_graph 工具来验证该示例的节点和结构。请记住,为了将 rqt_graph 与发现服务器协议一起使用 (即,查看 listener_discovery_servertalker_discovery_server 节点),必须在launch之前设置 ROS_DISCOVERY_SERVER 环境变量。 [待校准@7354]

高级用例 [待校准@7355]

以下各节显示了发现服务器的不同功能,这些功能允许您通过网络构建强大的发现服务器。 [待校准@7356]

服务器冗余 [待校准@7357]

通过使用 fastdds 工具,可以创建多个发现服务器。发现客户端 (ROS节点) 可以根据需要连接到任意数量的服务器。这允许有一个冗余网络,即使某些服务器或节点意外关闭,该网络也可以工作。下图显示了提供服务器冗余的简单体系结构。 [待校准@7358]

../../_images/ds_redundancy_example.svg

在多个终端中,运行以下代码以与冗余服务器建立通讯。 [待校准@7359]

fastdds discovery --server-id 0 --ip-address 127.0.0.1 --port 11811
fastdds discovery --server-id 1 --ip-address 127.0.0.1 --port 11888

--server-id N means server with id N. When referencing the servers with ROS_DISCOVERY_SERVER, server 0 must be in first place and server 1 in位居第二。 [待校准@7360]

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker
export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

现在,如果这些服务器中的一个发生故障,仍然会有可用的发现功能,并且节点仍然会发现彼此。 [待校准@7361]

备份服务器 [待校准@7362]

[需手动修复的语法]Fast DDS Discovery Server允许创建具有备份功能的服务器。这允许服务器在关机的情况下恢复其保存的最后状态。 [待校准@7363]

../../_images/ds_backup_example.svg

不同终端运行以下代码建立通讯带备份服务器。 [待校准@7364]

fastdds discovery --server-id 0 --ip-address 127.0.0.1 --port 11811 --backup
export ROS_DISCOVERY_SERVER="127.0.0.1:11811"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker
export ROS_DISCOVERY_SERVER="127.0.0.1:11811"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

几个备份文件发现服务器的工作目录 (目录是launched)。两个 SQLite 文件和两个 json 文件包含启动新服务器并在发生故障时恢复故障服务器状态所需的信息,避免了发现过程再次发生的需要,并且不会丢失信息。 [待校准@7365]

发现分区 [待校准@7366]

可以拆分与发现服务器的通信,以便在发现信息中创建虚拟分区。这意味着只有当两个端点之间存在共享发现服务器或发现服务器网络时,它们才会相互了解。我们将使用两个独立的服务器执行一个示例。下图显示了该架构。 [待校准@7367]

../../_images/ds_partition_example.svg

通过这种模式, Listener 1 将与 Talker 1Talker 2 相连,因为它们共享 Server 1Listener 2 将与 Talker 1 联系,因为他们共享 Server 2 。但是 Listener 2 不会听到来自 Talker 2 的消息,因为它们不共享任何发现服务器或发现服务器,包括通过冗余发现服务器之间的连接间接共享。 [待校准@7368]

运行第一个侦听本地主机的服务器,默认端口为11811。 [待校准@7369]

fastdds discovery --server-id 0 --ip-address 127.0.0.1 --port 11811

在另一个终端中,使用另一个端口 (在本例中为端口11888) 运行第二个服务器侦听本地主机。 [待校准@7370]

fastdds discovery --server-id 1 --ip-address 127.0.0.1 --port 11888

现在,在不同的终端中运行每个节点。使用 ROS_DISCOVERY_SERVER 环境变量来决定它们连接到哪个服务器。注意 ids must match[待校准@7371]

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_1
export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_1
export ROS_DISCOVERY_SERVER="127.0.0.1:11811"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_2
export ROS_DISCOVERY_SERVER=";127.0.0.1:11888"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_2

我们应该看到 Listener 1 是如何从两个谈话者节点接收信息的,而 Listener 2 是在一个不同于 Talker 2 的分区,因此不接收来自它的信息。 [待校准@7372]

注解

一旦两个端点 (ROS节点) 发现了彼此,它们就不需要它们之间的发现服务器网络来监听彼此的消息。 [待校准@7373]

将Fast DDS Discovery Server与简单发现协议进行比较 [待校准@7374]

为了比较使用简单发现协议 (用于分布式发现的默认DDS机制) 或发现服务器的执行节点,提供了两个脚本,用于执行talker和许多侦听器并分析此期间的网络流量。对于这个实验, tshark 需要安装在你的系统上。配置文件是强制性的,以避免使用进程内模式。 [待校准@7375]

注解

这些脚本需要发现服务器关闭功能,该功能仅适用于比ROS 2Foxy提供的版本更新的版本。为了使用此功能,请使用Fast DDSv2.1.0或更高版本编译ROS 2。 [待校准@7376]

这些脚本的特征是用于高级目的的参考,它们的研究留给了用户。 [待校准@7377]

  • : 下载: “bash网络流量生成器 <脚本/生成 _ 发现 _ 包.bash>” [待校准@7378]

  • : 下载: “python 3图生成器 <脚本/发现 _ 数据包.Py>” [待校准@7379]

  • : 下载: “xml配置 <脚本/no_intrprocess_configuration.Xml>” [待校准@7380]

运行bash脚本路径 setup.bash 文件源文件ROS 2作为参数。这将生成用于简单发现的流量跟踪。使用第二个参数 SERVER 执行相同的脚本。它将生成使用发现服务器的跟踪。 [待校准@7381]

注解

根据您的 tcpdump 配置,此脚本可能需要 sudo 特权才能读取网络设备上的流量。 [待校准@7382]

两次执行完成后,运行Python脚本以生成类似于以下图形的图形。 [待校准@7383]

$ export FASTRTPS_DEFAULT_PROFILES_FILE="no_intraprocess_configuration.xml"
$ sudo bash generate_discovery_packages.bash ~/ros2_foxy/install/local_setup.bash
$ sudo bash generate_discovery_packages.bash ~/ros2_foxy/install/local_setup.bash SERVER
$ python3 discovery_packets.py
../../_images/discovery_packets.svg

该图是实验特定运行的结果。读者可以执行脚本并生成自己的结果进行比较。可以很容易地看出,使用发现服务时会减少网络流量。 [待校准@7384]

流量的减少是避免每个节点宣布自己并等待网络上每个其他节点的响应的结果。这在大型架构中创建了大量流量。这种方法的减少随着节点数量的增加而增加,使得这种体系结构比简单的发现协议方法更具可扩展性。 [待校准@7385]

新的Fast DDS Discovery Serverv2自 * Fast DDS * v2.0.2起可用,取代了旧的发现服务器。在此新版本中,那些不共享话题的节点将自动调用y彼此不发现,从而保存连接它们及其端点所需的全部发现数据。上面的实验没有显示这种情况,但即使如此,由于ROS 2节点的隐藏基础设施话题,流量的大幅减少也可以得到重视。 [待校准@7386]