Round trip in C++

authors:Joost Baars
date:Mar 2020

Description

The round trip C++ directory can be found in src/demonstrators/RoundTrip/C++/. This directory contains a folder for the round trip implementation as well as the flood implementation.

This page is split into two major chapters. One for the round trip application and one for the flood application.

Dependencies

The dependencies necessary for succesful compilation of the round trip / flood application in C++ are the following:
  • CMake
  • C++17 compiler (Gcc 7+ for example)
  • CycloneDDS library

Round trip

This chapter contains the information about the round trip application. This application can be found in the directory: src/demonstrators/RoundTrip/C++/RoundTrip.

Configuring

First go to the RoundTrip C++ directory (see Round trip).

The C++ round trip implementation contains an implementation for the round trip with the use of callbacks or the use of of polling and reading. One of these implementations can be chosen before building the project.

The implementation can be configured by altering the following line in the CMakeLists.txt:

set(PROJECT roundtrip_read)

This line can be found at the top of the CMakeLists file. The roundtrip_read can be changed to roundtrip_callback for the callback implementation.

Building

First go to the round trip C++ directory (see Round trip).

Execute the following commands:

mkdir build && cd build
cmake ..
make

These commands compile the code and create the executable.

Execution

The application must be executed using various parameters. The application can be executed using the following command:

./RoundTrip <device ID> <number of devices> <total round trips>

The following example starts 4 nodes for the round trip. The slaves of the round trip are started in the background. Only the master is started in the foreground in this example. Each device pings a total of 1000 times. Therefore, there are 1000 round trips.

./RoundTrip 2 4 1000 & ./RoundTrip 3 4 1000 & ./RoundTrip 4 4 1000 &
./RoundTrip 1 4 1000

A more thorough description of the parameters can be found when executing the application with no parameters.

Note

Execution of the program

The round trip is initiated by the device with <device ID> = 1. Therefore, <device ID> = 1 should always be started after the other ID’s are started.

The devices added with <device ID> must be an increment of the previous one. This function does not dynamically search for the next device! So if there are three devices, device 2 and 3 should be started first. Afterwards, device 1 can be started.

The <total round trips> parameter should be the same for each application.

Implementation

Each round trip application creates a participant containing a reader and a writer. The writer writes to the topic of the ID above it. So applications with ID = 1 writes to the application with ID = 2. The reader reads from its own topic. These topics have the name “roundtrip” with the ID behind it. So the topic with ID = 1 is “roundtrip1”.

The application with ID = 1 initiates the round trip. Therefore, it starts with writing to topic “roundtrip2”. The application with ID = 2 then receives the message of the application with ID = 1, and sends a message to the next application.

Read

The read implementation continuously executes the dds_take() function to get the latest message of its own topic. dds_take() is used so the message is directly removed from DDS and so it won’t be read again. When a message is received, the application uses dds_write() for writing to the next application.

Callback

The callback implementation uses a callback function for receiving the latest message and writing to the next application. This implementation sleeps until data is received on the readers topic. When data is received, a callback function is executed where dds_write() writes to the next application in the round trip.

Flood

This chapter contains the information about the flood application. This application can be found in the directory: src/demonstrators/RoundTrip/C++/Flood

Building

First go to the round trip C++ directory (see Flood).

Execute the following commands:

mkdir build && cd build
cmake ..
make

These commands compile the code and create the executable.

Execution

The application must be executed using various parameters. The application can be executed using the following command:

./Flood <device ID> <number of devices> <total messages>

The following example starts 4 nodes for the flood application. The slaves of the flood are started in the background. Only the master is started in the foreground in this example. There are a total of 1000 messages send by the master. For a flood to be finished, these messages should all be correctly received by the master.

./Flood 2 4 1000 & ./Flood 3 4 1000 & ./Flood 4 4 1000 &
./Flood 1 4 1000

A more thorough description of the parameters can be found when executing the application with no parameters.

Note

Execution of the program

The flood is initiated by the device with <device ID> = 1. Therefore, <device ID> = 1 should always be started after the other ID’s are started.

The devices added with <device ID> must be an increment of the previous one. This function does not dynamically search for the next device! So if there are three devices, device 2 and 3 should be started first. Afterwards, device 1 can be started.

The <total messages> parameter should be the same for each application.

Implementation

Each flood application creates a participant containing a reader and a writer. The writer writes to the topic of the ID above it. So applications with ID = 1 writes to the application with ID = 2. The reader reads from its own topic. These topics have the name “flood” with the ID behind it. So the topic with ID = 1 is “flood1”.

The application with ID = 1 initiates the flood. Therefore, it starts with writing to topic “flood2” as fast as possible. The application with ID = 2 then receives the messages of the application with ID = 1, and sends a message to the next application for each message received.

The slaves (ID not equal to 1) just send a message to the other device in the flood loop as soon as they receive a message. The master (ID = 1) sends messages as fast as possible to the next device in the flood loop.

If the master sends a message, a value is incremented. The master keeps sending messages until the value is equal to the <total messages> parameter that the user inserted when executing the application. If the master receives a message, a value is incremented. At the end, this value should be the same as the <total messages> parameter that the user inserted when executing the application.

Slave

The slave implementation continuously executes the dds_take() function to get the latest message of its own topic. dds_take() is used so the message is directly removed from DDS and so it won’t be read again.

When a message is received, the application uses dds_write() for writing to the next application.

Master

The master implementation continuously executes the dds_take() function to get the latest message of its own topic. Afterwards, it writes a new message to the next device in the flood loop.

Therefore, at the beginning, the master only writes to the next devices. Aftwerwards, the loop will eventually be in a stable condition where the master reads a message first and writes a new message afterwards. In the end, the master won’t send messages anymore, and will only read the last messages that exist in the flood loop.