rticommunity / rticonnextdds-connector

RTI Connector for Connext DDS is a lightweight technology that enables DDS data to be accessed with Javascript (Node.js), Python, and Lua.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add GetDictionary to Infos class (CON-23)

ilya1725 opened this issue · comments

With the current implementation it is not possible to get the full DDS_SampleInfo object that corresponds to the data sample. Right now it is possible to only read if the sample is valid.
Will it be possible to add method getDictionary(self,index) to Infos class to read the full DDS_SampleInfo object?

Thank you.

Hello @ilya1725 ,

You are right: we do not expose all the info. We have plans of doing it at one point. But like #37 i am not sure when.

Would it be possible for you to request this features to support@rti.com? That will help increasing priority.

Best

Hi @gianpiero ,
Sure, I can bug support@rti.com.

Regards.

@ilya1725,

This request has been submitted by our support (CON-23)

Hi,
So I also needed to expose a few parameters from the SampleInfos structure.

I realized that I could get at them using the getStringFromInfos and getNumberFromInfos, but also alot of them haven't been exposed. For my purpose source_timestamp and reception_timestamp were enough so I have exposed them. (Find below my diff)

@gianpiero Is it ok if i submit this as a patch or will you be going another route to expose the SampleInfos struct.

diff --git a/rticonnextdds_connector/rticonnextdds_connector.py b/rticonnextdds_connector/rticonnextdds_connector.py
index 9333923..9843503 100644
--- a/rticonnextdds_connector/rticonnextdds_connector.py
+++ b/rticonnextdds_connector/rticonnextdds_connector.py
@@ -128,6 +128,14 @@ rtin_RTIDDSConnector_getBooleanFromInfos = rti.RTIDDSConnector_getBooleanFromInf
 rtin_RTIDDSConnector_getBooleanFromInfos.restype  = ctypes.c_int
 rtin_RTIDDSConnector_getBooleanFromInfos.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p]
 
+rtin_RTIDDSConnector_getStringFromInfos = rti.RTIDDSConnector_getStringFromInfos
+rtin_RTIDDSConnector_getStringFromInfos.restype = ctypes.c_char_p
+rtin_RTIDDSConnector_getStringFromInfos.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p]
+
+rtin_RTIDDSConnector_getNumberFromInfos = rti.RTIDDSConnector_getNumberFromInfos
+rtin_RTIDDSConnector_getNumberFromInfos.restype = ctypes.c_double
+rtin_RTIDDSConnector_getNumberFromInfos.argtypes = [ ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p]
+
 rtin_RTIDDSConnector_getSamplesLength = rti.RTIDDSConnector_getInfosLength
 rtin_RTIDDSConnector_getSamplesLength.restype = ctypes.c_double
 rtin_RTIDDSConnector_getSamplesLength.argtypes = [ctypes.c_void_p,ctypes.c_char_p]
@@ -184,6 +192,12 @@ class Infos:
 	def isValid(self, index):
 		return rtin_RTIDDSConnector_getBooleanFromInfos(self.input.connector.native,tocstring(self.input.name),index,tocstring('valid_data'));
 
+	def getSourceTime(self, index):
+		return rtin_RTIDDSConnector_getNumberFromInfos(self.input.connector.native,tocstring(self.input.name),index,tocstring('source_timestamp'));
+
+	def getReceptionTime(self, index):
+		return rtin_RTIDDSConnector_getNumberFromInfos(self.input.connector.native,tocstring(self.input.name),index,tocstring('reception_timestamp'));
+
 class Input:
 	def __init__(self, connector, name):
 		self.connector = connector;

Hello @sid5291 ,

I would like to avoid having a getXXX for each single field. We did not discuss this internally yet, but it think i would like to have a dictionary with all the fields together easily accessibile without having to implement getter functions for each one of them?

Does it make sense?

Hi @gianpiero,

Yes that does make sense. This was a little "hacky" for sure.

Also am I right in saying that some of the fields for Infos have not yet been implemented like the sample_state and view_state as I get back 0's/None's if I try a get on them or am I doing something wrong ?

Thank you

Hello @sid5291,

You are right: only those two fields are exposed right now. You are not doing anything wrong!

best

Hi @gianpiero,

Sorry for reviving this discussion again .. So i was working on getting reception_time for the samples and use it for some computation but i cant seem to understand how to derive the real world time from it .. It doesn't seem to be based on system time, and the weirder thing is that I seem to be getting a negative value.

Could you maybe provide some insight on the epoch that this timestamp is based on and how you are deriving it from the DDS_Time_t struct ..

Thank you for your help.

Hello @sid5291 ,

No problem: this is why we have github!
If I remember correctly DDS_Time_t should have two fields: sec and nanosec.

What the connector should return are milliseconds transformed this way:

double millisec = info->reception_timestamp.sec*1000;
millisec = millisec + info->reception_timestamp.nanosec/1000000;

does this info helps? Let me know. if not i will try to do some experiment myself

Hi @gianpiero ,

Thanks for your quick response..

This is what I suspected, Thank you for clarifying this .. The issue I'm having is that I'm getting a negative time stamp which seems to be an error to me, is this expected behaviour or could this be an overflow/casting problem?

This may actually be a more general question to do with the way DDS manages timestamps, but I would like to convert this timestamp to the Unix Epoch so therefore I would like to know what reference you are using internally to calculate this timestamp. I wasn't able to find any clear documentation about this.

Thank you for all your help
Sid

@sid5291 ,

I am looking at the code and i think i found an issue in the way i convert DDS_Time_t into the double that you get from the connector API.

I am going to implement a fix (CON-34). Would it be possible for you to test the library ? If yes, can you please let me know on what architecture are you running? It should be one of this: [link]

Let me know

Hello @sid5291 ,

I did some tests with the release library and, in python, i used

ms = input.infos.getReceptionTime(j);
toPrint = repr(ms);
print(toPrint);
print(datetime.datetime.fromtimestamp(ms/1000.0))

and with the release library i get negative numbers too:

-1943784869.0
1969-12-09 04:03:35.131000
-1943780200.0
1969-12-09 04:03:39.800000
-1943770164.0
1969-12-09 04:03:49.836000

I did some changes and fixed the way we do the conversion. And now I get correct values:

1488410801636.0
2017-03-01 15:26:41.636000
1488410808740.0
2017-03-01 15:26:48.740000
1488410817500.0
2017-03-01 15:26:57.500000
1488410817636.0
2017-03-01 15:26:57.636000
1488410827738.0
2017-03-01 15:27:07.738000
1488410837773.0
2017-03-01 15:27:17.773000

I think the bug is fixed, and we will update the libraries with the next release. Meanwhile I can provide you with an engineering build. Would that work? If yes, let me know your architecture.

best,
gianpiero

Hi @gianpiero ,

Thank you very much for fixing the issue and testing it on your side. My target architecture is x64Linux, If you could provide the engineering build I can start using it for my application.

Thank You,
Sid

Hi @sid5291,

Thanks for taking the time to test it. I just emailed you the library.

Best,
Gianpiero

@sid5291 verified the library and the fix to CON-34 works fine. It will be available with the next release

CON-23 is still open.

Hi @gianpiero ,

I tried to add the infos.getReceptionTime(j) to my reader code and I get an Attribute Error. Is it still accessible?

    if inputDDS.infos.isValid(j):
    self.topicDict = inputDDS.samples.getDictionary(j)
        ms = inputDDS.infos.getReceptionTime(j)

AttributeError: 'Infos' object has no attribute 'getReceptionTime'