Пример #1
0
        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));
            }
        }
Пример #2
0
        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.
            // 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)
        {
            // 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);

            // 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();
        }