[SOLVED] Publishing an object through RTI Connector for Python

5 posts / 0 new
Last post
Offline
Last seen: 1 year 2 months ago
Joined: 07/23/2018
Posts: 20
[SOLVED] Publishing an object through RTI Connector for Python

I am interfacing `ROS2` with 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


Lets say the topic the are communicating is called **`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 ?

A usual flow in RTI Connector is :

get an instance of the output :

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

and the post an instance :

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

Now how can I write an object of type `DetectedObject` instead of `setNumber` ?

gianpiero's picture
Offline
Last seen: 8 months 6 days ago
Joined: 06/02/2010
Posts: 174

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

Offline
Last seen: 1 year 2 months ago
Joined: 07/23/2018
Posts: 20

This definitely cleared out the conceptual problem. However I have a question :

  • what does objects[1] represent ? I guess the first element of the object, Then shouldnt it be object[1].id and object[2].name and so on...?
isabel's picture
Offline
Last seen: 2 months 1 week ago
Joined: 02/13/2017
Posts: 11

Hi Aakash,

 

Yes, the objects[1] represents the first element of the sequence of your type.

 

In this code you are filling the elements of an instance, where the type is MyMessage, which elements are a short id and a sequences of DetectedObjects (called objects).

So when you are giving values to objects[1].id, objects[1].name, and so on, you are filling the first element of the sequence.

Is you set objects[2].id you will be giving values to the second element of the sequence of your type.

 

Does it make sense?

I hope it clarifies you question.

 

Regards,

Isabel

 
Offline
Last seen: 1 year 2 months ago
Joined: 07/23/2018
Posts: 20

Thank you for the clarification. I understood it now :)