Search code examples
pythonrosdata-distribution-serviceros2rti-dds

Publishing sequences/objects through RTI Conector to ROS2 applications


I am interfacing ROS2 with a native RTI DDS Connector for Python where I am publishing messages in RTI connector and subscribing in ROS2.

I have the following message structure for the message named DetectedObjectList:

int16 id
// An array of objects of another message type
DetectedObject[ ] objects

This is interpreted as unbounded sequences in IDL.

Another message named DetectedObject:

int16 id
string name
int16 x
int16 y

Let's say the topic used for communication is "objects" and the message type is "DetectedObjectList".

Since the subscriber in ROS2 is subscribing to id of type int16 and objects of type DetectedObject[], how can I publish an object from RTI connector?

The usual flow in RTI Connector is:

  • Get an instance of the output:

    output = connector.getOutput("MyPublisher::MyDataWriter")

  • Post an instance:

    output.instance.setNumber("id", 5)

    output.write()

How can I write an object of type DetectedObject instead of setNumber?


Solution

  • I don't have experience with ROS, but I'll try to help with the DDS/Connector part.

    As far as I know in DDS you cannot specify an unbounded array. You can have unbounded Sequences, but not arrays. So, if you are using a type that looks like this:

    struct DetectedObject {
      short id;
      string name;
      short x;
      short y;
    };
    
    
    struct MyMessage {
      short id;
      DetectedObject objects[10];
    };
    

    or you have an unbounded sequence instead:

    struct DetectedObject {
      short id;
      string name;
      short x;
      short y;
    };
    
    
    struct MyMessage {
      short id;
      sequence<DetectedObject> objects;
    };
    

    Then your connector code will be something like this:

    connector = rti.Connector("MyParticipantLibrary::PubParticipant",
                              filepath + "/ROS.xml")
    outputDDS = connector.getOutput("MyPub::MyTopicWriter")
    
    for i in range(1, 500):
        # There are two ways to set values in an instance:
    
        # 1. Field by Fields:
        outputDDS.instance.setNumber("id", 1)
            #note index, for now, starts from 1. This may change in the future
        outputDDS.instance.setNumber("objects[1].id", 2)
        outputDDS.instance.setString("objects[1].name", "aName")
        outputDDS.instance.setNumber("objects[1].x", 3)
        outputDDS.instance.setNumber("objects[1].y", 4)
        outputDDS.write()
    
            # OR
    
        # 2. By first creating a dictionary and then setting it all at once:
        myDict = {'id': 5, 'objects': [{'id': 6, 'name': '', 'x': 7, 'y': 8}]}
        outputDDS.instance.setDictionary(myDict)
        outputDDS.write()
        sleep(2)
    

    Maybe somebody else can contribute more about the ROS <--> DDS mapping when it comes to unbounded arrays.

    I hope this help, Gianpiero