ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

ROS2 to fastrtps interoperability

asked 2021-06-18 13:25:31 -0500

swhart gravatar image

Hi, I'm looking to set up a system where ROS2 nodes communicate with stand-alone (non-ROS2) FastRTPS applications. All signs point to this being possible, but i haven't seen any example on how to do this. Does anyone have any guidance on how to do this? I'm currently using an Ubuntu 20.04 foxy desktop setup. Thanks! Steve

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2021-06-21 15:18:19 -0500

swhart gravatar image

Thanks ChuiV, this is helpful. After poking around some more, was able to get some topic communication to and from a standalone fastrtps app and a ROS2 node. I had five challenges, four of which if figured out, and one of which i found a work around on, but am still not sure the best solution:

Things I figured out:

  • the necessity of the rt/ topic prefix.
  • I needed to make sure the domainID is the the same on the ROS2 side as what i am setting in my fastrtps application. this means, of course setting, an env var in the terminal i am running my ROS2 node (export ROS_DOMAIN_ID=42)
  • I needed to make sure the messages were registered using the appropriate "ROS format" prefixes. In other words <msg_package_name>::msg::dds_::<MsgType>_
  • By default, fastrtps seemed to be trying to use shared memory as its transport layer, but ROS2 wants UDP (v4). By adding the following to my fastrtps applications, things connected:

    auto localhostUdpv4Transport = std::make_shared<UDPv4TransportDescriptor>();
    PParam.rtps.useBuiltinTransports = false;
    PParam.rtps.userTransports.push_back(localhostUdpv4Transport);
    

It's probably worth sharing the whole init() function for my fastrtps application that publishes a (custom) HelloWorld.msg that my ROS2 app can subscribe to:

bool HelloWorldPublisher::init()
{
    ParticipantAttributes PParam;
    auto localhostUdpv4Transport = std::make_shared<UDPv4TransportDescriptor>();
    PParam.rtps.useBuiltinTransports = false;
    PParam.rtps.userTransports.push_back(localhostUdpv4Transport);
    PParam.rtps.builtin.discovery_config.leaseDuration = c_TimeInfinite;
    PParam.domainId = 42;
    PParam.rtps.setName("hello_world");
    mp_participant = Domain::createParticipant(PParam);

    if (mp_participant == nullptr)
    {
        return false;
    }

    //REGISTER THE TYPE
    Domain::registerType(mp_participant, &m_type);

    //CREATE THE PUBLISHER
    PublisherAttributes Wparam;
    Wparam.topic.topicKind = NO_KEY;
    Wparam.topic.topicDataType = "hello_world_msgs::msg::dds_::HelloWorld_";
    Wparam.topic.topicName = "rt/hello_world";

    // fill in the data to the msg to send, can overwrite later
    m_Hello.message("hi from RTPS");

    mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
    if (mp_publisher == nullptr)
    {
        return false;
    }

    return true;
}

In this example, I am publishing a custom hello_world_msgs/HelloWorld.msg onto a ROS2 topic /hello_world, and with ROS_DOMAIN_ID=42. A simple ROS2 subscriber can will read this topic accordingly.


The thing I have not yet found a great answer/solution to is how to get a "shared" message type that's used by ROS2 and my fastrtps application.

My hacky work-around was to build my ROS2 message package, then go find the generated .idl file in the build directory, and manually copy it to my fastrtps workspace. I then used the fastrtps tools to generate the necessary DDS classes/files that I could compile against on my dds application side.

Ideally, there would be a way to do this directly from the ROS2 generated files, but I haven't figured this out yet. Any insights or suggestions on this?

edit flag offensive delete link more
0

answered 2021-06-21 09:25:50 -0500

ChuiV gravatar image

Maybe this isn't a great example to point to, but it's the one I'm familiar with.

The PX4 Autopilot system has a fastrtps bridge that talks with an agent on an offboard computer. px4_ros_com package source

While the fastrtps agent software talks to ros2, it's not written with any ros2 libraries (other than the message generation stuff most likely.)

So that's an example of a raw fastrtps application talking to ROS2 (without modification)

The ability for a ROS2 node to talk with a raw fastrtps node (without modification) has a few caveats. The first is going to be getting message type names to match up. The second is around topic names. By default, ros2 nodes prefix all topic names with rt/, rq/, or rr/ (topic, request, response respectively...) There is a avoid_ros_namespace_conventions parameter in the rclcpp::QoS structure, but even with that enabled, it forces every topic you make to have a leading / in the topic. Bottom line: if your raw fastrtps topics start with /, then you're fine. Otherwise you'll need to change your raw fastrtps nodes to have that / prefix the topic names.

Hope that gets you going in the right direction!

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2021-06-18 13:25:31 -0500

Seen: 399 times

Last updated: Jun 21 '21