Coherent Group Example to Java crash

4 posts / 0 new
Last post
Offline
Last seen: 1 year 13 hours ago
Joined: 09/10/2019
Posts: 3
Coherent Group Example to Java crash

Hello,

 

we're trying to translate the C++/C# example from here

https://github.com/rticommunity/rticonnextdds-examples/blob/master/examples/connext_dds/group_coherent_presentation/

to Java, but run into an issue. When there is any datawriter in the coherent publisher, there will be a crash in nddscore.dll when calling publisher.end_coherent_changes()

we basically have a 1:1 translation of the c++ code to java

 

Thanks for any hints

 

ray

PK_RTI's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 07/01/2021
Posts: 19

Hello Ray,

Have you started with one of the existing, non-group coherent Java examples and modified it? Is there any way that you could post your code snippet for review? That would make assisting much easier.

Thanks,

PK

Offline
Last seen: 1 year 13 hours ago
Joined: 09/10/2019
Posts: 3

Hello and thanks for your response PK. We started with translating from the C++ code directly, skipping the non-group Java examples.

Here's the whole publisher file, the crash happens here

publisher.end_coherent_changes();

if the writers are created with participant.create_datawriter... instead of publisher.create_datawriter... , there's no crash. But I suspect that the coherent grouping takes into account only the datawriters inside the publisher not the participant's "implicit" publisher.

package de.fkie.GroupCoherentExample;

import ...
import static com.rti.dds.infrastructure.ReliabilityQosPolicyKind.RELIABLE_RELIABILITY_QOS;

/** 
* Simple example showing all Connext code in one place for readability.
*/
public class TemperaturePublisher extends Application implements AutoCloseable {
    private DomainParticipant participant = null; // Usually one per application
    public Publisher publisher= null;///
    private TemperatureDataWriter writer_temperature = null;
    private HeartRateDataWriter writer_heartRate = null;
    private AlarmDataWriter writer_alarm = null;
        //Additionally writing get_patient_heart_rate() and get_patient_temperature()
    public static int get_patient_heart_rate()
    {
        int[] heart_rates = new int[]{ 35, 56, 85, 110};
        int index = ThreadLocalRandom.current().nextInt() % 4;
        if(index < 0)
        {
            index = index +4;
        }
        return heart_rates[index];
    }

    public static float get_patient_temperature()
    {
        float[] temperatures = new float[]{ (float)95.0, (float)98.1, (float)99.2, (float)101.7};
        int index = ThreadLocalRandom.current().nextInt() % 4;
        if(index < 0)
        {
            index = index +4;
        }
        return temperatures[index];
    }
    

