How to publish fixed payload size data ? + casting 'DDS.StringDataWriter' to 'DDS.BytesDataWriter' ERROR !

7 posts / 0 new
Last post
Offline
Last seen: 9 years 10 months ago
Joined: 05/25/2014
Posts: 6
How to publish fixed payload size data ? + casting 'DDS.StringDataWriter' to 'DDS.BytesDataWriter' ERROR !

Hello Everybody,

I have two questions + I need code troubleshooting.  

1# How I can send fixed payload size using data writer with certain publishing rate to mimic sensor behavior? 

2# Is it possible to send different string using StringDataWriter with the same payload (string) size all the time? 

 

ERROR:

I used DynamicDataWriter or BytesDataWriter but I always get error here:

bytes_DW = (DDS.BytesDataWriter)
participant.create_datawriter(
topic,
DDS.Publisher.DATAWRITER_QOS_DEFAULT,
null, /* Listener */
DDS.StatusMask.STATUS_MASK_NONE);

error: Unable to cast object of type 'DDS.StringDataWriter' to type 'DDS.BytesDataWriter'.

I'm using visual studio 2010 in window 8 environment. 

Thank in Advance.

Keywords:
rip
rip's picture
Offline
Last seen: 20 hours 13 min ago
Joined: 04/06/2012
Posts: 324

Hi,

In the Java implementation, a String is not a byte (octet) array, which is why the cast fails.  It's just a plain String object.  If you want it as bytes, use the native Java methods to do so (String has a method that returns a byte array).

1) If you define a type with an array, as in

struct myDumptruckType { 
     array<octet, 30> sand; 
};

The serialized RTPS data payload* will always be 30 octets (answering question 2), even if they are empty (ie, 0x0).  If you use a sequence (sequence<octet, 30> gravel) and gravel is empty, then only a size (0x00) is sent. 

* not the RTPS message in its entirety, as that will have RTPS header and sub-header and additional information included.

But -- unless the sensor is actually generating octets -- you don't want to do this, because you aren't sending octet data, you are sending data (shorts, integers, floats or doubles).  If you send an octet array, you defeat DDS's ability to handle the data as data and force yourself to write your own data marshaling/demarshaling (keeping endianness, 32bit vs 64bit, etc in your code, all of which DDS does for you).

Based on your initial comments, I don't think you are doing DDS optimally, in how you are trying to mimic a sensor.  Instead, use an application to read the sensor, populate a DDS Type instance with the data, and publish it data-centrically:

struct mySensorType { 
    string<32> sensorId; //@key
    sequence<double, 8> payload;
};

The middleware now has the necessary information to allow data validation, content-filtered topics, etc.  This is how a sensor like the Leap Motion is handled.

Data rate:  If you are generating sensor data for testing or simulation, and trying to get a sub-tick (one system clock tick, usually 100Hz on Linux or 60Hz on Windows), you will need to use some other method then Thread.sleep(0), as that only gets you system clock tick rate.  If your sensor is slower than the system clock rate, your resolution will still be based on the system clock tick.

 

 

 

rip
rip's picture
Offline
Last seen: 20 hours 13 min ago
Joined: 04/06/2012
Posts: 324

I think I don't really understand what you are trying to do.  Can you clarify?

Are you converting the sensor data into a string?

 

Offline
Last seen: 9 years 10 months ago
Joined: 05/25/2014
Posts: 6

Thanks for your reply,

 I don't think you are doing DDS optimally, in how you are trying to mimic a sensor.  Instead, use an application to read the sensor, populate a DDS Type instance with the data, and publish it data-centrically:

struct mySensorType { 
    string<32> sensorId; //@key
    sequence<double, 8> payload;
};

You are totally right. But to test my network, I want to send certain payload size with certain rate from each sensor node. Of course, using string is not allowing that because it has fixed size. 

Actually, using string data writer was not in my plan. I started by using dynamic data (just like what you suggested) then the error (posted in main post) occurred. Thus, I used octet data type (bytes) to escape from the error but the same casting error appear (I couldn’t solve it). For this reason, I start thinking about using string datawriter.  

rip
rip's picture
Offline
Last seen: 20 hours 13 min ago
Joined: 04/06/2012
Posts: 324

Hi,

"DynamicData" is different from user defined types generated from IDL.  Are you talking DynamicData, or IDL Types?

Once you've populated the IDL defined type, are you trying to serialize that into a fixed-length byte stream?  Casting is absolutely not going to work.  The IDL-generated TypeSupport libraries do have serialize/deserialize methods, but they are not public API and we don't supply any information about how to use them in your own code. 

 

 

Offline
Last seen: 9 years 10 months ago
Joined: 05/25/2014
Posts: 6

Hi,

Actually, I built my code based on "RTI\ndds.5.0.0\example\CSHARP\Hello_dynamic" example. I used "dynamic data" terminology from there.

rip
rip's picture
Offline
Last seen: 20 hours 13 min ago
Joined: 04/06/2012
Posts: 324

Hi,

That example does use DynamicData objects, rather than defined types.

If you are not yet truly familiar with the DDS Type system, you probably want to stay away from the DynamicData objects for now.

I'd recommend moving into the Hello_idl directory and starting there, instead, because you can then define your types data-centrically, based on what you need to send.  Or, don't use one of the example directories at all.  Create a new directory and add an IDL file to that, that captures what kind of data you are sending.

struct SensorType { 
    string<24> sensorId; //@key 
    sequence<double, 64> payload;
};

That idl would allow you to send the name of the sensor in the payload (allowing subscribers to filter for it or against it), and allow you to send either a single reading (as a double) or a waveform (as a series of doubles).  You probably have additional information you might want to add, let me know what you have/what you might want there, and I'll extend the idl to suit.

What kind of sensors are these?

Also, I'm still not sure what you mean by this:

1# How I can send fixed payload size using data writer with certain publishing rate to mimic sensor behavior?

Questions:

You want a fixed payload size, does that include the size of the RTPS headers? (from an outside observer) or do you mean the RTPS sub-message payload block is always the same size?  (if so, replace 'sequence' in the example IDL with 'array').  Also, remember that applications are not expected to get a serialized octet sequence, the application just gets an object of SensorType with the sensorId and payload already filled in. 

At what rate are you trying to publish the data?  faster or slower than one system clock tick?  Is this for a pure simulation? can you use batching?