/// <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 receive before exiting</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 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 <DynamicData> reader = subscriber.CreateDataReader(topic); // Obtain the DataReader's Status Condition StatusCondition statusCondition = reader.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) int samplesRead = 0; statusCondition.Triggered += _ => samplesRead += ProcessData(reader); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(statusCondition); while (samplesRead < sampleCount) { // Dispatch will call the handlers associated to the WaitSet // conditions when they activate Console.WriteLine("HelloWorld subscriber sleeping for 4 sec..."); waitset.Dispatch(Duration.FromSeconds(4)); } }
public bool Initialize(Parameters parameters) { this.parameters = parameters; if (!ParseConfig()) { return(false); } string baseProfile = parameters.QosLibrary + "::BaseProfileQos"; string pingProfile = parameters.QosLibrary + "::ThroughputQos"; string pongProfile = parameters.QosLibrary + "::ThroughputQos"; var qosProvider = new QosProvider(parameters.QosFile); var participantQos = GetParticipantQos(baseProfile); if (parameters.LatencyTest) { pongSemaphore = new Semaphore(0, 1); } if (SecureUseSecure) { // validate arguments if (!ValidateSecureArgs()) { Console.Error.WriteLine("Failure validating arguments"); return(false); } ConfigureSecurePlugin(ref participantQos); } participant = DomainParticipantFactory.Instance.CreateParticipant(parameters.Domain, participantQos); if (participant == null) { Console.Error.Write("Problem creating participant.\n"); return(false); } publisher = participant.CreatePublisher(qosProvider.GetPublisherQos(pingProfile)); if (publisher == null) { Console.Error.WriteLine("Problem creating publisher."); return(false); } subscriber = participant.CreateSubscriber(qosProvider.GetSubscriberQos(pongProfile)); if (subscriber == null) { Console.Error.WriteLine("Problem creating subscriber."); return(false); } return(true); }
private void RunExample(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 // 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")); // 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 <DynamicData> reader = subscriber.CreateDataReader(topic); // Obtain the DataReader's Status Condition StatusCondition statusCondition = reader.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) int samplesRead = 0; statusCondition.Triggered += _ => samplesRead += ProcessData(reader); // Create a WaitSet and attach the StatusCondition var waitset = new WaitSet(); waitset.AttachCondition(statusCondition); while (samplesRead < sampleCount && !shutdownRequested) { // Dispatch will call the handlers associated to the WaitSet // conditions when they activate Console.WriteLine("ChocolateTemperature subscriber sleeping for 4 sec..."); waitset.Dispatch(Duration.FromSeconds(4)); } }
private DomainParticipantQos GetParticipantQos(string profile) { var qosProvider = new QosProvider(parameters.QosFile); var participantQos = qosProvider.GetDomainParticipantQos(profile); // set initial peers and not use multicast if (peerHostCount > 0) { participantQos = participantQos.WithDiscovery(policy => { policy.InitialPeers.InsertRange(0, peerHostArray); policy.MulticastReceiveAddresses.Clear(); // qos.discovery.multicast_receive_addresses = new DDS.StringSeq(); }); } if (!transport.ConfigureTransport(ref participantQos)) { return(null); } /* * At this point, and not before is when we know the transport message size. * Now we can decide if we need to use asynchronous or not. */ maxSynchronousSize = transport.MinimumMessageSizeMax - (PerftestTransport.MessageOverheadBytes); if (!DataSizeRelatedCalculations()) { Console.Error.Write("[Error] Failed to configure the data size settings.\n"); return(null); } if (parameters.EnableAutoThrottle) { participantQos = participantQos.WithProperty(policy => policy.Add("dds.domain_participant.auto_throttle.enable", "true")); } return(participantQos); }
/// <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); } }
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 DataWriterQos GetWriterQos(string topicName) { string qosProfile = parameters.QosLibrary + "::" + GetQoSProfileName(topicName); var qosProvider = new QosProvider(parameters.QosFile); DataWriterQos dataWriterQos = qosProvider.GetDataWriterQos(qosProfile); if (parameters.NoPositiveAcks && (qosProfile == "PerftestQosLibrary::ThroughputQos" || qosProfile == "PerftestQosLibrary::LatencyQos")) { dataWriterQos = dataWriterQos.WithProtocol(policy => { policy.DisablePositiveAcks = true; if (parameters.KeepDurationUsec != -1) { policy.RtpsReliableWriter.DisablePositiveAcksMinSampleKeepDuration = Duration.FromMilliseconds((ulong)parameters.KeepDurationUsec / 1000); } }); } if (isLargeData || parameters.Asynchronous) { dataWriterQos = dataWriterQos.WithPublishMode(policy => { policy.Kind = PublishModeKind.Asynchronous; if (!parameters.FlowController.StartsWith("default", true, null)) { policy.FlowControllerName = "dds.flow_controller.token_bucket." + parameters.FlowController; } }); } // only force reliability on throughput/latency topics if (topicName != ANNOUNCEMENT_TOPIC_NAME.Value) { if (!parameters.BestEffort) { // default: use the setting specified in the qos profile dataWriterQos = dataWriterQos.WithReliability(policy => policy.Kind = ReliabilityKind.Reliable); } else { // override to best-effort dataWriterQos = dataWriterQos.WithReliability(policy => policy.Kind = ReliabilityKind.BestEffort); } } // These Qos settings are only set for the Throughput datawriter if (topicName == THROUGHPUT_TOPIC_NAME.Value) { if (transport.UseMulticast) { dataWriterQos = dataWriterQos.WithProtocol(policy => policy.RtpsReliableWriter.EnableMulticastPeriodicHeartbeat = true); } if (parameters.BatchSize > 0) { dataWriterQos = dataWriterQos.WithBatch(policy => { policy.Enable = true; policy.MaxDataBytes = parameters.BatchSize; }); dataWriterQos = dataWriterQos.WithResourceLimits(policy => policy.MaxSamples = LengthUnlimited.Value); dataWriterQos = dataWriterQos.WithWriterResourceLimits(policy => policy.MaxBatches = (int)parameters.SendQueueSize); } else { dataWriterQos = dataWriterQos.WithResourceLimits(policy => policy.MaxSamples = (int)parameters.SendQueueSize); } if (parameters.EnableAutoThrottle) { dataWriterQos = dataWriterQos.WithProperty(policy => policy.Add("dds.data_writer.auto_throttle.enable", "true")); } if (parameters.EnableTurboMode) { dataWriterQos = dataWriterQos.WithProperty(policy => policy.Add("dds.data_writer.enable_turbo_mode", "true")); dataWriterQos = dataWriterQos.WithBatch(policy => policy.Enable = false); dataWriterQos = dataWriterQos.WithWriterResourceLimits(policy => policy.MaxBatches = (int)parameters.SendQueueSize); dataWriterQos = dataWriterQos.WithResourceLimits(policy => policy.MaxSamples = AllocationSettings.Unlimited); } } return(dataWriterQos); }
private DataReaderQos GetReaderQos(string topicName) { string qosProfile = parameters.QosLibrary + "::" + GetQoSProfileName(topicName); var qosProvider = new QosProvider(parameters.QosFile); DataReaderQos dataReaderQos = qosProvider.GetDataReaderQos(qosProfile); // only force reliability on throughput/latency topics if (topicName != ANNOUNCEMENT_TOPIC_NAME.Value) { if (!parameters.BestEffort) { dataReaderQos = dataReaderQos.WithReliability(policy => policy.Kind = ReliabilityKind.Reliable); } else { dataReaderQos = dataReaderQos.WithReliability(policy => policy.Kind = ReliabilityKind.BestEffort); } } if (parameters.NoPositiveAcks && (topicName == THROUGHPUT_TOPIC_NAME.Value || topicName == LATENCY_TOPIC_NAME.Value)) { dataReaderQos = dataReaderQos.WithProtocol(policy => policy.DisablePositiveAcks = true); } if (topicName == THROUGHPUT_TOPIC_NAME.Value || (topicName == LATENCY_TOPIC_NAME.Value && !directCommunication && ((DurabilityKind)parameters.Durability == DurabilityKind.Transient || (DurabilityKind)parameters.Durability == DurabilityKind.Persistent))) { dataReaderQos = dataReaderQos = dataReaderQos.WithDurability(policy => { policy.Kind = (DurabilityKind)parameters.Durability; policy.DirectCommunication = directCommunication; }); } dataReaderQos = dataReaderQos.WithResourceLimits(policy => policy.InitialInstances = (int)(parameters.Instances + 1)); if (instanceMaxCountReader != -1) { instanceMaxCountReader++; } dataReaderQos = dataReaderQos.WithResourceLimits(policy => policy.MaxInstances = instanceMaxCountReader); if (parameters.Instances > 1) { if (parameters.InstanceHashBuckets > 0) { dataReaderQos = dataReaderQos.WithResourceLimits(policy => policy.InstanceHashBuckets = parameters.InstanceHashBuckets); } else { dataReaderQos = dataReaderQos.WithResourceLimits(policy => policy.InstanceHashBuckets = (int)parameters.Instances); } } if (transport.UseMulticast && transport.AllowsMulticast()) { string multicastAddr = transport.GetMulticastAddr(topicName); if (multicastAddr == null) { Console.Error.WriteLine("topic name must either be " + THROUGHPUT_TOPIC_NAME.Value + " or " + LATENCY_TOPIC_NAME.Value + " or " + ANNOUNCEMENT_TOPIC_NAME.Value); return(null); } dataReaderQos = dataReaderQos.WithMulticast(policy => { policy.Value.Add(Rti.Dds.Core.Policy.TransportMulticastSettings.Default); policy.Value[0] = policy.Value[0].With(policy2 => { policy2.ReceiveAddress = multicastAddr; policy2.ReceivePort = 0; }); }); } if (parameters.UnboundedSize > 0) { dataReaderQos = dataReaderQos.WithProperty(policy => policy.Add("dds.data_reader.history.memory_manager.fast_pool.pool_buffer_max_size", parameters.UnboundedSize.ToString())); } return(dataReaderQos); }
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, 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); } }
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(); }
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, 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(); }