.. date: 31/03/2026 author: Andre' Neto copyright: Copyright 2017 F4E | European Joint Undertaking for ITER and the Development of Fusion Energy ('Fusion for Energy'). Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence") You may not use this work except in compliance with the Licence. You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl warning: Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licence permissions and limitations under the Licence. UDPReceiver =========== The :vcisdoxygenmccl:`UDPReceiver` DataSource can be used to receive application data over UDP. Typical use cases include subscribing to data from a remote application. This data can be used for monitoring or control purposes. In the latter case, the data is used to synchronise the ``RealTimeThread``. In this section, the ``LinuxTimer`` will be replaced by a ``UDPReceiver`` and the ``RealTimeThread`` will execute every time a UDP packet arrives. This way, the ``ReferencePosition`` signal will be synchronised with the arrival of UDP packets, which are generated by the sender application. The sender is the application developed in the previous section, which streams application statistics and the ``ReferencePosition`` over UDP. The configuration file for the sender is ``../Configurations/MassSpring/RTApp-MassSpring-24-Sender.cfg``. .. literalinclude:: /_static/tutorial/Configurations/MassSpring/RTApp-MassSpring-24-Receiver.cfg :language: c++ :lines: 1184-1198 :caption: UDPReceiver configuration. Note that the port number is set by the variable ``TUTORIAL_UDP_PORT_1``, which is replaced by ``Makefile.cfg`` and must match the port number used by the sender application. :linenos: :emphasize-lines: 3 .. literalinclude:: /_static/tutorial/Configurations/MassSpring/RTApp-MassSpring-24-Receiver.cfg :language: c++ :lines: 5-36 :caption: ``GAMTimer`` replaced with ``GAMUDPReceiver``. The ``Frequency`` parameter still needs to be set to a non-zero value, but the actual pace of the ``RealTimeThread`` will be determined by the arrival of UDP packets. :linenos: :emphasize-lines: 9 Running the application ----------------------- Start the sender application with: .. code-block:: bash make -C ../Configurations/MassSpring/ -f Makefile.cfg ./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-24-Sender_Gen.cfg -l RealTimeLoader -s State1 Once the application is running, inspect the ``screen`` output and verify that the application is running without issues. The log should show entries similar to the following: .. code-block:: console $ [Warning - Threads.cpp:181]: Failed to change the thread priority (likely due to insufficient permissions) $ [Information - RealTimeLoader.cpp:111]: Started application in state State1 $ [Information - MARTeApp.cpp:135]: Application starting $ [Information - LoggerBroker.cpp:152]: Time [0:0]:0 $ [Information - LoggerBroker.cpp:152]: Time [0:0]:1000000 ... Open another terminal and start the receiver application with: .. code-block:: bash ./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-24-Receiver_Gen.cfg -l RealTimeLoader -s State1 Once the application is running, inspect the ``screen`` output and verify that the application is running without issues. The log should show entries similar to the following: .. code-block:: console $ [Warning - Threads.cpp:181]: Failed to change the thread priority (likely due to insufficient permissions) $ [Information - RealTimeLoader.cpp:111]: Started application in state State1 $ [Information - MARTeApp.cpp:135]: Application starting $ [Information - LoggerBroker.cpp:152]: Time [0:0]:14000000 ... .. note:: The actual time values will depend on the arrival of UDP packets, which in turn depends on the execution of the sender application. If the receiver application is started before the sender, the first ``Time`` value will not be zero, but will correspond to the ``Time`` of the first received UDP packet. Exercises --------- Ex. 1: Detecting stalled data ----------------------------- In the example above, the receiver application waits indefinitely for UDP packets to arrive. In some cases, it may be desirable to detect if the data stream has stalled (e.g. due to a network issue or because the sender application has stopped). This can be achieved by using the ``Timeout`` parameter of the ``UDPReceiver`` DataSource, which specifies a timeout in milliseconds after which the ``UDPReceiver`` will return a failure. .. warning:: A DataSource failure propagates to the interfacing GAM and then to the ``GAMScheduler``. This means that all subsequent GAMs in the execution list **will not be executed**. Consequently, if a GAM needs to gracefully handle a failure, it must be executed before the GAM that will fail (which means it will use data from the previous cycle). 1. Edit the file ``../Configurations/MassSpring/RTApp-MassSpring-25-Receiver.cfg`` and modify the DataSource ``UDPWriterReference`` to have a ``Timeout`` of ``1.0 s``. 2. Add a ``MathExpressionGAM`` to detect stalled data based on the ``Time`` signal and name it ``UDPStalled``. 3. Add the ``UDPStalled`` signal to the ``GAMWriterStats`` GAM and to the ``UDPWriterStats`` DataSource. 4. Add the new ``MathExpressionGAM`` to the execution list before the ``GAMUDPReceiver``, and also move the ``GAMWriterStats`` before the ``GAMUDPReceiver``. 5. Run ``make -C ../Configurations/MassSpring/ -f Makefile.cfg`` to generate the configuration file with the correct UDP port numbers. .. code-block:: bash make -C ../Configurations/MassSpring/ -f Makefile.cfg ./MARTeApp.sh -f ../Configurations/MassSpring/RTApp-MassSpring-25-Receiver_Gen.cfg -l RealTimeLoader -s State1 .. code-block:: bash TUTORIAL_UDP_PORT_4=`awk '/\+UDPWriterStats/,/}/ {if ($1=="Port") print $3}' ../Configurations/MassSpring/RTApp-MassSpring-25-Receiver_Gen.cfg`;echo "TUTORIAL_UDP_PORT_4=$TUTORIAL_UDP_PORT_4" python ../Test/Integrated/udp_monitor.py -p $TUTORIAL_UDP_PORT_4 -s 3 6. Stop the sender application and verify on the python output that the receiver application detects the stalled data stream. .. dropdown:: Solution :icon: key The solution is to modify the configuration file ``../Configurations/MassSpring/RTApp-MassSpring-25-Receiver.cfg`` and to add a ``MathExpressionGAM``. .. literalinclude:: /_static/tutorial/Configurations/MassSpring/RTApp-MassSpring-25-Receiver-solution.cfg :language: c++ :caption: MathExpressionGAM to detect stalled data based on the ``Time`` signal. :linenos: :lines: 5-30 Add the ``UDPStalled`` signal to the ``GAMWriterStats`` GAM and to the ``UDPWriterStats`` DataSource. .. literalinclude:: /_static/tutorial/Configurations/MassSpring/RTApp-MassSpring-25-Receiver-solution.cfg :language: c++ :caption: Updated ``GAMWriterStats`` with the ``UDPStalled`` signal. :linenos: :lines: 950-957,992-997 .. literalinclude:: /_static/tutorial/Configurations/MassSpring/RTApp-MassSpring-25-Receiver-solution.cfg :language: c++ :caption: Updated ``UDPWriterStats`` with the ``UDPStalled`` signal. :linenos: :lines: 1184-1193 Add the new ``MathExpressionGAM`` to the execution list before the ``GAMUDPReceiver``, and also move the ``GAMWriterStats`` before the ``GAMUDPReceiver``. .. literalinclude:: /_static/tutorial/Configurations/MassSpring/RTApp-MassSpring-25-Receiver-solution.cfg :language: c++ :caption: Updated execution list. :linenos: :lines: 1238-1251 :emphasize-lines: 10