Routing Service between domain with Different DataTypes

23 posts / 0 new
Last post
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25
Routing Service between domain with Different DataTypes

I have two applications runing DDS on different domain, 0 & 1. Both have different topics with different DataTypes. I want to route specific topics from Domain 1 to 0. When I tried this, I would get error stating "Incompatible offered QoS on DataWriter assocated with topic. Is it possible and how do I using the routing service for this? 

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

Are you saying that you want to route a topic in one domain to a different topic in a different domain and that the two topics have different datatypes?

Or is it that you just have different topics with different datatypes that you want to route through Routing Service, but the topic name and topic datatype will be the same in the domain from where its published to the domain to where its subscribed.

I assume that you are able to configure Routing Service to do this in the second case (which is pretty much the example configuration distributed with Routing Service).

For the first case, you can't use <auto_route>s which require the same topic and datatype for <input> and <output>, instead, you'll have to use <topic_route> to define a route between domains and between topics with different names and/or different datatypes.  You may need to use an assignment transformation if the names of the members in the input datatype and the output datatypes aren't exactly the same, and you need to map the member of the input Topic to a member of the output Topic.  See the example here, an example configuration file is provided in the workspace in your home directory, C:\Users\<name>\Documents\rti_workspace\6.0.1\examples\routing_service\shapes\topic_bridge_w_transf1.xml.

HOWEVER, the error that you are seeing has nothing to do with the configuration of routes, ""Incompatible offered QoS on DataWriter assocated with topic".  I'm not sure where you are seeing this error message, but assuming that it's being produced by Routing Service, this means that the DataWriter created by Routing Service to publish the data into the <output> domain has a QOS configuration that's incompatible with the applications that subscribe to the data in the <output> domain.

You'll need to use standard techniques to figure out what QOS values are incompatible, I suggest running RTI Admin Console, and then modify the QOS of the DataWriter created by Routing Service to use either the same QOS profile as used to create the DataReaders in the subscribing apps or to just configure the offending QOS policy with compatible values using the <datawriter_qos> tag in the <output> tag of a <topic_route>, see this doc.

 

 

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Hi Howard,

It's the first instance. I have to two applications on different domain with different topics and datatypes in each. I want to route topics from Domain 1 to Domain 0 while keeping the datatypes of Domain 1. I was using the admin console to view the topics in both domains and saw the error right after i started the routing service using the xml.

File Attachments: 
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

I have the IDLs I want to use. The main IDL includes reference to other IDLs. Is there a way to convert the IDLs completely to DDS xml?

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

How do you mean "reference"?  Do you mean that it uses "#include <another.idl>" syntax?  Or does it just use types that were defined in another file?

Are these IDL files currently used to generate the type support code for your DDS applications?   I assume that your IDL files are passed to rtiddsgen to generate the type support code for the datatypes for use in your DDS applications.

If so, you can use rtiddsgen with the "-convertToXML" command line option to convert an IDL to XML format.  However, you'll need to do it for all of the IDL files that you have if one IDL file includes another IDL file.

Why do you need to convert the datatypes defined in IDL to XML?

 

 

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

I'm not sure what you mean by keeping the dataypes of Domain 1.  If the data types are different in Domain 0 and Domain 1, then when you deal with the data in Domain 0, Routing Service needs to use the data type defined in that domain, and the same for dealing with data in Domain 1.

As explained in my previous response, within Routing Service, you can use an assignment transformation to map members of the datatype defined in Domain 1 to the members of the datatype in Domain 0.

The RoutingService XML configuration file that you provided assumes that the datatypes in the input and output domains are exactly the same, which is why you see your error.

You have to change the Routing Service configuration to use specific data types in the input domain and output domain as well as apply an assignment transformation.  In my previous response, I pointed at an example that you can use and learn from.

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Thanks for the explanation and sorry for the confusion. When I mention "reference", it's using the "#include <>". I want to convert to xml so I can include the type definition in the Routing Service. I thought that I could use the "Type convert" or "Code Generator" to conver the IDL so that it could be included in the routing service.

Looking at the "topic_bridge_w_transf2.xml", is this only possible by creating the function to transform the type? I'm still new to routing service and will need detail explanation on how to do this. 

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

