在不稳定网络中使用服务质量设置

背景

请阅读文档页面 关于 QoS 设置的信息,了解 ROS 2 中可用支持的背景信息。

在此演示中,我们将生成一个发布相机图像的节点,另一个节点订阅该图像并在屏幕上显示。然后我们将模拟它们之间的有丢包的网络连接,并展示不同的服务质量设置如何处理这个不良连接。

先决条件

本教程假设您已经安装了一个 工作正常的 ROS 2 系统 和 OpenCV。请参阅 OpenCV 文档 以获取安装说明。您还需要 ROS 包 image_tools

sudo apt-get install ros-humble-image-tools

运行演示

在运行演示之前,请确保您的计算机连接了可工作的摄像头。

一旦您安装了ROS 2,请源码您的设置文件:

. <path to ROS 2 install space>/setup.bash

然后运行:

ros2 run image_tools showimage

目前还不会发生任何事情。showimage 是一个订阅者节点,正在等待 image 主题的发布者。

注意:稍后您需要使用“Ctrl-C”关闭“showimage”进程。您不能只是关闭窗口。

在另一个终端中,源化安装文件并运行发布节点:

ros2 run image_tools cam2image

这将从您的网络摄像头发布一张图像。如果您的计算机没有连接摄像头,还有一个命令行选项可以发布预定义的图像。

ros2 run image_tools cam2image --ros-args -p burger_mode:=True

在此窗口中,您将看到终端输出:

Publishing image #1
Publishing image #2
Publishing image #3
...

将会弹出一个标题为“view”的窗口,显示您的摄像头视频。在第一个窗口中,您将看到订阅者的输出:

Received image #1
Received image #2
Received image #3
...

注解

macOS用户: 如果这些示例不起作用或者您收到一个类似``ddsi_conn_write failed -1``的错误,那么您需要增加系统范围的UDP数据包大小:

$ sudo sysctl -w net.inet.udp.recvspace=209715
$ sudo sysctl -w net.inet.udp.maxdgram=65500

这些更改不会在重启后生效。如果您希望更改持久生效,请将以下行添加到``/etc/sysctl.conf``(如果文件不存在,则创建该文件):

net.inet.udp.recvspace=209715
net.inet.udp.maxdgram=65500

命令行选项

在其中一个终端中,将原始命令添加-h标志:

ros2 run image_tools showimage -h

添加网络流量

警告

本演示的这一部分在RTI的Connext DDS上不适用。当在同一主机上运行多个节点时,RTI Connext DDS实现使用共享内存和环回接口。降低环回接口的吞吐量不会影响共享内存,因此两个节点之间的流量不会受到影响。

注解

下一部分仅适用于Linux系统。

然而,在macOS和Windows上,您可以使用工具“Network Link Conditioner”(xcode工具套件的一部分)和“Clumsy”(http://jagt.github.io/clumsy/index.html)来实现类似的效果,但它们不在本教程中介绍。

我们将使用Linux的网络流量控制实用程序``tc``(http://linux.die.net/man/8/tc)。

sudo tc qdisc add dev lo root netem loss 5%

这个神奇的咒语将在本地环回设备上模拟5%的丢包。如果您使用更高分辨率的图像(例如``--ros-args -p width:=640 -p height:=480``),您可能希望尝试较低的丢包率(例如``1%``)。

接下来,我们启动``cam2image``和``showimage``,很快我们会注意到两个程序似乎减慢了图像传输的速率。这是由于默认的QoS设置的行为引起的。在有丢包的通道上强制可靠性意味着发布者(在本例中为``cam2image``)将重发网络数据包,直到从消费者(即``showimage``)接收到确认。

现在让我们尝试运行这两个程序,但使用更合适的设置。首先,我们将使用``-p reliability:=best_effort``选项来启用尽力而为的通信。现在,发布者将仅尝试传递网络数据包,并不期望来自消费者的确认。我们现在看到,``showimage``一侧的一些帧已经丢失,所以在运行``showimage``的shell中的帧编号将不再是连续的:

尽力而为的图像传输

完成后,请记得删除队列规则:

sudo tc qdisc delete dev lo root netem loss 5%