首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >码头集装箱中与ROS2节点的通信问题

码头集装箱中与ROS2节点的通信问题
EN

Stack Overflow用户
提问于 2021-01-26 11:08:44
回答 1查看 2K关注 0票数 1

我在学习ROS2。我有一个码头容器与ROS2狐狸安装在里面。

这个容器安装了许多其他东西,所以我最好处理它,而不是从DockerHub下载的东西。

容器基于Ubuntu18.04,我的主机运行Ubuntu20.04。

以下不起作用:

主机:$ docker run --net host -it <container name>

容器内:

代码语言:javascript
复制
# env | grep ROS_
ROS_DOMAIN_ID=142
ROS_VERSION=2
ROS_LOCALHOST_ONLY=0
ROS_PYTHON_VERSION=3
ROS_DISTRO=foxy


# ros2 run examples_rclpy_minimal_publisher publisher_local_function
[INFO] [1611658788.451254349] [minimal_publisher]: Publishing: "Hello World: 0"
[INFO] [1611658788.930325228] [minimal_publisher]: Publishing: "Hello World: 1"
[INFO] [1611658789.430629464] [minimal_publisher]: Publishing: "Hello World: 2"
...

在另一个终端的同一主机上:

代码语言:javascript
复制
$ source /opt/ros/foxy/setup.zsh
$ export ROS_DOMAIN_ID=142
$ env | grep ROS_
ROS_DISTRO=foxy
ROS_LOCALHOST_ONLY=0
ROS_PYTHON_VERSION=3
ROS_VERSION=2
ROS_DOMAIN_ID=142


$ ros2 run examples_rclpy_minimal_subscriber subscriber_member_function

没有来自用户的输出。

同时,我看到开放的UDP端口:

代码语言:javascript
复制
$ sudo netstat -unlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 0.0.0.0:35379           0.0.0.0:*                           2103557/python3
udp        0      0 127.0.0.1:41750         0.0.0.0:*                           1867221/python3
udp        0      0 0.0.0.0:42900           0.0.0.0:*                           2103557/python3
udp        0      0 0.0.0.0:42900           0.0.0.0:*                           1867221/python3
udp        0      0 0.0.0.0:42912           0.0.0.0:*                           2103557/python3
udp        0      0 0.0.0.0:42913           0.0.0.0:*                           2103557/python3
udp        0      0 0.0.0.0:42916           0.0.0.0:*                           1867221/python3
udp        0      0 0.0.0.0:42917           0.0.0.0:*                           1867221/python3
udp        0      0 127.0.0.1:47375         0.0.0.0:*                           2103557/python3

从186 with开始的PIDs属于主机上的ros2_daemon,PID从210 the开始属于python,运行在容器中。

如果我在容器中的另一个/bin/bash中执行订阅服务器,它就能工作,也就是说,订阅服务器打印它从发布服务器接收到的消息。

多播UDP数据报也可以工作:

集装箱内:

代码语言:javascript
复制
# ros2 multicast receive
Waiting for UDP multicast datagram...
Received from 106.xxx.xxx.xxx:45829: 'Hello World!'

主持人:

代码语言:javascript
复制
$ ros2 multicast send
Sending one UDP multicast datagram...

最新消息。我试过拉标准容器osrf/ros:foxy-桌面.实例也如预期的那样起作用。

容器中的Publisher:

代码语言:javascript
复制
$ docker pull osrf/ros:foxy-desktop
$ docker run --net host -it osrf/ros:foxy-desktop
# export ROS_DOMAIN_ID=142
# env | grep ROS_
ROS_VERSION=2
ROS_PYTHON_VERSION=3
ROS_DOMAIN_ID=142
ROS_LOCALHOST_ONLY=0
ROS_DISTRO=foxy
#ros2 run examples_rclpy_minimal_publisher publisher_local_function

[INFO] [1611670054.887068490] [minimal_publisher]: Publishing: "Hello World: 0"
[INFO] [1611670055.367854925] [minimal_publisher]: Publishing: "Hello World: 1"
...