No, you don't have to create a transform.  If you look at the XML configuration file, you'll see:

 

    <plugin_library name="Transformations">
        <!--
        This transformation is implemented in that shared library. It allows
        copying fields from one dynamic data sample to other dynamic data sample
        -->
        <transformation_plugin name="Assign">
            <!--
            By specifing this value, RTI Router will search for
            librtirsassigntransf.so in Unix systems and rtirsassigntransfs.dll in Windows
            systems. The path to search will be the current directory or if
            not there, the RTI Route executable directory, which is where it
            actually is.
            -->
            <dll>rtirsassigntransf</dll>
            <create_function>RTI_RoutingServiceAssignTransformationPlugin_create</create_function>
        </transformation_plugin>
    </plugin_library>

This instances an "rtiassigntransf" which is a DLL/shared library that is distributed with RTI Connext DDS that can be used by Routing Service to map members of one type to another per the other configuration in the file:

                    <transformation plugin_name="Transformations::Assign">
                        <!--
                        We will pass some parameters that the modify method will
                        receive to configure this instance. This transformation expects
                        a set of assignments between a field of the output sample
                        type and a field of the input sample type.

                            In our case, we are getting the fields we need, the
                            coordinates of the input ShapeType sample, and
                            assigning them to the output PointType sample
                            -->
                            <property>
                                <value>
                                    <element>
                                        <name>x_coord</name>
                                        <value>x</value>
                                    </element>
                                    <element>
                                        <name>y_coord</name>
                                        <value>y</value>
                                    </element>
                                </value>
                            </property>
                        </transformation>

So, what project are you working on?  I assume that you have an RTI developer license and the project has support from RTI.  If so, you can ask your support contact (a developer on your project that has been assigned RTI support access) to get additional help directly from RTI's support team.

 

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

In that example, the datatype (ShapeType) exists in both domains and it's just switching coordinates. If datatype I have in domain 1 does not exists in domain 0, can I use the custom code to assign it to domain 0 without defining the datatype in that domain?

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

Your input datatype and your output datatype don't have to be the same datatype.  In the configuration file for Routing Service

                    <input participant="1">
                        <topic_name>Topic1</topic_name>
                        <registered_type_name>Type1</registered_type_name>
                    </input>
                    <output>
                        <!-- Same output topic and type -->
                        <topic_name>Topic2</topic_name>
                        <registered_type_name>Type2</registered_type_name>
                       

                        <transformation plugin_name="Transformations::Assign">
                            <property>
                                <value>
                                    <element>
                                        <name>outputfield1</name>
                                        <value>inputfield1</value>
                                    </element>
                                    <element>
                                        <name>outputfield2</name>
                                        <value>inputfield2</value>
                                    </element>
                                    ...
                                </value>
                            </property>
                        </transformation>

                    </output>

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Hi Howard, I think we're talking about different things. I have an application running on Domain 1 and a different application running on Domain 0. I want to send the topic(s) from Domain 1 to Domain 0 and make changes in Domain 0 software to read the topic(s). I'm using the routing service from Domain 1 to pass the topic(s). When I use the Admin Console to view the topic(s) on Domain 0, I don't see them. I see the process for the routing service on Domain 1 in the admin console. The two applications I'm running are on different machine but within the same subnet.

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

So if configured correctly, Routing Service will create 2 DomainParticipants, one on domain 0 and one on domain 1.  And it will also create the Topics for Domain 0 and Domain 1.

It's likely to be a configuration problem, if you only see that Routing Service has created topics for domain 1 and not domain 0.  In which case, if you post the configuration, I can help troubleshoot.

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Here's the xml i'm using for the routing service:

 

<?xml version="1.0"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/5.3.0/rti_routing_service.xsd">

<!--
**********************************************************************
RTI Routing service - 
**********************************************************************
This reads VehicleStatus from domain 1 and publish to domain 0.

**********************************************************************
-->


<!--
This is the routing service configuration for this example
-->
<routing_service name="DomainRoute">

<annotation>
<documentation>
Reads Status from domain 1 and publish to domain 0.
</documentation>
</annotation>

<domain_route name="DomainRoute" enabled="true">
<participant_1>
<domain_id>1</domain_id>
</participant_1>
<participant_2>
<domain_id>0</domain_id>
</participant_2>

<!--
A session with default configuration that contains a single topic route
-->
<session name="Session" enabled="true">

