Understanding keyed topic with multiple DDS devices

4 posts / 0 new
Last post
Offline
Last seen: 1 year 7 months ago
Joined: 01/24/2018
Posts: 2
Understanding keyed topic with multiple DDS devices

Hi all,

First post so if it is not in the relevant forum, please move it. Apologies for the long post as well.

I am currently designing a system in which I am going to have several devices that are DDS compliant and are of the same type. They might all join the same domain and same topic at one point in time. The topic is keyed. All these devices will implement only the DDS writer.

On the remote side, my application will implement the reader. I am having some problems understanding how the keys work in general. I understand the overall concept but following are some questions for which I can not find any answer. 

1. if my understanding of the keyed topic is correct, the dds writer will allocate a value to the key before writing to the topic. Let's say the system is started up with device #1 connected to the DDS domain. The device starts writing its data and might allocated key  = 1. Then later on device #2 is connected and joins the same domain and same topic. Device #2 is identical to Device #1 (for instance same sensor in a different room). Note in this example that those devices are not simple devices attached to the same application. They are independent and have their own DDS logic. Device #2 starts writing its data to the topic and will have to allocate a key value. what is stopping device #2 from allocating key = 1? if it is possible, how DDS know that the update to the topic is for device #1 or  device #2? or is it part of the writer to ensure that there is no duplicate key? If so,  how do you achieve this if the DDS writers are completely independent (for instance different applications on different nodes)?.

2. is there a way for a reader to tell a writer to use a specific value for its key? for instance if I take the above scenario, when device #1 join the DDS domain , my understanding is that the subscriber is notified (via DATA msg). Upon receiving this notification, can a reader/subscriber enforce a writer to use a specific value for the key? In this case device #1 would be "forced" to use key = 1 then when device #2 join the domain it is forced by the reader to use key = 2. The reader would be in charge of maintaining a key value database.

3. if I am using the default domain ID and several independent and identical devices join the DDS domain, how can I filter out writers and listen only to the one I want? for instance, same above scenario and I have device #1, device #2, and device #3 joining the dds domain because they are identical. However I only want to listen to device #1. I could do it if as a reader I know the key value that device #1 is using. But as a reader I don't have control over the vlaue of this key.

Note that in the above case scenarios, I have no control over what I call "devices". They are off the shelves devices that are DDS compliant and also have their topic matching mine (basically I am desiging the DDS reader side to be able to interface with any off the shelves devices compliant to DDS and indetical topic.)

Looking forwards to getting some clarifications.

Offline
Last seen: 2 months 2 days ago
Joined: 02/11/2016
Posts: 142

Hello emistral,

While I am not working for RTI I will try to help out:

1.

When using the basic qos with keyed types, DDS does not prevent multiple writers from updating the same key.

That being said, there are methods of guaranteeing only one application will update values for each key

a. You can pre-configure different devices to have different IDs.

Benefits: You can choose meaningful IDs that will be easier to monitor later, and given that you do the configuration work correctly, you are 100% sure you will have no conflicts.

You will also make sure all devices have an ID to work with.

Pitfalls: It requires configuration of every reporting device, and maintenance of that configuration as new devices are added (or devices are redeployed).

b. You can use GUIDs (most programming languages have builtin libraries to create such guids) as the key value.

Benefits: You will not need to configure each device, and still be quite certain not to have conflicting IDs (which will also result in every device having a unique ID to work with).

Pitfalls: In the very unlikely event of conflicting IDs you may not realize it very quickly and it will result in multiple devices updating the value for the same key. Also, it's harder to monitor which device is behind each ID.

Other solutions (besides the one described in the following subsection) will most likely be fairly complicated and are prone to synchronization issues.

2.

What you are describing is (as far as I'm aware) not directly supported by RTI DDS.

That being said, you can use a request reply pattern.
RTI supports such a pattern with specific api calls but you can easily implement it using the following approach:
Define two topics: topic for requests and topic for replies
Each device will send a request using some guid (you can actually just have the reader make use of the participant / writer guid of the participant / writer that sent the request)
The "reading application" will listen for requests and reply with two fields: guid received and an ID to be used by the requester
The devices will listen for replies where the guid is their guid and use the replied ID in the original topic.
It's a bit complicated but will supply unique IDs (depending on the receiving app giving out unique IDs) that may be meaningful (depending on the receiving app making IDs meaningful) without requiring configuration.

3.

In a scenario where you are writing the reading application and want to be able to filter out data from a device based on a pre-known key, it makes sense for each device to have a predefined ID (where different instances of "identical" devices must also have different IDs).
Once you've configured different devices to have different IDs, and assuming you have the hard-coded mapping of device -> ID, you can use ContentFilteredTopics to filter out data based on the ID.
You can also (although it is not advised) filter them in your code based on the ID (this will save you the time of learning how to use ContentFilteredTopics but may be quite a waste of resources in production)

Hopefully this helps,
Roy.

Offline
Last seen: 1 year 7 months ago
Joined: 01/24/2018
Posts: 2

Hi Roy,

Thanks for the answers. Your answers helped me but unfortunately because I have no control over the devices that are being connected to the domain, I can't force a device to use a predefined key or use their GUID as a key.

Same applies unfortunately to your answer to my question #2. All because I have no control of the writer. If I want to guarantee a working system, I need to put all the logic on the reader side. For instance I will rely  on DATA messages when a writers join the domain as the writer's keep-alive messages and will put a deadline qos on the topic as well. I cannot put any logic on the writer side because I have no guarantee that it will implement what is requested.

Thanks

Offline
Last seen: 6 months 1 week ago
Joined: 02/20/2014
Posts: 9

Emistral,

Have you looked at the option of just using SampleInfo's GUID information to identify the source?  I don't have things on-hand to double-check, but I'd expect you can use the original publication virtual GUID to unique identify each device.  And if I recall correctly the first half of the GUID contains the source IP which you could then use to further identify which specific sensor you're receiving data from, since I assume you at least configure the IP for each sensor.

Assuming this works, worst case you'd filter in the receiver callbacks.  There's also the option of using content filtered topics if you know the exact GUID you want.  For example, here's the filter for the GUID on the related sample (which isn't exactly what you want, but it's at least a starting point so you know this feature's there): "@related_sample_identity.writer_guid.value = &hex(00000000000000000000000000000000)".  Where the zeroes there would be the hex values for the 32-bit GUID.