在不稳定网络中使用服务质量设置
背景
请阅读文档页面 关于 QoS 设置的信息,了解 ROS 2 中可用支持的背景信息。
在此演示中,我们将生成一个发布相机图像的节点,另一个节点订阅该图像并在屏幕上显示。然后我们将模拟它们之间的有丢包的网络连接,并展示不同的服务质量设置如何处理这个不良连接。
先决条件
本教程假设您已经安装了一个 工作正常的 ROS 2 系统 和 OpenCV。请参阅 OpenCV 文档 以获取安装说明。您还需要 ROS 包 image_tools
。
sudo apt-get install ros-humble-image-tools
# Clone and build the demos repo using the branch that matches your installation
git clone https://github.com/ros2/demos.git -b humble
运行演示
在运行演示之前,请确保您的计算机连接了可工作的摄像头。
一旦您安装了ROS 2,请源码您的设置文件:
. <path to ROS 2 install space>/setup.bash
. <path to ROS 2 install space>/setup.bash
call <path to ROS 2 install space>/local_setup.bat
然后运行:
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
添加网络流量
警告
本演示的这一部分在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%