<topic_route name="Domain1toDomain0">
<!-- Reading data from participant_1 -->
<input participant="1">
<!--
Reading a type whose registered name is StatusTypeICD.
As we don't register ourselves on participant_1, its actual
type code will have to be discovered when the router runs
-->
<registered_type_name>StatusTypeICD</registered_type_name>
<!--
Reading topic Status
-->
<topic_name>Status</topic_name>
</input>
<output>
<!-- Writing the same type -->
<registered_type_name>StatusTypeICD</registered_type_name>
<topic_name>Status</topic_name>
</output>

</topic_route>

</session>
</domain_route>
</routing_service>

</dds>

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

So, I see the same topic name and topic type being used for the input (domain 1) and output (domain 0).  Didn't you say that you had a different type for the output?  If so, you need to change your configuration to specify the datatype that you want to use in domain 0.

In addition, Routing Service won't create the datareaders for the input or datawriters for the output if it doesn't know the definition of the datatype.  It usually finds out the definition by discovering an application that uses that datatype in the domain.

So, if you don't have an application that subscribes to a Topic with the datatype in domain 0, then RS won't be able to create a DataWriter until you do.  Similarily, need an application that publishes a Topic with the input datatupe in domain 1 for the RS to create a DataReader.

Just running Admin Console won't trigger RS to create any of the DataReaders/DataWriters that it uses since Admin Console itself has no knowledge of user datatypes on startup.

 

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

The same topic will be use for domain 0. The problem I'm having is that I don't see the topic in Domain 0. The application on Domain 1 does publish the topic on Domain 1. I currently don't have anything subscribing to the topic on Domain 0. I had thought that I could us RS to create the topic on Domain 0 since the application on Domain 1 was publishing the topic and use the Admin Console to see the topic on Domain 0.

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

I thought that your original problem was that you had different data types in the 2 domains and wanted to map members of one datatype to the other by the Routing Service?

In any case, no Routing Service has no idea what the datatype definition is in Domain 0 until you create a DataReader in that domain.  And when that happens, it'll create a DataWriter for the route.

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Hi Howard,

Thanks for the help. I've created the reader in python on domain VM and I'm running into issue where it erroring out due to types not define in the xml. I got the below error. In the xml, I define the qos_library, domain_library, and domain_participant_library. I didn't include the types.

 

rticonnextdds_connector.rticonnextdds_connector.Error: Failed to create Connector:
DDS_XMLHelper_lookupXmlTypeCode:!get XMLTypeCode
DDS_XMLRegisterType_get_type_code:!get XML TypeCode not found
DDS_FactoryXmlPlugin_assertTopic:!Assert registered type
DDS_DomainParticipantFactory_create_participant_from_config:!create participant with default parameters
RTIDDSConnector_newI:!new participant
RTIDDSConnector_EntitiesLookupList_delete:RTIDDSConnector

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

Hi, so to use RTI Connector, you have to define the data type in the XML file.  If you don't, you won't be able to use RTI Connector.

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Is there another option to create a subscriber without the types define on the reader?

Howard's picture
Offline
Last seen: 3 hours 37 min ago
Joined: 11/29/2012
Posts: 605

Not with RTI Connector.  DDS must know a data type inorder to receive the data for a topic, deserialize it and provided it to a reader.  Using the standard C/C++ APIs, you can use the builtin discovery Topics to discover the datatypes of user Topics that are being published and then use those dataypes to create a dynamic data reader to subscribe to the data.

I believe that you can also do that with the new Python DDS API that is still in a pre-productization phase but can be found here.

https://community.rti.com/static/documentation/connext-dds/current/api/connext_dds/api_python/

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Thanks. I'll look at that. I was able to convert my IDLs to xml. I remember there's a way to reference the type to a file. Do you have the syntax for that?

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Nevermind. I found the article on this. Here's the link in case other needs it.

<types><include file="../file.xml" /></types>

 

How to load multiple XML files with RTI Connector | Data Distribution Service (DDS) Community RTI Connext Users

Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2020
Posts: 25

Wasn't sure if I should continue with this topic for the issue i'm having with the python script producing error related to the XML TypeCode not found. I posted it on this topic Python: Failed to create Connector | Data Distribution Service (DDS) Community RTI Connext Users