Ask Your Question
0

[ROS2] Configure TCP communication for cloud endpoint

asked 2020-07-28 01:52:59 -0500

Charles K. gravatar image

updated 2021-01-21 12:38:09 -0500

jayess gravatar image

Hi,

I am trying to configure the default rmw_fastrtps middleware in ROS2 to accept messages from a eProsima FastDDS producer via TCP.

The communication between a local eProsima FastDDS producer and a ROS2 node based on the RTPS (UDP) protocol works fine (tested with osrf/ros2 docker image). The idea behind switching to a TCP based DDS communication is that the ROS2 application should run in a public cloud environment that can accept DDS messages from eProsima FastDDS participants.

I could successfully test the producer to cloud communication with two FastDDS participants (local and cloud) according to the documentation: https://fast-dds.docs.eprosima.com/en...

When trying to modify the rmw_fastrtps middleware for accepting TCP connections (compare https://github.com/ros2/rmw_fastrtps) I get following exception when starting the ROS2 executable:

[XMLPARSER Error] Error adding the transport tcp_transport_1. There is other transport with the same id -> Function insertTransportById
[XMLPARSER Error] Error adding profile 'TCPParticipant' from file 'DEFAULT_FASTRTPS_PROFILES.xml' -> Function extractParticipantProfile
terminate called after throwing an instance of 'eprosima::fastcdr::exception::NotEnoughMemoryException' what():  Not enough memory in the buffer stream

DEFAULT_FASTRTPS_PROFILES.xml

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<transport_descriptors>
    <transport_descriptor>
        <transport_id>tcp_transport_1</transport_id>
        <type>TCPv4</type>
        <sendBufferSize>9216</sendBufferSize>
        <receiveBufferSize>9216</receiveBufferSize>
        <listening_ports>
            <port>7400</port>
        </listening_ports>
        <wan_addr>172.17.0.2</wan_addr>
    </transport_descriptor>
</transport_descriptors>

<participant profile_name="TCPParticipant">
    <rtps>
        <userTransports>
            <transport_id>tcp_transport_1</transport_id>
        </userTransports>
        <useBuiltinTransports>false</useBuiltinTransports>
    </rtps>
</participant>
</profiles>

Changing the ID did not help.

I could not find any examples if a TCP based communication is even possible. Even in the rclpy documentation I couldn’t find any hints that the TCP transport could be configured programmatically.

Is this possible? What other option can be chosen when the ROS2 participant should run in a cloud environment?

edit retag flag offensive close merge delete

Comments

Hi, did this end-up working for you?

I am running into the same issue. Communication between native FastDDS applications (https://github.com/eProsima/Fast-DDS/...) seems to be working, but not in ROS2. I even tried this on the ROS2 Foxy release.

Any pointers? Thanks.

vmanchal gravatar image vmanchal  ( 2020-09-03 14:11:08 -0500 )edit

Hi, sorry for the late reply. I have given up finding a solution. My assumption was that the client libraries are abstracting too much from the actual middleware implementation.

Charles K. gravatar image Charles K.  ( 2020-10-14 05:58:38 -0500 )edit

1 Answer

Sort by » oldest newest most voted
2

answered 2021-01-21 04:56:47 -0500

EduardoPonz gravatar image

Hi everyone,

I think your example should work with some ticking.

[XMLPARSER Error] Error adding the transport tcp_transport_1. There is other transport with the same id -> Function 
insertTransportById
[XMLPARSER Error] Error adding profile 'TCPParticipant' from file 'DEFAULT_FASTRTPS_PROFILES.xml' -> Function 
extractParticipantProfile

From this error, it seems that you're using the same XML file to create more than one Fast DDS participant. This will happen if you're instantiating more than one context within the directory where DEFAULT_FASTRTPS_PROFILES.xml is located. Can that be the case? I'd suggest applying that XML only for the node you want. To do that, you could name the file differently, and then use environment variable FASTRTPS_DEFAULT_PROFILES_FILE to point to that file (see Environment Variables)

terminate called after throwing an instance of 'eprosima::fastcdr::exception::NotEnoughMemoryException' what():  Not enough memory in the buffer stream

This error will be shown if you application uses unbounded types (which is very common in ROS 2). It originates from using history memory policy = PREALLOCATED_MEMORY_MODE, which preallocates memory for the samples, which in your case then exceed the buffer size, thus generating the error. Even though that value is the default for Fast DDS, it is not the default when using ROS 2. Can it be that you're setting environment variable RMW_FASTRTPS_USE_QOS_FROM_XML=1? As stated here, that has some implications that are needed to be addressed in the XML. I'd suggest using PREALLOCATED_WITH_REALLOC_MEMORY_MODE instead. With this memory mode, Fast DDS will simply allocate more memory for you buffer if needed (see Memory management policy).

Furthermore, in order for your participant profile to be loaded in ROS 2, you'd need to add the attribute is_default_profile="true" to the <participant> tag (see Example).

edit flag offensive delete link more

Comments

Hi Eduardo, thank you very munch for the hints! Currently we have a slightly changed setup running, but I will try to check your proposed solution if time allows.

Charles K. gravatar image Charles K.  ( 2021-01-27 03:00:20 -0500 )edit

Happy to help!

EduardoPonz gravatar image EduardoPonz  ( 2021-01-27 04:12:02 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2020-07-28 01:41:48 -0500

Seen: 339 times

Last updated: Jan 21