    // Usually one per application
    private void runApplication() {
        // Start communicating in a domain
        participant = Objects.requireNonNull(
            DomainParticipantFactory.get_instance().create_participant(
                getDomainId(),
                DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
                null, // listener
                StatusKind.STATUS_MASK_NONE));

        // A Publisher allows an application to create one or more DataWriters
        PublisherQos publisherQos = new PublisherQos();
        participant.get_default_publisher_qos(publisherQos);
        //Publisher publisher = Objects.requireNonNull(
        //participant.create_publisher_with_profile("NGVADataModel","StatePattern",null,StatusKind.STATUS_MASK_NONE));
        Publisher publisher = participant.create_publisher(publisherQos,null,StatusKind.STATUS_MASK_NONE);
        publisherQos.presentation.access_scope = PresentationQosPolicyAccessScopeKind.GROUP_PRESENTATION_QOS;
        publisherQos.presentation.coherent_access = true;
        publisherQos.presentation.ordered_access = true;
        publisher.set_qos(publisherQos);

        DataWriterQos dataWriterQos = new DataWriterQos();
        publisher.get_default_datawriter_qos(dataWriterQos);

        // Changes for additional HeartRate and Alarm
        // Register the datatype to use when creating the Topic
        String typeName_temperature= TemperatureTypeSupport.get_type_name();
        TemperatureTypeSupport.register_type(participant, typeName_temperature);
        // Register the datatype to use when creating the Topic
        String typeName_heartRate = HeartRateTypeSupport.get_type_name();
        HeartRateTypeSupport.register_type(participant, typeName_heartRate);
        // Register the datatype to use when creating the Topic
        String typeName_alarm = AlarmTypeSupport.get_type_name();
        AlarmTypeSupport.register_type(participant, typeName_alarm);

        // Create a Topic with a name and a datatype
        Topic topic_temperature = Objects.requireNonNull(
            participant.create_topic_with_profile("Temperature",
                    typeName_temperature,
                    "NGVADataModel",
                    "StatePattern",
                    null,
                    StatusKind.STATUS_MASK_NONE));
        // Create a Topic with a name and a datatype
        Topic topic_heartRate = Objects.requireNonNull(
                participant.create_topic_with_profile("HeartRate",
                        typeName_heartRate,
                        "NGVADataModel",
                        "StatePattern",
                        null,
                        StatusKind.STATUS_MASK_NONE));
        // Create a Topic with a name and a datatype
        Topic topic_alarm = Objects.requireNonNull(
                participant.create_topic_with_profile("Alarm",
                        typeName_alarm,
                        "NGVADataModel",
                        "StatePattern",
                        null,
                        StatusKind.STATUS_MASK_NONE));

        // This DataWriter writes data on "Example GroupCoherentExample_Temperature" Topic
        DataWriterQos pubQos = new DataWriterQos();
        publisher.get_default_datawriter_qos(pubQos);
        pubQos.reliability.kind = RELIABLE_RELIABILITY_QOS;
        pubQos.history.kind = HistoryQosPolicyKind.KEEP_ALL_HISTORY_QOS;        
        TemperatureDataWriter writer_temperature = (TemperatureDataWriter) Objects.requireNonNull(
            publisher.create_datawriter(topic_temperature, pubQos,
                    null,
                    StatusKind.STATUS_MASK_ALL));
	 
        // This DataWriter writes data on "Example GroupCoherentExample_Temperature" Topic
        HeartRateDataWriter writer_heartRate = (HeartRateDataWriter) Objects.requireNonNull(
                publisher.create_datawriter_with_profile(topic_heartRate,
                        "NGVADataModel",
                        "StatePattern",
                        null,
                        StatusKind.STATUS_MASK_ALL));

        // This DataWriter writes data on "Example GroupCoherentExample_Temperature" Topic
        AlarmDataWriter writer_alarm = (AlarmDataWriter) Objects.requireNonNull(
                publisher.create_datawriter_with_profile(topic_alarm,
                        "NGVADataModel",
                        "StatePattern",
                        null,
                        StatusKind.STATUS_MASK_ALL));

        // Create data sample for writing
        Temperature temperature_data = new Temperature();
        HeartRate   heartRate_data = new HeartRate();
        Alarm alarm_data = new Alarm();
        alarm_data.patient_id = 1;
        alarm_data.alarm_code = AlarmCode.PATIENT_OK;
        heartRate_data.patient_id = 1;
        heartRate_data.beats_per_minute = 65;
        temperature_data.patient_id = 1;
        temperature_data.temperature = 98;
        boolean bed = true;
        for (int samplesWritten = 0; !isShutdownRequested() && samplesWritten < getMaxSampleCount(); samplesWritten++) {

            // Modify the data to be written here
            //temperature_data.patient_id = samplesWritten;
            heartRate_data.beats_per_minute = get_patient_heart_rate();
            temperature_data.temperature = get_patient_temperature();
            if(heartRate_data.beats_per_minute >= 100
                 || heartRate_data.beats_per_minute <= 40
                 || temperature_data.temperature >= 100.0
                 || temperature_data.temperature <= 95.0)
            {
                System.out.println("Writing Coherent Set, count " + samplesWritten);
                publisher.begin_coherent_changes();
                writer_heartRate.write(heartRate_data,InstanceHandle_t.HANDLE_NIL);
                writer_temperature.write(temperature_data,InstanceHandle_t.HANDLE_NIL);
                alarm_data.alarm_code = AlarmCode.ABNORMAL_READING;
                writer_alarm.write(alarm_data,InstanceHandle_t.HANDLE_NIL);
                publisher.end_coherent_changes();
            }else{
                System.out.println("Writing Normal Samples, count " + samplesWritten);
                writer_heartRate.write(heartRate_data,InstanceHandle_t.HANDLE_NIL);
                writer_temperature.write(temperature_data,InstanceHandle_t.HANDLE_NIL);
            }
           try {
                final long sendPeriodMillis = 1000; // 1 second
                Thread.sleep(sendPeriodMillis);
            } catch (InterruptedException ix) {
                System.err.println("INTERRUPTED");
                break;
            }

        }

    }

    @Override
    public void close() {
    // Delete all entities (DataWriter, Topic, Publisher, DomainParticipant)
    if (participant != null) {
            participant.delete_contained_entities();
            DomainParticipantFactory.get_instance().delete_participant(participant);
        }
    }

    public static void main(String[] args) {
        // Create example and run: Uses try-with-resources,
        // publisherApplication.close() automatically called
        try (TemperaturePublisher publisherApplication = new TemperaturePublisher()) {
            publisherApplication.parseArguments(args);
            publisherApplication.addShutdownHook();
            publisherApplication.runApplication();
        }

        // Releases the memory used by the participant factory. Optional at application exit.
        DomainParticipantFactory.finalize_instance();
    }
}

Cheers,

 

ray

Offline
Last seen: 1 year 13 hours ago
Joined: 09/10/2019
Posts: 3

Hello,

after successfully running the non coherent group examples you mentioned we found a difference, which is likely the cause.

The writer uses the BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS policy - removing this makes the code not crash inside the dll anymore.

Cheers,

Ray