.. _understanding_aliasing: Understanding Topic and Type Aliasing ===================================== ROS 2 Topic and Type Mangling ----------------------------- In ROS 2, topic and type names undergo "topic mangling," meaning that the topic name set in an application is not the topic name sent on the wire. For example, topics in ROS 2 are prefixed with ``rt/``. If creating the topic ``Foo``, the announced topic would be ``rt/Foo``. Similarly, a type name in ROS 2 has ``dds_::`` inserted between the namespace and the final typename, and is suffixed with ``_``, so a type name ``Foo`` becomes ``dds_::Foo_`` on the wire and a type name ``namespace::Foo`` becomes ``namespace::dds_::Foo_``. As a result, ROS2 applications can't communicate with DDS applications that are created with the same topic name, because the names on the wire are not the same. Starting in *Connext* 7.5.0, ROS 2 and DDS applications can communicate using a simple setting described in :ref:`configuring_aliasing`. You can turn the property on or off with an XML QoS profile, rather than having to regenerate your types and recompile your code with the "mangled" topic and type names. Connext Topic and Type Aliasing ------------------------------- Using the ``dds.ros.enable_interoperability`` property (see :ref:`configuring_aliasing`), *Connext* can perform the ROS 2 topic and type "mangling" automatically. Topic and type aliasing in *Connext* works by propagating aliases in the endpoint discovery data that can be considered as valid alternatives to the primary topic and type names. If you are using Wireshark® to look at the endpoint data, the aliases are propagated with the parameter IDs ``PID_TOPIC_NAME_ALIASES`` and ``PID_TYPE_NAME_ALIASES``. The rules that |CONNEXT| uses to generate the topic aliases when ``dds.ros.enable_interoperability`` is set to true are as follows: - Prefix normal topic names with ``rt/``. For example, |CONNEXT| transforms the normal topic name ``Foo`` into ``rt/Foo``. - Prefix requester topic names created using the RTI Request/Reply API with ``rq/`` and suffix them with ``Request``. For example, |CONNEXT| transforms the requester topic name ``Foo`` into ``rq/FooRequest``. - Prefix replier topics created using the RTI Request/Reply API with ``rr/`` and suffix them with ``Reply``. For example, |CONNEXT| transforms the replier topic name ``Foo`` into ``rr/FooReply``. Type names are also subject to a slightly different form of mangling. ROS 2 types often have a namespace (in IDL, this is indicated with the module name). Consider a type created in ROS 2 with the following IDL: .. code-block:: text module tutorial_interfaces { module msg { struct Num { int64 num; }; }; }; Type names in ROS 2 have ``dds_::`` inserted between the namespace and the final type name, or at the beginning of the type name if no namespace is present (we identify a namespace as fields separated with ``::``). They are then suffixed with ``_``. For example, the above IDL file would result in the typename ``tutorial_interfaces::msg::Num::num`` in *Connext*, but in ROS 2 would become ``tutorial_interfaces::msg::dds_::Num::num_``. This also applies to types without namespaces: the typename ``FooType`` (without a namespace) in *Connext* would become ``dds_::FooType_`` in ROS 2. When a 7.5.0-or-later *Connext* application encounters another 7.5.0-or-later *Connext* application that announces topic aliases, it compares its own topic name (and topic name alias if it exists) to both the topic name and topic name alias of the other application when performing topic matching. (See :ref:`configuring_aliasing` for information on setting the properties.) If either the topic name or topic name alias matches, the endpoint is considered compatible and discovery takes place. For example, a |CONNEXT| application creates a writer with the following code snippet: .. code-block:: C++ // Get the default participant QoS dds::domain::qos::DomainParticipantQos participant_qos = dds::core::QosProvider::Default().participant_qos(); // Add dds.ros.enable_interoperability as a property to the participant QoS rti::core::policy::Property property = participant_qos.policy(); property.set(rti::core::policy::Property::Entry("dds.ros.enable_interoperability", "TRUE")); participant_qos << property; // Create a participant with the dds.ros.enable_interoperability property dds::domain::DomainParticipant participant(0, participant_qos); // Create a topic and endpoint on the participant dds::topic::Topic topic(participant, "Foo"); dds::pub::Publisher publisher(participant); dds::dds::pub::DataWriter writer(publisher, topic); In this case, the "primary" topic name that the topic is created with is ``Foo``. If ``dds.ros.enable_interoperability`` is set to true, the topic alias will be ``rt/Foo``; however, if ``dds.ros.use_mangled_names_as_default`` is also set to true (see :ref:`configuring_aliasing`), the "primary" topic that |CONNEXT| sends on the wire will be ``rt/Foo``, with ``Foo`` sent as the topic alias. When a reader in another application discovers this writer, it will see that its "primary" topic name is ``rt/Foo``: .. code-block:: C++ // Get the publication data of the remote writer in the reader application std::vector matched_writers = rti::sub::matched_publication_data(reader); for (const auto& pub_data : matched_pubs) { // This will print "rt/Foo" std::cout << "Matched publication topic: " << pub_data.topic_name() << std::endl; } This behavior, enabled by the properties discussed in :ref:`configuring_aliasing`, allows ROS 2 applications to believe that the |CONNEXT| writer was created on the topic ``rt/Foo`` (to match the ROS 2 topic), when it was really created on the topic ``Foo``. The same is done when encountering a type name alias; however, this type name comparison only occurs if TypeCode and TypeObject propagation is not enabled. If TypeCodes or TypeObjects are propagated, the type representation will be compared to perform matching and the type name will be ignored. See `Introduction to TypeCode `__ in the *Core Libraries User's Manual* for more information.