public void TestLookupInstance() { PublicationBuiltinTopicData data = default; SampleInfo info = new SampleInfo(); DomainParticipant otherParticipant = AssemblyInitializer.Factory.CreateParticipant(AssemblyInitializer.RTPS_DOMAIN); Assert.IsNotNull(otherParticipant); otherParticipant.BindRtpsUdpTransportConfig(); TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(otherParticipant, typeName); Assert.AreEqual(ReturnCode.Ok, result); var topic = otherParticipant.CreateTopic(TestContext.TestName, typeName); Assert.IsNotNull(topic); var publisher = otherParticipant.CreatePublisher(); Assert.IsNotNull(publisher); DataWriterQos dwQos = TestHelper.CreateNonDefaultDataWriterQos(); dwQos.Ownership.Kind = OwnershipQosPolicyKind.SharedOwnershipQos; DataWriter dataWriter = publisher.CreateDataWriter(topic, dwQos); Assert.IsNotNull(dataWriter); Thread.Sleep(500); ReturnCode ret = _dr.ReadNextSample(ref data, info); Assert.AreEqual(ReturnCode.Ok, ret); // Lookup for an existing instance var handle = _dr.LookupInstance(data); Assert.AreNotEqual(InstanceHandle.HandleNil, handle); ret = otherParticipant.DeleteContainedEntities(); Assert.AreEqual(ReturnCode.Ok, ret); TestHelper.TestNonDefaultPublicationData(data); ret = AssemblyInitializer.Factory.DeleteParticipant(otherParticipant); Assert.AreEqual(ReturnCode.Ok, ret); }
/// <summary> /// Creates a DomainParticipant, Topic, Publisher and DataWriter<HelloWorld>. /// </summary> public HelloWorldPublisher(int domainId) { // Start communicating in a domain, usually one participant per application // Load QoS profile from USER_QOS_PROFILES.xml file participant = DomainParticipantFactory.Instance.CreateParticipant(domainId); // A Topic has a name and a datatype. Topic <HelloWorld> topic = participant.CreateTopic <HelloWorld>( "Example InstanceStatisticsExample_HelloWorld"); // Create a Publisher Publisher publisher = participant.CreatePublisher(); // Create a DataWriter, loading QoS profile from USER_QOS_PROFILES.xml writer = publisher.CreateDataWriter(topic); }
/// <summary> /// Creates a DomainParticipant, Topic, Publisher and DataWriter. /// </summary> public HelloWorldPublisher( int domainId, string expectedPassword, string topicName) { // Save the expected password. We will only communicate with // subscriptions that send this password via discovery. this.expectedPassword = expectedPassword; // Configure the participant QoS to increase the user data max length DomainParticipantQos participantQos = DomainParticipantFactory.Instance.DefaultParticipantQos .WithResourceLimits(policy => policy.ParticipantUserDataMaxLength = 1024); // Create the participant participant = DomainParticipantFactory.Instance.CreateParticipant( domainId, qos: participantQos, preEnableAction: p => { // The preEnableAction is executed right before the participant // is enabled and communication starts. By looking up the // built-in discovery readers here we ensure that // that they will receive all the discovery information. participantReader = p.BuiltinSubscriber .LookupDataReader <ParticipantBuiltinTopicData>( Subscriber.ParticipantBuiltinTopicName); // The DataAvailable event is called when another participant // is discovered and before this participant has started // communicating with it participantReader.DataAvailable += OnNewParticipant; subscriptionReader = p.BuiltinSubscriber .LookupDataReader <SubscriptionBuiltinTopicData>( Subscriber.SubscriptionBuiltinTopicName); subscriptionReader.DataAvailable += OnNewSubscription; } ); // Create a topic, a publisher and a writer Topic <HelloWorld> topic = participant.CreateTopic <HelloWorld>(topicName); Publisher publisher = participant.CreatePublisher(); writer = publisher.CreateDataWriter(topic); }
public void TestInitialize() { _participant = AssemblyInitializer.Factory.CreateParticipant(AssemblyInitializer.RTPS_DOMAIN); Assert.IsNotNull(_participant); _participant.BindRtpsUdpTransportConfig(); TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(_participant, typeName); Assert.AreEqual(ReturnCode.Ok, result); _topic = _participant.CreateTopic(TestContext.TestName, typeName); Assert.IsNotNull(_topic); Assert.IsNull(_topic.GetListener()); Assert.AreEqual(TestContext.TestName, _topic.Name); Assert.AreEqual(typeName, _topic.TypeName); SubscriberQos sQos = new SubscriberQos(); sQos.EntityFactory.AutoenableCreatedEntities = false; sQos.Presentation.OrderedAccess = true; sQos.Presentation.CoherentAccess = true; sQos.Presentation.AccessScope = PresentationQosPolicyAccessScopeKind.InstancePresentationQos; _subscriber = _participant.CreateSubscriber(sQos); Assert.IsNotNull(_subscriber); PublisherQos pQos = new PublisherQos(); pQos.EntityFactory.AutoenableCreatedEntities = false; pQos.Presentation.OrderedAccess = true; pQos.Presentation.CoherentAccess = true; pQos.Presentation.AccessScope = PresentationQosPolicyAccessScopeKind.InstancePresentationQos; _publisher = _participant.CreatePublisher(pQos); Assert.IsNotNull(_publisher); _listener = new MyDataWriterListener(); _writer = _publisher.CreateDataWriter(_topic, _listener); Assert.IsNotNull(_writer); _dataWriter = new TestStructDataWriter(_writer); DataReaderQos qos = new DataReaderQos(); qos.Reliability.Kind = ReliabilityQosPolicyKind.ReliableReliabilityQos; _reader = _subscriber.CreateDataReader(_topic, qos); Assert.IsNotNull(_reader); }
private static void TestOnSubscriptionLostDisconnected() { DomainParticipantFactory dpf = ParticipantService.Instance.GetDomainParticipantFactory(); DomainParticipant participant = dpf.CreateParticipant(INFOREPO_DOMAIN); if (participant == null) { throw new ApplicationException("Failed to create the participant."); } BindTcpTransportConfig(participant); Publisher publisher = participant.CreatePublisher(); if (publisher == null) { throw new ApplicationException("Failed to create the publisher."); } TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(participant, typeName); if (result != ReturnCode.Ok) { throw new ApplicationException("Failed to register the type." + result.ToString()); } Topic topic = participant.CreateTopic("TestOnSubscriptionLostDisconnected", typeName); if (topic == null) { throw new ApplicationException("Failed to create the topic."); } DataWriter writer = publisher.CreateDataWriter(topic); if (writer == null) { throw new ApplicationException("Failed to create the writer."); } while (true) { System.Threading.Thread.Sleep(100); } }
public void Run(int domainId, int sampleCount) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create a Topic named // "ChocolateTemperature" with type Temperature Topic <Temperature> topic = participant.CreateTopic <Temperature>("ChocolateTemperature"); // Exercise #2.1: Add new Topic // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter writes data on Topic "ChocolateTemperature" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <Temperature> writer = publisher.CreateDataWriter(topic); // Create a DynamicData sample for writing var sample = new Temperature(); // Exercise #2.2: Add new DataWriter and data sample var rand = new Random(); for (int count = 0; count < sampleCount && !shutdownRequested; count++) { // Modify the data to be written here sample.sensor_id = sensorId; sample.degrees = rand.Next(30, 33); // Random number between 30 and 32 Console.WriteLine($"Writing ChocolateTemperature, count {count}"); writer.Write(sample); // Exercise #2.3 Write data with new ChocolateLotState DataWriter // Exercise #1.1: Change this to sleep 100 ms in between writing temperatures Thread.Sleep(4000); } }
/// <summary> /// Main function, receiving structured command-line arguments /// via the System.Console.DragonFruit package. /// For example: dotnet run -- --domain-id 54 --sample-count 5 /// </summary> /// <param name="domainId">The domain ID to create the DomainParticipant</param> /// <param name="sampleCount">The number of data samples to publish</param> public static void Main(int domainId = 0, int sampleCount = int.MaxValue) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml // // A participant needs to be Disposed to release middleware resources. // The 'using' keyword indicates that it will be Disposed when this // scope ends. using DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create dynamically-typed // Topic named "HelloWorld Topic" with the type definition of // "HelloWorld" in hello_world.xml. To get the type we use a QosProvider var provider = new QosProvider("../hello_world.xml"); Topic <DynamicData> topic = participant.CreateTopic( "Example HelloWorld", provider.GetType("HelloWorld")); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter will write data on Topic "HelloWorld Topic" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <DynamicData> writer = publisher.CreateDataWriter(topic); var sample = writer.CreateData(); for (int count = 0; count < sampleCount; count++) { // Modify the data to be written here sample.SetValue("msg", $"Hello {count}"); Console.WriteLine($"Writing {sample}"); writer.Write(sample); Thread.Sleep(1000); } }
public void TestInitialize() { _participant = AssemblyInitializer.Factory.CreateParticipant(AssemblyInitializer.RTPS_DOMAIN); Assert.IsNotNull(_participant); _participant.BindRtpsUdpTransportConfig(); TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(_participant, typeName); Assert.AreEqual(ReturnCode.Ok, result); _topic = _participant.CreateTopic(TestContext.TestName, typeName); Assert.IsNotNull(_topic); Assert.IsNull(_topic.Listener); Assert.AreEqual(TestContext.TestName, _topic.Name); Assert.AreEqual(typeName, _topic.TypeName); _publisher = _participant.CreatePublisher(); Assert.IsNotNull(_publisher); }
/// <summary> /// Creates a DomainParticipant, Topic, Publisher and DataWriter<HelloWorld>. /// </summary> public HelloWorldPublisher(int domainId) { // Enable network capture. // This must be called before any other network capture function, and // before creating any participant for which we want to capture traffic. NetworkCapture.Enable(); // Start communicating in a domain, usually one participant per application // Load QoS profile from USER_QOS_PROFILES.xml file participant = DomainParticipantFactory.Instance.CreateParticipant(domainId); // A Topic has a name and a datatype. Topic <HelloWorld> topic = participant.CreateTopic <HelloWorld>( "Network capture shared memory example"); // Create a Publisher Publisher publisher = participant.CreatePublisher(); // Create a DataWriter, loading QoS profile from USER_QOS_PROFILES.xml, and writer = publisher.CreateDataWriter(topic); }
private void InitializeDDS() { //string id = usuario.Id; string id = "0"; int.TryParse(id, out domainId); // Create the DomainFactory factory = DomainParticipantFactory.GetInstance(Bootstrap.CreateInstance()); // Create the DomainParticipant with reference to the configuration file with the domain ID dp = factory.CreateParticipant(domainId); // Console.WriteLine("Domain ID = {0} has been created", domainId); // Implicitly create TypeSupport and register type: tp = dp.CreateTopic <ChatMessage>("Greetings Topic"); // Create the subscriber sub = dp.CreateSubscriber(); // Create a Listener for the publishing data ls = new MyListener(backgroundWorker1, backgroundWorker2, backgroundWorker3, backgroundWorker4, backgroundWorker5, backgroundWorker6); ls2 = new MyListener2(); // Create the DataReader using the topic, politics of QoS for DataReader and implemented listener dr = sub.CreateDataReader <ChatMessage>(tp, sub.GetDefaultDataReaderQos(), ls, null); // Create the publisher pub = dp.CreatePublisher(); // Create the DataWriter using the topic specified //dw = pub.CreateDataWriter(tp); dw = pub.CreateDataWriter <ChatMessage>(tp, pub.GetDefaultDataWriterQos(), ls2, null); }
private void RunExample( int domainId = 0, uint lotsToProcess = 10) { // Loads the QoS from the qos_profiles.xml file. var qosProvider = new QosProvider("./qos_profiles.xml"); // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // Load DomainParticipant QoS profile var participantQos = qosProvider.GetDomainParticipantQos( "ChocolateFactoryLibrary::MonitoringControlApplication"); DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId, participantQos); // A Topic has a name and a datatype. Create a Topic with type // ChocolateLotState. Topic name is a constant defined in the IDL file. Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic <ChocolateLotState>("ChocolateLotState"); // Add a Topic for Temperature to this application Topic <Temperature> temperatureTopic = participant.CreateTopic <Temperature>("ChocolateTemperature"); ContentFilteredTopic <Temperature> filteredTemperatureTopic = participant.CreateContentFilteredTopic( name: "FilteredTemperature", relatedTopic: temperatureTopic, filter: new Filter( expression: "degrees > %0 or degrees < %1", parameters: new string[] { "32", "30" })); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter writes data on Topic "ChocolateLotState" var writerQos = qosProvider.GetDataWriterQos( "ChocolateFactoryLibrary::ChocolateLotStateProfile"); DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter(lotStateTopic, writerQos); // A Subscriber allows an application to create one or more DataReaders // Subscriber QoS is configured in USER_QOS_PROFILES.xml Subscriber subscriber = participant.CreateSubscriber(); // Create DataReader of Topic "ChocolateLotState". // DataReader QoS is configured in USER_QOS_PROFILES.xml var readerQos = qosProvider.GetDataReaderQos( "ChocolateFactoryLibrary::ChocolateLotStateProfile"); DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader(lotStateTopic, readerQos); // Add a DataReader for Temperature to this application readerQos = qosProvider.GetDataReaderQos( "ChocolateFactoryLibrary::ChocolateTemperatureProfile"); DataReader <Temperature> temperatureReader = subscriber.CreateDataReader(filteredTemperatureTopic, readerQos); // Obtain the DataReader's Status Condition StatusCondition temperatureStatusCondition = temperatureReader.StatusCondition; temperatureStatusCondition.EnabledStatuses = StatusMask.DataAvailable; // Associate a handler with the status condition. This will run when the // condition is triggered, in the context of the dispatch call (see below) temperatureStatusCondition.Triggered += _ => MonitorTemperature(temperatureReader); // Do the same with the lotStateReader's StatusCondition StatusCondition lotStateStatusCondition = lotStateReader.StatusCondition; lotStateStatusCondition.EnabledStatuses = StatusMask.DataAvailable; int lotsProcessed = 0; lotStateStatusCondition.Triggered += _ => lotsProcessed += MonitorLotState(lotStateReader); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(lotStateStatusCondition); // Add the new DataReader's StatusCondition to the Waitset waitset.AttachCondition(temperatureStatusCondition); // Start publishing in a separate thread var startLotTask = Task.Run(() => PublishStartLot(lotStateWriter, lotsToProcess)); while (!shutdownRequested && lotsProcessed < lotsToProcess) { waitset.Dispatch(Duration.FromSeconds(4)); } startLotTask.Wait(); }
// Exercise #4.4: Add monitor_temperature function private void RunExample( int domainId = 0, uint lotsToProcess = 10) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create a Topic named // "ChocolateLotState" with type ChocolateLotState. Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic <ChocolateLotState>( "ChocolateLotState"); // Exercise #4.1: Add a Topic for Temperature to this application // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter writes data on Topic "ChocolateLotState" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter(lotStateTopic); // A Subscriber allows an application to create one or more DataReaders // Subscriber QoS is configured in USER_QOS_PROFILES.xml Subscriber subscriber = participant.CreateSubscriber(); // Create DataReader of Topic "ChocolateLotState". // DataReader QoS is configured in USER_QOS_PROFILES.xml DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader(lotStateTopic); // Exercise #4.2: Add a DataReader for Temperature to this application // Obtain the DataReader's Status Condition StatusCondition lotStateStatusCondition = lotStateReader.StatusCondition; // Enable the 'data available' status. lotStateStatusCondition.EnabledStatuses = StatusMask.DataAvailable; int lotsProcessed = 0; lotStateStatusCondition.Triggered += _ => lotsProcessed += MonitorLotState(lotStateReader); // Create a WaitSet and attach the StatusCondition WaitSet waitset = new WaitSet(); waitset.AttachCondition(lotStateStatusCondition); // Exercise #4.3: Add the new DataReader's StatusCondition to the Waitset // Start publishing in a separate thread var startLotTask = Task.Run(() => PublishStartLot(lotStateWriter, lotsToProcess)); while (!shutdownRequested && lotsProcessed < lotsToProcess) { waitset.Dispatch(Duration.FromSeconds(4)); } startLotTask.Wait(); }
public void TestNotifyDataReaders() { // Initialize entities TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(_participant, typeName); Assert.AreEqual(ReturnCode.Ok, result); Topic topic = _participant.CreateTopic(nameof(TestNotifyDataReaders), typeName); Assert.IsNotNull(topic); Assert.IsNull(topic.GetListener()); Assert.AreEqual(nameof(TestNotifyDataReaders), topic.Name); Assert.AreEqual(typeName, topic.TypeName); Publisher publisher = _participant.CreatePublisher(); Assert.IsNotNull(publisher); DataWriter writer = publisher.CreateDataWriter(topic); Assert.IsNotNull(writer); TestStructDataWriter dataWriter = new TestStructDataWriter(writer); int subscriberReceived = 0; int readerReceived = 0; // Create the Subscriber and the DataReader with the corresponding listeners MySubscriberListener subListener = new MySubscriberListener(); subListener.DataOnReaders += (sub) => { subscriberReceived++; if (subscriberReceived % 2 == 0) { sub.NotifyDataReaders(); } }; Subscriber subscriber = _participant.CreateSubscriber(subListener); Assert.IsNotNull(subscriber); MyDataReaderListener readListener = new MyDataReaderListener(); readListener.DataAvailable += (read) => { readerReceived++; }; DataReader reader = subscriber.CreateDataReader(topic, readListener); Assert.IsNotNull(reader); System.Threading.Thread.Sleep(100); // Publish instances for (int i = 0; i < 10; i++) { dataWriter.Write(new TestStruct { Id = i, ShortType = (short)i }); System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(100); // Check the received instances Assert.AreEqual(10, subscriberReceived); Assert.AreEqual(5, readerReceived); }
/// <summary> /// Runs the publisher example. /// </summary> public static void RunPublisher( int domainId, int sampleCount, CancellationToken cancellationToken, bool useXmlQos = false) { // Start communicating in a domain, usually one participant per application // Load default QoS profile from USER_QOS_PROFILES.xml file using DomainParticipant participant = DomainParticipantFactory.Instance.CreateParticipant(domainId); // A Topic has a name and a datatype. Topic <HelloWorld> topic = participant.CreateTopic <HelloWorld>("Example async"); // Create a Publisher Publisher publisher = participant.CreatePublisher(); DataWriterQos writerQos; if (useXmlQos) { // Retrieve the DataWriterQos from the default profile in // USER_QOS_PROFILES.xml writerQos = QosProvider.Default.GetDataWriterQos(); } else { // Configure the DataWriterQos in code, to the same effect as // the XML file. writerQos = publisher.DefaultDataWriterQos .WithReliability(policy => { policy.Kind = ReliabilityKind.Reliable; policy.MaxBlockingTime = Duration.FromSeconds(60); }) .WithHistory(policy => { policy.Kind = HistoryKind.KeepLast; policy.Depth = 12; }) .WithProtocol(policy => { policy.RtpsReliableWriter.MinSendWindowSize = 50; policy.RtpsReliableWriter.MaxSendWindowSize = 50; }) .WithPublishMode(policy => { policy.Kind = PublishModeKind.Asynchronous; // The built-in fixed-rate flow controller publishes // all written samples once per second policy.FlowControllerName = PublishMode.FixedRateFlowControllerName; }); } DataWriter <HelloWorld> writer = publisher.CreateDataWriter(topic, writerQos); var sample = new HelloWorld(); for (int count = 0; count < sampleCount && !cancellationToken.IsCancellationRequested; count++) { // Modify the data to be sent here sample.x = count; Console.WriteLine($"Writing x={sample.x}"); // With asynchronous publish mode, the Write() puts the sample // in the queue but doesn't send it until the flow controller // indicates so. writer.Write(sample); Thread.Sleep(100); } // You can wait until all written samples have been actually published // (note that this doesn't ensure that they have actually been received // if the sample required retransmission) writer.WaitForAsynchronousPublishing(Duration.FromSeconds(10)); }
private void RunExample(int domainId, string sensorId) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // Uses TemperingApplication QoS profile to set participant name. var qosProvider = new QosProvider("./qos_profiles.xml"); var participantQos = qosProvider.GetDomainParticipantQos( "ChocolateFactoryLibrary::TemperingApplication"); DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId, participantQos); // Create the topics Topic <Temperature> temperatureTopic = participant.CreateTopic <Temperature>("ChocolateTemperature"); Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic <ChocolateLotState>("ChocolateLotState"); // Exercise #1.1: Create a Content-Filtered Topic that filters out // chocolate lot state unless the next_station = TEMPERING_CONTROLLER // A Publisher allows an application to create one or more DataWriters // Create Publisher with default QoS. Publisher publisher = participant.CreatePublisher(); // Create DataWriter of Topic "ChocolateTemperature" // using ChocolateTemperatureProfile QoS profile for Streaming Data DataWriter <Temperature> temperatureWriter = publisher.CreateDataWriter( temperatureTopic, qos: qosProvider.GetDataWriterQos("ChocolateFactoryLibrary::ChocolateTemperatureProfile")); // Create DataWriter of Topic "ChocolateLotState" // using ChocolateLotStateProfile QoS profile for State Data DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter( lotStateTopic, qos: qosProvider.GetDataWriterQos("ChocolateFactoryLibrary::ChocolateLotStateProfile")); // A Subscriber allows an application to create one or more DataReaders Subscriber subscriber = participant.CreateSubscriber(); // Create DataReader of Topic "ChocolateLotState". // using ChocolateLotStateProfile QoS profile for State Data // Exercise #1.2: Change the DataReader's Topic to use a // Content-Filtered Topic DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader( lotStateTopic, qos: qosProvider.GetDataReaderQos("ChocolateFactoryLibrary::ChocolateLotStateProfile"), preEnableAction: reader => reader.RequestedIncompatibleQos += OnRequestedIncompatibleQos); // Obtain the DataReader's Status Condition StatusCondition statusCondition = lotStateReader.StatusCondition; // Enable the 'data available' status. statusCondition.EnabledStatuses = StatusMask.DataAvailable; // Associate an event handler with the status condition. // This will run when the condition is triggered, in the context of // the dispatch call (see below) statusCondition.Triggered += _ => ProcessLot(lotStateReader, lotStateWriter); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(statusCondition); // Create a thread to periodically publish the temperature Console.WriteLine($"ChocolateTemperature Sensor with ID: {sensorId} starting"); var temperatureTask = Task.Run( () => PublishTemperature(temperatureWriter, sensorId)); while (!shutdownRequested) { // Wait for ChocolateLotState Console.WriteLine("Waiting for lot"); waitset.Dispatch(Duration.FromSeconds(10)); } temperatureTask.Wait(); }
private void RunExample( int domainId = 0, uint lotsToProcess = 10) { // Exercise #1.1: Add QoS provider // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // Exercise #1.2: Load DomainParticipant QoS profile DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create a Topic named // "ChocolateLotState" with type ChocolateLotState. Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic <ChocolateLotState>( CHOCOLATE_LOT_STATE_TOPIC.Value); // Add a Topic for Temperature to this application Topic <Temperature> temperatureTopic = participant.CreateTopic <Temperature>( CHOCOLATE_TEMPERATURE_TOPIC.Value); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter writes data on Topic "ChocolateLotState" // Exercise #4.1: Load ChocolateLotState DataWriter QoS profile after // debugging incompatible QoS DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter(lotStateTopic); // A Subscriber allows an application to create one or more DataReaders // Subscriber QoS is configured in USER_QOS_PROFILES.xml Subscriber subscriber = participant.CreateSubscriber(); // Create DataReader of Topic "ChocolateLotState". // Exercise #1.3: Update the lotStateReader and temperatureReader // to use correct QoS DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader(lotStateTopic); // Add a DataReader for Temperature to this application DataReader <Temperature> temperatureReader = subscriber.CreateDataReader(temperatureTopic); // Obtain the DataReader's Status Condition StatusCondition temperatureStatusCondition = temperatureReader.StatusCondition; temperatureStatusCondition.EnabledStatuses = StatusMask.DataAvailable; // Associate a handler with the status condition. This will run when the // condition is triggered, in the context of the dispatch call (see below) temperatureStatusCondition.Triggered += _ => MonitorTemperature(temperatureReader); // Do the same with the lotStateReader's StatusCondition StatusCondition lotStateStatusCondition = lotStateReader.StatusCondition; lotStateStatusCondition.EnabledStatuses = StatusMask.DataAvailable; int lotsProcessed = 0; lotStateStatusCondition.Triggered += _ => lotsProcessed += MonitorLotState(lotStateReader); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(lotStateStatusCondition); // Add the new DataReader's StatusCondition to the Waitset waitset.AttachCondition(temperatureStatusCondition); // Start publishing in a separate thread var startLotTask = Task.Run(() => PublishStartLot(lotStateWriter, lotsToProcess)); while (!shutdownRequested && lotsProcessed < lotsToProcess) { waitset.Dispatch(Duration.FromSeconds(4)); } startLotTask.Wait(); }
public void TestGetKeyValue() { // Call GetKeyValue with HandleNil PublicationBuiltinTopicData data = default; SampleInfo info = new SampleInfo(); ReturnCode ret = _dr.GetKeyValue(ref data, InstanceHandle.HandleNil); Assert.AreEqual(ReturnCode.BadParameter, ret); DomainParticipant otherParticipant = AssemblyInitializer.Factory.CreateParticipant(AssemblyInitializer.RTPS_DOMAIN); Assert.IsNotNull(otherParticipant); otherParticipant.BindRtpsUdpTransportConfig(); Assert.IsTrue(_participant.WaitForParticipants(1, 20_000)); TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(otherParticipant, typeName); Assert.AreEqual(ReturnCode.Ok, result); var topic = otherParticipant.CreateTopic(TestContext.TestName, typeName); Assert.IsNotNull(topic); var publisher = otherParticipant.CreatePublisher(); Assert.IsNotNull(publisher); DataWriterQos dwQos = TestHelper.CreateNonDefaultDataWriterQos(); dwQos.Ownership.Kind = OwnershipQosPolicyKind.SharedOwnershipQos; DataWriter dataWriter = publisher.CreateDataWriter(topic, dwQos); Assert.IsNotNull(dataWriter); int count = 200; ret = ReturnCode.NoData; while (ret != ReturnCode.Ok && count > 0) { Thread.Sleep(100); // Get an existing instance ret = _dr.ReadNextSample(ref data, info); count--; } Assert.AreEqual(ReturnCode.Ok, ret); TestHelper.TestNonDefaultPublicationData(data); PublicationBuiltinTopicData aux = default; ret = _dr.GetKeyValue(ref aux, info.InstanceHandle); Assert.AreEqual(ReturnCode.Ok, ret); for (int i = 0; i < 16; i++) { Assert.AreEqual(data.Key.Value[i], aux.Key.Value[i]); } ret = otherParticipant.DeleteContainedEntities(); Assert.AreEqual(ReturnCode.Ok, ret); ret = AssemblyInitializer.Factory.DeleteParticipant(otherParticipant); Assert.AreEqual(ReturnCode.Ok, ret); }
public OpenDDSharpService() { _config = ServiceLocator.Current.GetInstance <IConfigurationService>(); _disc = new RtpsDiscovery(RTPS_DISCOVERY) { ResendPeriod = new TimeValue { Seconds = 1 }, SedpMulticast = true }; ParticipantService.Instance.AddDiscovery(_disc); ParticipantService.Instance.DefaultDiscovery = RTPS_DISCOVERY; long ticks = DateTime.Now.Ticks; string configName = "openddsharp_rtps_interop_" + ticks.ToString();; string instName = "internal_openddsharp_rtps_transport_" + ticks.ToString();; _tConfig = TransportRegistry.Instance.CreateConfig(configName); _inst = TransportRegistry.Instance.CreateInst(instName, "rtps_udp"); _rui = new RtpsUdpInst(_inst); _tConfig.Insert(_inst); TransportRegistry.Instance.GlobalConfig = _tConfig; ParticipantService.Instance.SetRepoDomain(0, RTPS_DISCOVERY); _domainFactory = ParticipantService.Instance.GetDomainParticipantFactory("-DCPSDebugLevel", "10", "-ORBLogFile", "LogFile.log", "-ORBDebugLevel", "10"); _participant = _domainFactory.CreateParticipant(0); if (_participant == null) { throw new Exception("Could not create the participant"); } ShapeTypeTypeSupport support = new ShapeTypeTypeSupport(); ReturnCode result = support.RegisterType(_participant, TYPE_NAME); if (result != ReturnCode.Ok) { throw new Exception("Could not register type: " + result.ToString()); } _squareTopic = _participant.CreateTopic(SQUARE_TOPIC_NAME, TYPE_NAME); if (_squareTopic == null) { throw new Exception("Could not create square topic"); } _circleTopic = _participant.CreateTopic(CIRCLE_TOPIC_NAME, TYPE_NAME); if (_circleTopic == null) { throw new Exception("Could not create circle topic"); } _triangleTopic = _participant.CreateTopic(TRIANGLE_TOPIC_NAME, TYPE_NAME); if (_triangleTopic == null) { throw new Exception("Could not create triangle topic"); } _publisher = _participant.CreatePublisher(); if (_publisher == null) { throw new Exception("Could not create publisher"); } _subscriber = _participant.CreateSubscriber(); if (_subscriber == null) { throw new Exception("Could not create subscriber"); } _shapeWaitSets = new List <ShapeWaitSet>(); _shapeDynamics = new List <ShapeDynamic>(); _cfCircleCount = 0; _cfSquareCount = 0; _cfTriangleCount = 0; }
private static void TestPublisher(DomainParticipant participant) { Console.WriteLine("Starting applicattion as Publisher..."); Publisher publisher = participant.CreatePublisher(); if (publisher == null) { throw new ApplicationException("Publisher could not be created."); } Topic topic = CreateTestTopic(participant); DataWriterQos qos = new DataWriterQos(); qos.Reliability.Kind = ReliabilityQosPolicyKind.ReliableReliabilityQos; DataWriter dw = publisher.CreateDataWriter(topic, qos); if (dw == null) { throw new ApplicationException("DataWriter could not be created."); } TestStructDataWriter dataWriter = new TestStructDataWriter(dw); Console.WriteLine("Waiting for the subscriber..."); bool wait = WaitForSubscriptions(dw, 1, 60000); if (wait) { Console.WriteLine("Subscription found. Sending test data with default values..."); TestStruct data = new TestStruct(); dataWriter.Write(data); ReturnCode ret = dataWriter.WaitForAcknowledgments(new Duration { Seconds = 60, NanoSeconds = 0, }); if (ret == ReturnCode.Ok) { Console.WriteLine("Data sent and acknowledged."); } else { Console.WriteLine("No acknowledge received: " + ret.ToString()); return; } Console.WriteLine("Subscription found. Sending test data with custom values..."); data = new TestStruct { ShortField = -1, LongField = -2, LongLongField = -3, UnsignedShortField = 1, UnsignedLongField = 2, UnsignedLongLongField = 3, BooleanField = true, CharField = 'C', WCharField = 'W', FloatField = 42.42f, DoubleField = 0.42, //LongDoubleField = 0.4242m, OctetField = 0x42, UnboundedStringField = "Unbounded string field.", UnboundedWStringField = "Unbounded WString field.", BoundedStringField = "Bounded string field.", BoundedWStringField = "Bounded WString field.", BoundedBooleanSequenceField = { true, true, false }, UnboundedBooleanSequenceField = { true, true, false, true, true, false }, BoundedCharSequenceField = { '1', '2', '3', '4', '5' }, UnboundedCharSequenceField = { '1', '2', '3', '4', '5', '6' }, BoundedWCharSequenceField = { '1', '2', '3', '4', '5' }, UnboundedWCharSequenceField = { '1', '2', '3', '4', '5', '6' }, BoundedOctetSequenceField = { 0x42, 0x69 }, UnboundedOctetSequenceField = { 0x42, 0x69, 0x42, 0x69, 0x42, 0x69 }, BoundedShortSequenceField = { 1, 2, 3, 4, 5 }, UnboundedShortSequenceField = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }, BoundedUShortSequenceField = { 1, 2, 3, 4, 5 }, UnboundedUShortSequenceField = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }, BoundedLongSequenceField = { 1, 2, 3, 4, 5 }, UnboundedLongSequenceField = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }, BoundedULongSequenceField = { 1, 2, 3, 4, 5 }, UnboundedULongSequenceField = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }, BoundedLongLongSequenceField = { 1, 2, 3, 4, 5 }, UnboundedLongLongSequenceField = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }, BoundedULongLongSequenceField = { 1, 2, 3, 4, 5 }, UnboundedULongLongSequenceField = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }, BoundedFloatSequenceField = { 0.42f, 42.42f, 1f, 2f, 3f }, UnboundedFloatSequenceField = { 0.42f, 42.42f, 1f, 2f, 3f, 0.42f, 42.42f, 1f, 2f, 3f }, BoundedDoubleSequenceField = { 0.42, 42.42, 1, 2, 3 }, UnboundedDoubleSequenceField = { 0.42, 42.42, 1, 2, 3, 0.42, 42.42, 1, 2, 3 }, BoundedStringSequenceField = { "This", "is", "the", "end." }, BoundedWStringSequenceField = { "This", "is", "the", "end." }, UnboundedStringSequenceField = { "This", "is", "the", "end.", "This", "is", "the", "end." }, UnboundedWStringSequenceField = { "This", "is", "the", "end.", "This", "is", "the", "end." }, NestedStructField = { Id = 1, Message = "This is the end." }, BoundedStructSequenceField = { new NestedStruct { Id = 1, Message = "This is the end." }, new NestedStruct { Id = 2, Message = "my only friend, the end." } }, UnboundedStructSequenceField = { new NestedStruct { Id = 1, Message = "This is the end." }, new NestedStruct{ Id = 2, Message = "my only friend, the end." } }, TestEnumField = TestEnum.ENUM12, BoundedEnumSequenceField = { TestEnum.ENUM1, TestEnum.ENUM2, TestEnum.ENUM3, TestEnum.ENUM4, TestEnum.ENUM5 }, UnboundedEnumSequenceField = { TestEnum.ENUM1, TestEnum.ENUM2, TestEnum.ENUM3, TestEnum.ENUM4, TestEnum.ENUM5, TestEnum.ENUM6, TestEnum.ENUM7, TestEnum.ENUM8, TestEnum.ENUM9, TestEnum.ENUM10, TestEnum.ENUM11, TestEnum.ENUM12 }, ShortArrayField = new short[] { 1, -2, 3, -4, 5 }, UnsignedShortArrayField = new ushort[] { 1, 2, 3, 4, 5 }, LongArrayField = new int[] { 1, -2, 3, -4, 5 }, UnsignedLongArrayField = new uint[] { 1, 2, 3, 4, 5 }, LongLongArrayField = new long[] { 1, -2, 3, -4, 5 }, UnsignedLongLongArrayField = new ulong[] { 1, 2, 3, 4, 5 }, CharArrayField = new char[] { 'A', 'B', 'C', 'D', 'E' }, WCharArrayField = new char[] { 'A', 'B', 'C', 'D', 'E' }, BooleanArrayField = new bool[] { true, true, false, true, true }, OctetArrayField = new byte[] { 0x42, 0x42, 0x69, 0x42, 0x42 }, FloatArrayField = new float[] { 0.42f, 0.4242f, 1f, 2f, 3f }, DoubleArrayField = new double[] { 0.42, 0.4242, 1, 2, 3 }, StringArrayField = new string[] { "This", "is", "the", "end", "my only friend, the end." }, WStringArrayField = new string[] { "This", "is", "the", "end", "my only friend, the end." }, EnumArrayField = new TestEnum[] { TestEnum.ENUM1, TestEnum.ENUM2, TestEnum.ENUM3, TestEnum.ENUM4, TestEnum.ENUM5 }, StructArrayField = new NestedStruct[] { new NestedStruct { Id = 1, Message = "This is the end." }, new NestedStruct { Id = 2, Message = "This is the end." }, new NestedStruct { Id = 3, Message = "This is the end." }, new NestedStruct { Id = 4, Message = "This is the end." }, new NestedStruct { Id = 5, Message = "This is the end." }, }, ShortMultiArrayField = new short[, , ] { { { -01, -02 }, { -03, -04 }, { -05, -06 }, { -07, -08 }, }, { { -09, -10 }, { -11, -12 }, { -13, -14 }, { -15, -16 }, }, { { -17, -18 }, { -19, -20 }, { -21, -22 }, { -23, -24 }, } }, UnsignedShortMultiArrayField = new ushort[, , ] { { { 01, 02 }, { 03, 04 }, { 05, 06 }, { 07, 08 }, }, { { 09, 10 }, { 11, 12 }, { 13, 14 }, { 15, 16 }, }, { { 17, 18 }, { 19, 20 }, { 21, 22 }, { 23, 24 }, } }, LongMultiArrayField = new[, , ] { { { -01, 02 }, { -03, 04 }, { -05, 06 }, { -07, 08 }, }, { { -09, 10 }, { -11, 12 }, { -13, 14 }, { -15, 16 }, }, { { -17, 18 }, { -19, 20 }, { -21, 22 }, { -23, 24 }, } }, UnsignedLongMultiArrayField = new[, , ] { { { 25U, 26U }, { 27U, 28U }, { 29U, 30U }, { 31U, 32U }, }, { { 33U, 34U }, { 35U, 36U }, { 37U, 38U }, { 39U, 40U }, }, { { 41U, 42U }, { 43U, 44U }, { 45U, 46U }, { 47U, 48U }, } }, LongLongMultiArrayField = new[, , ] { { { -25L, -26L }, { -27L, -28L }, { -29L, -30L }, { -31L, -32L }, }, { { -33L, -34L }, { -35L, -36L }, { -37L, -38L }, { -39L, -40L }, }, { { -41L, -42L }, { -43L, -44L }, { -45L, -46L }, { -47L, -48L }, } }, UnsignedLongLongMultiArrayField = new[, , ] { { { 49UL, 50UL }, { 51UL, 52UL }, { 53UL, 54UL }, { 55UL, 56UL }, }, { { 57UL, 58UL }, { 59UL, 60UL }, { 61UL, 62UL }, { 63UL, 64UL }, }, { { 65UL, 66UL }, { 67UL, 68UL }, { 69UL, 70UL }, { 71UL, 72UL }, } }, FloatMultiArrayField = new[, , ] { { { 01.01f, 02.02f }, { 03.03f, 04.04f }, { 05.05f, 06.06f }, { 07.07f, 08.08f } }, { { 09.09f, 10.10f }, { 11.11f, 12.12f }, { 13.13f, 14.14f }, { 15.15f, 16.16f }, }, { { 17.17f, 18.18f }, { 19.19f, 20.20f }, { 21.21f, 22.22f }, { 23.23f, 24.24f }, } }, DoubleMultiArrayField = new[, , ] { { { 01.01, 02.02 }, { 03.03, 04.04 }, { 05.05, 06.06 }, { 07.07, 08.08 }, }, { { 09.09, 10.10 }, { 11.11, 12.12 }, { 13.13, 14.14 }, { 15.15, 16.16 }, }, { { 17.17, 18.18 }, { 19.19, 20.20 }, { 21.21, 22.22 }, { 23.23, 24.24 }, } }, BooleanMultiArrayField = new[, , ] { { { true, false }, { true, false }, { true, false }, { true, false }, }, { { true, false }, { true, false }, { true, false }, { true, false }, }, { { true, false }, { true, false }, { true, false }, { true, false }, } }, OctetMultiArrayField = new byte[, , ] { { { 01, 02 }, { 03, 04 }, { 05, 06 }, { 07, 08 }, }, { { 09, 10 }, { 11, 12 }, { 13, 14 }, { 15, 16 }, }, { { 17, 18 }, { 19, 20 }, { 21, 22 }, { 23, 24 }, } }, EnumMultiArrayField = new TestEnum[, , ] { { { TestEnum.ENUM1, TestEnum.ENUM2 }, { TestEnum.ENUM3, TestEnum.ENUM4 }, { TestEnum.ENUM5, TestEnum.ENUM6 }, { TestEnum.ENUM7, TestEnum.ENUM8 }, }, { { TestEnum.ENUM9, TestEnum.ENUM10 }, { TestEnum.ENUM11, TestEnum.ENUM12 }, { TestEnum.ENUM1, TestEnum.ENUM2 }, { TestEnum.ENUM3, TestEnum.ENUM4 }, }, { { TestEnum.ENUM5, TestEnum.ENUM6 }, { TestEnum.ENUM7, TestEnum.ENUM8 }, { TestEnum.ENUM9, TestEnum.ENUM10 }, { TestEnum.ENUM11, TestEnum.ENUM12 }, }, }, StructMultiArrayField = new NestedStruct[, , ] { { { new NestedStruct { Id = 1, Message = "01" }, new NestedStruct { Id = 2, Message = "02" } }, { new NestedStruct { Id = 3, Message = "03" }, new NestedStruct { Id = 4, Message = "04" } }, { new NestedStruct { Id = 5, Message = "05" }, new NestedStruct { Id = 6, Message = "06" } }, { new NestedStruct { Id = 7, Message = "07" }, new NestedStruct { Id = 8, Message = "08" } }, }, { { new NestedStruct { Id = 9, Message = "09" }, new NestedStruct { Id = 10, Message = "10" } }, { new NestedStruct { Id = 11, Message = "11" }, new NestedStruct { Id = 12, Message = "12" } }, { new NestedStruct { Id = 13, Message = "13" }, new NestedStruct { Id = 14, Message = "14" } }, { new NestedStruct { Id = 15, Message = "15" }, new NestedStruct { Id = 16, Message = "16" } }, }, { { new NestedStruct { Id = 17, Message = "17" }, new NestedStruct { Id = 18, Message = "18" } }, { new NestedStruct { Id = 19, Message = "19" }, new NestedStruct { Id = 20, Message = "20" } }, { new NestedStruct { Id = 21, Message = "21" }, new NestedStruct { Id = 22, Message = "22" } }, { new NestedStruct { Id = 23, Message = "23" }, new NestedStruct { Id = 24, Message = "24" } }, }, }, StringMultiArrayField = new[, , ] { { { "01", "02" }, { "03", "04" }, { "05", "06" }, { "07", "08" }, }, { { "09", "10" }, { "11", "12" }, { "13", "14" }, { "15", "16" }, }, { { "17", "18" }, { "19", "20" }, { "21", "22" }, { "23", "24" }, }, }, WStringMultiArrayField = new[, , ] { { { "01", "02" }, { "03", "04" }, { "05", "06" }, { "07", "08" }, }, { { "09", "10" }, { "11", "12" }, { "13", "14" }, { "15", "16" }, }, { { "17", "18" }, { "19", "20" }, { "21", "22" }, { "23", "24" }, }, }, CharMultiArrayField = new[, , ] { { { '1', '2' }, { '3', '4' }, { '5', '6' }, { '7', '8' }, }, { { '9', '0' }, { '1', '2' }, { '3', '4' }, { '5', '6' }, }, { { '7', '8' }, { '9', '0' }, { '1', '2' }, { '3', '4' }, } }, WCharMultiArrayField = new[, , ] { { { '1', '2' }, { '3', '4' }, { '5', '6' }, { '7', '8' } }, { { '9', '0' }, { '1', '2' }, { '3', '4' }, { '5', '6' }, }, { { '7', '8' }, { '9', '0' }, { '1', '2' }, { '3', '4' }, } }, }; dataWriter.Write(data); ret = dataWriter.WaitForAcknowledgments(new Duration { Seconds = 60, NanoSeconds = 0, }); if (ret == ReturnCode.Ok) { Console.WriteLine("Data sent and acknowledged."); } else { Console.WriteLine("No acknowledge received: " + ret.ToString()); } } else { Console.WriteLine("Subscription not found."); } }
/// <summary> /// Runs the publisher example. /// </summary> public static void RunPublisher(int domainId, int sampleCount) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml // // A participant needs to be Disposed to release middleware resources. // The 'using' keyword indicates that it will be Disposed when this // scope ends. using DomainParticipant participant = DomainParticipantFactory.Instance.CreateParticipant(domainId); // A Topic has a name and a datatype. Topic <HelloWorld> topic = participant.CreateTopic <HelloWorld>("Example PartitionsExample_HelloWorld"); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter will write data on Topic "Example HelloWorld" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <HelloWorld> writer = publisher.CreateDataWriter(topic); var sample = new HelloWorld(); for (int count = 0; count < sampleCount; count++) { // Modify the data to be sent here sample.x = count; Console.WriteLine($"Writing HelloWorld, count {count}"); writer.Write(sample); // Every 5 samples we will change the partition name. // These are the partition expressions we are going to try: // "bar", "A*", "A?C", "X*Z", "zzz" and "A*C". string[] newPartitions = null; if ((count + 1) % 25 == 0) { // Matches "ABC", name[1] here can match name[0] there, // as long as there is some overlapping name. newPartitions = new string[] { "zzz", "A*C" }; } else if ((count + 1) % 25 == 20) { // Strings that are regular expressions aren't tested for // literal matches, so this won't match "X*Z". newPartitions = new string[] { "X*Z" }; } else if ((count + 1) % 25 == 15) { // Matches "ABC". newPartitions = new string[] { "A?C" }; } else if ((count + 1) % 25 == 10) { // Matches "ABC". newPartitions = new string[] { "A*" }; } else if ((count + 1) % 25 == 5) { // No literal match for "bar". // For the next iterations we are using only one partition. newPartitions = new string[] { "bar" }; } if (newPartitions != null) { // Update the publisher QoS with the new partitions publisher.Qos = publisher.Qos.WithPartition(currentPartition => { currentPartition.Clear(); // remove previous partitions currentPartition.AddRange(newPartitions); // add new partitions }); Console.WriteLine( "Publisher partition set to: " + string.Join(separator: ",", values: publisher.Qos.Partition.Name)); } Thread.Sleep(1000); } }
static void Main(string[] args) { bool useListener = true; OpenDDSharp.Ace.Init(); ParticipantService participantService = ParticipantService.Instance; DomainParticipantFactory domainFactory = participantService.GetDomainParticipantFactory(args); DomainParticipantQos qos = new DomainParticipantQos(); qos.EntityFactory.AutoenableCreatedEntities = false; qos.UserData.Value = Encoding.UTF8.GetBytes("sometext"); DomainParticipant participant = domainFactory.CreateParticipant(42, qos); if (participant == null) { throw new Exception("Could not create the participant"); } DomainParticipantQos aux = new DomainParticipantQos(); ReturnCode ret = participant.GetQos(aux); aux.EntityFactory.AutoenableCreatedEntities = true; ret = participant.SetQos(aux); if (participant != null) { TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(participant, typeName); if (result != ReturnCode.Ok) { throw new Exception("Could not register the type"); } Topic topic = participant.CreateTopic("TopicName", typeName); Publisher publisher = participant.CreatePublisher(); if (publisher == null) { throw new Exception("Could not create the publisher"); } DataWriter dw = publisher.CreateDataWriter(topic); if (dw == null) { throw new Exception("Could not create the datawriter"); } TestStructDataWriter dataWriter = new TestStructDataWriter(dw); Subscriber subscriber = participant.CreateSubscriber(); if (subscriber == null) { throw new Exception("Could not create the subscribre"); } MyDataListener listener = null; if (useListener) { listener = new MyDataListener(); } DataReader dataReader = subscriber.CreateDataReader(topic, listener, StatusKind.DataAvailableStatus); if (dataReader == null) { throw new Exception("Could not create the datareader"); } WaitSet waitSet = null; StatusCondition statusCondition = null; if (!useListener) { waitSet = new WaitSet(); statusCondition = dataReader.StatusCondition; waitSet.AttachCondition(statusCondition); statusCondition.EnabledStatuses = StatusKind.DataAvailableStatus; new System.Threading.Thread(delegate() { ICollection <Condition> conditions = new List <Condition>(); Duration duration = new Duration { Seconds = Duration.InfiniteSeconds }; waitSet.Wait(conditions, duration); foreach (Condition cond in conditions) { if (cond == statusCondition && cond.TriggerValue) { StatusCondition sCond = (StatusCondition)cond; StatusMask mask = sCond.EnabledStatuses; if ((mask & StatusKind.DataAvailableStatus) != 0) { DataAvailable(dataReader); } } } }).Start(); } TestStruct test = new TestStruct { RawData = "Hello, I love you, won't you tell me your name?" }; test.LongSequence.Add(20); test.LongSequence.Add(10); test.LongSequence.Add(0); test.StringSequence.Add("Hello,"); test.StringSequence.Add("I love you"); test.StringSequence.Add("won't you tell me your name?"); test.LongDoubleType = 1.1; test.LongDoubleSequence.Add(1.1); test.LongDoubleSequence.Add(2.2); test.LongDoubleSequence.Add(3.3); test.LongArray[0, 0] = 1; test.LongArray[0, 1] = 2; test.LongArray[0, 2] = 3; test.LongArray[0, 3] = 4; test.LongArray[1, 0] = 1; test.LongArray[1, 1] = 2; test.LongArray[1, 2] = 3; test.LongArray[1, 3] = 4; test.LongArray[2, 0] = 1; test.LongArray[2, 1] = 2; test.LongArray[2, 2] = 3; test.LongArray[2, 3] = 4; test.StringArray[0, 0] = "Hello,"; test.StringArray[0, 1] = "I love you,"; test.StringArray[1, 0] = "won't you tell me"; test.StringArray[1, 1] = "your name?"; test.StructArray[0, 0] = new BasicTestStruct() { Id = 0 }; test.StructArray[0, 1] = new BasicTestStruct() { Id = 1 }; test.StructArray[1, 0] = new BasicTestStruct() { Id = 2 }; test.StructArray[1, 1] = new BasicTestStruct() { Id = 3 }; test.LongDoubleArray[0, 0] = 1.1; test.LongDoubleArray[0, 1] = 2.2; test.LongDoubleArray[1, 0] = 3.3; test.LongDoubleArray[1, 1] = 4.4; test.StructSequence.Add(new BasicTestStruct() { Id = 1 }); test.StructSequence.Add(new BasicTestStruct() { Id = 2 }); test.StructSequence.Add(new BasicTestStruct() { Id = 3 }); result = dataWriter.Write(test); System.Threading.Thread.Sleep(1000); if (!useListener) { waitSet.DetachCondition(statusCondition); } participant.DeleteContainedEntities(); domainFactory.DeleteParticipant(participant); } participantService.Shutdown(); OpenDDSharp.Ace.Fini(); Console.WriteLine("Press ENTER to finish the test."); Console.ReadLine(); }
/// <summary> /// Runs the publisher example. /// </summary> public static void RunPublisher( int domainId, int sampleCount, uint tokenBucketPeriodMs, CancellationToken cancellationToken) { // Create a custom flow controller configuration DomainParticipantQos participantQos = ConfigureFlowController( tokenBucketPeriodMs); // Start communicating in a domain, usually one participant per application using DomainParticipant participant = DomainParticipantFactory.Instance.CreateParticipant(domainId, participantQos); // A Topic has a name and a datatype. Topic <HelloWorld> topic = participant.CreateTopic <HelloWorld>("Example cfc"); // Create a Publisher Publisher publisher = participant.CreatePublisher(); // Create a writer with the QoS specified in the default profile // in USER_QOS_PROFILES.xml, which sets up the publish mode policy DataWriter <HelloWorld> writer = publisher.CreateDataWriter(topic); // Create a sample to write with a long payload var sample = new HelloWorld { str = new string('a', 999) }; for (int count = 0; count < sampleCount && !cancellationToken.IsCancellationRequested; count++) { // Simulate a bursty writer by sending 10 samples at a time, // after sleeping for a period if (count % 10 == 0) { Thread.Sleep(1000); } // Modify the data to be sent here sample.x = count; Console.WriteLine($"Writing x={sample.x}"); // With asynchronous publish mode, the Write() puts the sample // in the queue but doesn't send it until the flow controller // indicates so. writer.Write(sample); } try { // Wait until all written samples have been actually published writer.WaitForAsynchronousPublishing(maxWait: Duration.FromSeconds(10)); // And wait until the DataReader has acknowledged them writer.WaitForAcknowledgments(maxWait: Duration.FromSeconds(10)); } catch (TimeoutException) { Console.WriteLine("Timed out waiting to publish all samples"); } }
private void RunExample( int domainId, int sampleCount, string sensorId) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create a Topic named // "ChocolateTemperature" with type Temperature // In this example we use a DynamicType defined in XML, which creates // a DynamicData topic. var provider = new QosProvider("../chocolate_factory.xml"); Topic <DynamicData> topic = participant.CreateTopic( "ChocolateTemperature", provider.GetType("Temperature")); // Exercise #2.1: Add new Topic Topic <DynamicData> lotStateTopic = participant.CreateTopic( "ChocolateLotState", provider.GetType("ChocolateLotState")); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter writes data on Topic "ChocolateTemperature" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <DynamicData> writer = publisher.CreateDataWriter(topic); // Create a DynamicData sample for writing DynamicData sample = writer.CreateData(); // Exercise #2.2: Add new DataWriter and data sample DataWriter <DynamicData> lotStateWriter = publisher.CreateDataWriter(lotStateTopic); DynamicData lotStateSample = lotStateWriter.CreateData(); Random rand = new Random(); for (int count = 0; count < sampleCount && !shutdownRequested; count++) { // Modify the data to be written here sample.SetValue("sensor_id", sensorId); sample.SetValue("degrees", rand.Next(30, 33)); Console.WriteLine($"Writing ChocolateTemperature, count {count}"); writer.Write(sample); // Exercise #2.3 Write data with new ChocolateLotState DataWriter lotStateWriter.SetValue("lot_id", count % 100); // SetAnyValue performs type conversions. In this case it can // translate a string to the corresponding enumerator. lotStateWriter.SetAnyValue("lot_status", "WAITING"); lotStateWriter.Write(lotStateSample); // Exercise #1.1: Change this to sleep 100 ms in between writing temperatures Thread.Sleep(4000); } }
public void TestTakeInstance() { List <PublicationBuiltinTopicData> data = new List <PublicationBuiltinTopicData>(); List <SampleInfo> infos = new List <SampleInfo>(); ReturnCode ret = _dr.Read(data, infos); Assert.AreEqual(ReturnCode.NoData, ret); Assert.AreEqual(0, data.Count); Assert.AreEqual(0, infos.Count); DomainParticipant otherParticipant = AssemblyInitializer.Factory.CreateParticipant(AssemblyInitializer.RTPS_DOMAIN); Assert.IsNotNull(otherParticipant); otherParticipant.BindRtpsUdpTransportConfig(); TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(otherParticipant, typeName); Assert.AreEqual(ReturnCode.Ok, result); var topic = otherParticipant.CreateTopic(TestContext.TestName, typeName); Assert.IsNotNull(topic); var publisher = otherParticipant.CreatePublisher(); Assert.IsNotNull(publisher); DataWriterQos dwQos = TestHelper.CreateNonDefaultDataWriterQos(); dwQos.Ownership.Kind = OwnershipQosPolicyKind.SharedOwnershipQos; DataWriter dataWriter = publisher.CreateDataWriter(topic, dwQos); Assert.IsNotNull(dataWriter); Thread.Sleep(500); ret = _dr.ReadNextInstance(data, infos, InstanceHandle.HandleNil); Assert.AreEqual(ReturnCode.Ok, ret); Assert.AreEqual(1, data.Count); Assert.AreEqual(1, infos.Count); TestHelper.TestNonDefaultPublicationData(data.First()); var handle = infos.First().InstanceHandle; data = new List <PublicationBuiltinTopicData>(); infos = new List <SampleInfo>(); ret = _dr.TakeInstance(data, infos, handle); Assert.AreEqual(ReturnCode.Ok, ret); Assert.AreEqual(1, data.Count); Assert.AreEqual(1, infos.Count); TestHelper.TestNonDefaultPublicationData(data.First()); ret = otherParticipant.DeleteContainedEntities(); Assert.AreEqual(ReturnCode.Ok, ret); ret = AssemblyInitializer.Factory.DeleteParticipant(otherParticipant); Assert.AreEqual(ReturnCode.Ok, ret); }
public void TestOnPublicationLost() { ManualResetEventSlim evt = new ManualResetEventSlim(false); DomainParticipant domainParticipant = AssemblyInitializer.Factory.CreateParticipant(AssemblyInitializer.INFOREPO_DOMAIN); Assert.IsNotNull(domainParticipant); domainParticipant.BindTcpTransportConfig(); Publisher publisher = domainParticipant.CreatePublisher(); Assert.IsNotNull(publisher); TestStructTypeSupport support = new TestStructTypeSupport(); string typeName = support.GetTypeName(); ReturnCode result = support.RegisterType(domainParticipant, typeName); Assert.AreEqual(ReturnCode.Ok, result); Topic topic = domainParticipant.CreateTopic("TestOnPublicationLostDisconnected", typeName); Assert.IsNotNull(topic); MyDataWriterListener listener = new MyDataWriterListener(); DataWriter writer = publisher.CreateDataWriter(topic, listener); int count = 0; listener.PublicationLost += (w, s) => { Assert.AreEqual(writer, w); Assert.AreEqual(1, s.SubscriptionHandles.Count()); Assert.AreNotEqual(InstanceHandle.HandleNil, s.SubscriptionHandles.First()); count++; evt.Set(); }; SupportProcessHelper supportProcess = new SupportProcessHelper(TestContext); Process process = supportProcess.SpawnSupportProcess(SupportTestKind.PublicationLostTest); try { // Wait for discovery bool found = writer.WaitForSubscriptions(1, 20000); Assert.IsTrue(found); } finally { supportProcess.KillProcess(process); } bool resp = evt.Wait(20000); Assert.IsTrue(resp); Assert.AreEqual(1, count); // Remove the listener to avoid extra messages result = writer.SetListener(null); Assert.AreEqual(ReturnCode.Ok, result); domainParticipant.DeleteContainedEntities(); AssemblyInitializer.Factory.DeleteParticipant(domainParticipant); evt.Dispose(); }
public void TestGetParticipant() { Publisher publisher = _participant.CreatePublisher(); Assert.IsNotNull(publisher); Assert.AreEqual(_participant, publisher.Participant); }
private void RunExample(int domainId, string sensorId) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create Topics using the types // defined in chocolate_factory.xml var provider = new QosProvider("../chocolate_factory.xml"); Topic <Temperature> temperatureTopic = participant.CreateTopic( "ChocolateTemperature", types.Temperature); Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic( "ChocolateLotState", types.ChocolateLotState); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // Create DataWriters of Topics "ChocolateTemperature" & "ChocolateLotState" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <Temperature> temperatureWriter = publisher.CreateDataWriter(temperatureTopic); DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter(lotStateTopic); // A Subscriber allows an application to create one or more DataReaders // Subscriber QoS is configured in USER_QOS_PROFILES.xml Subscriber subscriber = participant.CreateSubscriber(); // This DataReader reads data of type Temperature on Topic // "ChocolateTemperature". DataReader QoS is configured in // USER_QOS_PROFILES.xml DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader(lotStateTopic); // Obtain the DataReader's Status Condition StatusCondition statusCondition = lotStateReader.StatusCondition; // Enable the 'data available' status. statusCondition.EnabledStatuses = StatusMask.DataAvailable; // Associate an event handler with the status condition. // This will run when the condition is triggered, in the context of // the dispatch call (see below) statusCondition.Triggered += _ => ProcessLot(lotStateReader, lotStateWriter); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(statusCondition); // Create a thread to periodically publish the temperature Console.WriteLine($"ChocolateTemperature Sensor with ID: {sensorId} starting"); var temperatureTask = Task.Run( () => PublishTemperature(temperatureWriter, sensorId)); while (!shutdownRequested) { // Wait for ChocolateLotState Console.WriteLine("Waiting for lot"); waitset.Dispatch(Duration.FromSeconds(4)); } temperatureTask.Wait(); }
private void RunExample( int domainId = 0, uint lotsToProcess = 10) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // DomainParticipant QoS is configured in USER_QOS_PROFILES.xml DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId); // A Topic has a name and a datatype. Create a Topic named // "ChocolateLotState" with type ChocolateLotState // In this example we use a DynamicType defined in XML, which creates // a DynamicData topic. Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic( "ChocolateLotState", types.ChocolateLotState); // Exercise #4.1: Add a Topic for Temperature to this application Topic <Temperature> temperatureTopic = participant.CreateTopic( "ChocolateTemperature", types.Temperature); // A Publisher allows an application to create one or more DataWriters // Publisher QoS is configured in USER_QOS_PROFILES.xml Publisher publisher = participant.CreatePublisher(); // This DataWriter writes data on Topic "ChocolateLotState" // DataWriter QoS is configured in USER_QOS_PROFILES.xml DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter(lotStateTopic); // A Subscriber allows an application to create one or more DataReaders // Subscriber QoS is configured in USER_QOS_PROFILES.xml Subscriber subscriber = participant.CreateSubscriber(); // Create DataReader of Topic "ChocolateLotState". // DataReader QoS is configured in USER_QOS_PROFILES.xml DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader(lotStateTopic); // Exercise #4.2: Add a DataReader for Temperature to this application DataReader <Temperature> temperatureReader = subscriber.CreateDataReader(temperatureTopic); // Obtain the DataReader's Status Condition StatusCondition temperatureStatusCondition = temperatureReader.StatusCondition; temperatureStatusCondition.EnabledStatuses = StatusMask.DataAvailable; // Associate a handler with the status condition. This will run when the // condition is triggered, in the context of the dispatch call (see below) temperatureStatusCondition.Triggered += _ => MonitorTemperature(temperatureReader); // Do the same with the lotStateReader's StatusCondition StatusCondition lotStateStatusCondition = lotStateReader.StatusCondition; lotStateStatusCondition.EnabledStatuses = StatusMask.DataAvailable; int lotsProcessed = 0; lotStateStatusCondition.Triggered += _ => lotsProcessed += MonitorLotState(lotStateReader); // Create a WaitSet and attach the StatusCondition WaitSet waitset = new WaitSet(); waitset.AttachCondition(lotStateStatusCondition); // Exercise #4.3: Add the new DataReader's StatusCondition to the Waitset waitset.AttachCondition(temperatureStatusCondition); var startLotTask = Task.Run(() => PublishStartLot(lotStateWriter, lotsToProcess)); while (!shutdownRequested && lotsProcessed < lotsToProcess) { waitset.Dispatch(Duration.FromSeconds(4)); } startLotTask.Wait(); }
private void RunExample(int domainId, string stationKind) { if (!Enum.TryParse <StationKind>(stationKind, out var currentStation)) { throw new ArgumentException("Invalid station"); } // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // Uses TemperingApplication QoS profile to set participant name. var qosProvider = new QosProvider("./qos_profiles.xml"); // By specifying a default library, we can later refer to the // profiles without the library name qosProvider.DefaultLibrary = "ChocolateFactoryLibrary"; DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant( domainId, qosProvider.GetDomainParticipantQos("IngredientApplication")); Topic <Temperature> temperatureTopic = participant.CreateTopic <Temperature>("ChocolateTemperature"); Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic <ChocolateLotState>("ChocolateLotState"); ContentFilteredTopic <ChocolateLotState> filteredLotStateTopic = participant.CreateContentFilteredTopic( name: "FilteredLot", relatedTopic: lotStateTopic, filter: new Filter( expression: "next_station = %0", parameters: new string[] { $"'{stationKind}'" })); Publisher publisher = participant.CreatePublisher(); // Create DataWriter of Topic "ChocolateLotState" // using ChocolateLotStateProfile QoS profile for State Data DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter( lotStateTopic, qosProvider.GetDataWriterQos("ChocolateLotStateProfile")); Subscriber subscriber = participant.CreateSubscriber(); // Create DataReader of Topic "ChocolateLotState", filtered by // next_station, and using ChocolateLotStateProfile QoS profile for // State Data. DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader( filteredLotStateTopic, qosProvider.GetDataReaderQos("ChocolateLotStateProfile")); // Monitor the DataAvailable status StatusCondition statusCondition = lotStateReader.StatusCondition; statusCondition.EnabledStatuses = StatusMask.DataAvailable; statusCondition.Triggered += _ => ProcessLot(currentStation, lotStateReader, lotStateWriter); var waitset = new WaitSet(); waitset.AttachCondition(statusCondition); while (!shutdownRequested) { // Wait for ChocolateLotState Console.WriteLine("Waiting for lot"); waitset.Dispatch(Duration.FromSeconds(10)); } }
private void RunExample(int domainId, string sensorId) { // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // Uses TemperingApplication QoS profile to set participant name. var qosProvider = new QosProvider("./qos_profiles.xml"); var participantQos = qosProvider.GetDomainParticipantQos( "ChocolateFactoryLibrary::TemperingApplication"); DomainParticipant participant = DomainParticipantFactory.Instance .CreateParticipant(domainId, participantQos); // A Topic has a name and a datatype. Topic <Temperature> temperatureTopic = participant.CreateTopic <Temperature>( CHOCOLATE_TEMPERATURE_TOPIC.Value); Topic <ChocolateLotState> lotStateTopic = participant.CreateTopic <ChocolateLotState>( CHOCOLATE_LOT_STATE_TOPIC.Value); // A Publisher allows an application to create one or more DataWriters // Create Publisher with default QoS. Publisher publisher = participant.CreatePublisher(); // Create DataWriter of Topic "ChocolateTemperature" // using ChocolateTemperatureProfile QoS profile for Streaming Data DataWriter <Temperature> temperatureWriter = publisher.CreateDataWriter( temperatureTopic, qos: qosProvider.GetDataWriterQos("ChocolateFactoryLibrary::ChocolateTemperatureProfile")); // Create DataWriter of Topic "ChocolateLotState" // using ChocolateLotStateProfile QoS profile for State Data DataWriter <ChocolateLotState> lotStateWriter = publisher.CreateDataWriter( lotStateTopic, qos: qosProvider.GetDataWriterQos("ChocolateFactoryLibrary::ChocolateLotStateProfile")); // A Subscriber allows an application to create one or more DataReaders Subscriber subscriber = participant.CreateSubscriber(); // This DataReader reads data of type Temperature on Topic // "ChocolateTemperature" using ChocolateLotStateProfile QoS // profile for State Data. // // We will handle the "requested incompatible qos" event. By doing // it as a preEnableAction, we avoid a race condition in which // the event could trigger right after the reader creation but // right before adding the event handler. DataReader <ChocolateLotState> lotStateReader = subscriber.CreateDataReader( lotStateTopic, qos: qosProvider.GetDataReaderQos("ChocolateFactoryLibrary::ChocolateLotStateProfile"), preEnableAction: reader => reader.RequestedIncompatibleQos += OnRequestedIncompatibleQos); // Obtain the DataReader's Status Condition StatusCondition statusCondition = lotStateReader.StatusCondition; // Enable the 'data available' status. statusCondition.EnabledStatuses = StatusMask.DataAvailable; // Associate an event handler with the status condition. // This will run when the condition is triggered, in the context of // the dispatch call (see below) statusCondition.Triggered += _ => ProcessLot(lotStateReader, lotStateWriter); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(statusCondition); // Create a thread to periodically publish the temperature Console.WriteLine($"ChocolateTemperature Sensor with ID: {sensorId} starting"); var temperatureTask = Task.Run( () => PublishTemperature(temperatureWriter, sensorId)); while (!shutdownRequested) { // Wait for ChocolateLotState Console.WriteLine("Waiting for lot"); waitset.Dispatch(Duration.FromSeconds(4)); } temperatureTask.Wait(); }