主机上的订户:

代码语言:javascript
复制
$ ros2 run examples_rclpy_minimal_subscriber subscriber_member_function
[INFO] [1611670073.075589355] [minimal_subscriber]: I heard: "Hello World: 7"
[INFO] [1611670073.540520496] [minimal_subscriber]: I heard: "Hello World: 8"
[INFO] [1611670074.040020703] [minimal_subscriber]: I heard: "Hello World: 9"
...

更新2

回到原来的容器里。我在netstat中看到两个具有相同端口号7400的UDP套接字。可以吗?

更新:是的,是:https://stackoverflow.com/a/1694148

在上面的netstat输出中也出现了同样的现象,但是端口数不同。

代码语言:javascript
复制
$ sudo netstat -unlp
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
...
udp        0      0 0.0.0.0:39604           0.0.0.0:*                           2319288/python3
udp        0      0 0.0.0.0:7400            0.0.0.0:*                           2319288/python3
udp        0      0 0.0.0.0:7400            0.0.0.0:*                           2319267/python3
udp        0      0 0.0.0.0:7412            0.0.0.0:*                           2319267/python3
...

和程序:

代码语言:javascript
复制
$ ps axf
...
2319287 pts/4    S+     0:00      \_ /usr/bin/python3 /opt/ros/foxy/bin/ros2 run examples_rclpy_minimal_publisher publisher_local_function
2319288 pts/4    Sl+    0:01          \_ /usr/bin/python3 /opt/ros/foxy/lib/examples_rclpy_minimal_publisher/publisher_local_function
...
2319050 ?        Sl     0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id ae2da482416
2319075 pts/0    Ss+    0:00  \_ /bin/bash
2319266 pts/0    S      0:00      \_ /usr/bin/python3 /root/git/ros2_foxy/install/bin/ros2 run examples_rclpy_minimal_subscriber subscriber_member_function
2319267 pts/0    Sl     0:00          \_ /usr/bin/python3 /root/git/ros2_foxy/install/lib/examples_rclpy_minimal_subscriber/subscriber_member_function

ID 2319288的进程正在从主机上运行,我意外地切断了ps的输出。

更新3

如果不运行

  1. ,则订阅服务器将看到来自发布服务器的消息。我负担不起,因为在网络中看不到码头集装箱。

  1. I已经将容器中的订阅服务器替换为netcat (netcat -l -u 42900) --容器中的netcat已经收到了来自在其外部工作的发布服务器的消息。容器与--net=host

一起运行。

它表明容器中的网络一切正常,但是ROS2在某种程度上不正确地使用它。

我该怎么改正?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-12 09:00:19

Fast的最后一个版本在默认情况下带有SharedMemory传输。使用--net=host意味着两个SharedMemory参与者都认为他们在同一台机器上,他们试图使用SharedMemory而不是UDP进行通信。Fast-DDS团队将致力于实施一种机制来检测这种情况.同时,我可以给你两个解决方案:

  1. 使用XML在其中一个DDS参与者中禁用SharedMemory传输。

代码语言:javascript
复制
    <?xml version="1.0" encoding="UTF-8" ?>
    <profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles" >
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>CustomUdpTransport</transport_id>
                <type>UDPv4</type>
            </transport_descriptor>
        </transport_descriptors>

        <participant profile_name="participant_profile" is_default_profile="true">
            <rtps>
                <userTransports>
                    <transport_id>CustomUdpTransport</transport_id>
                </userTransports>

                <useBuiltinTransports>false</useBuiltinTransports>
            </rtps>
        </participant>
    </profiles>

  1. 在主机和容器之间启用SharedMemory。为此,您应该共享/dev/shm

代码语言:javascript
复制
docker run -ti --net host -v /dev/shm:/dev/shm <DOCKER_IMAGE>

另外,两个应用程序都应该使用相同的UID运行。在我的例子中,我的码头容器的用户是root (UID=0)。然后,我不得不以root用户的身份运行主机应用程序。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65900201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档