Skip to content

Commit fe09cf3

Browse files
authored
Add Modern C++ DL example (#632)
Updated cmake-utils to include the new Modern C++ DL imported target
1 parent 73b9199 commit fe09cf3

File tree

7 files changed

+400
-1
lines changed

7 files changed

+400
-1
lines changed

examples/connext_dds/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ if(NOT DEFINED CONNEXTDDS_CONNEXT_DDS_EXAMPLES)
7575
"custom_transport"
7676
"deadline_contentfilter"
7777
# "discovery_snapshot"
78+
"distributed_logger"
7879
"dynamic_data_using_publisher_subscriber"
7980
"flat_data_api"
8081
"flat_data_latency"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Example Code: Distributed Logger
2+
3+
## Concept
4+
5+
RTI Distributed Logger is an API that allows publishing log messages to a DDS Topic.
6+
This will allow your distributed application to send log messages that can be monitored
7+
using tools such as RTI Spy or RTI Admin Console.
8+
9+
It is also possible to use the API directly, creating your own logging infrastructure.
10+
11+
## Example Description
12+
13+
Similar examples are available in other programming languages in the
14+
`rti_workspace/<version>/examples/distributed_logger/<language>/`
15+
folder created under your home directory when RTI Connext is installed.
16+
17+
This example shows a simple application running Distributed Logger to
18+
log several messages using different configurations.
19+
20+
The log messages can then be visualized using RTI Tools such as RTI Spy
21+
or RTI Admin Console.
22+
For example, you may find RTI Spy in your RTI Connext DDS installation
23+
and run it from a terminal as follows:
24+
25+
```sh
26+
cd rti_connext_dds-7.2.0/bin
27+
./rtiddsspy -printSample
28+
```
29+
30+
Once the Distributed Logger example is running in a different terminal,
31+
you should start seeing state information along with the logged messages
32+
on RTI Spy:
33+
34+
```txt
35+
RTI Connext DDS Spy built with DDS version: 7.2.0
36+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37+
rtiddsspy is listening for data, press CTRL+C to stop it.
38+
39+
[...]
40+
41+
09:02:38 New data from 192.168.1.228 : topic="rti/distlog" type="com::rti::dl::LogMessage"
42+
hostAndAppId:
43+
rtps_host_id: 16867916
44+
rtps_app_id: 1940525435
45+
level: 400
46+
category: ""
47+
message: "This is a warning message"
48+
messageId: 1
49+
50+
[...]
51+
```
52+
53+
To learn more about the *Distributed Logger*, refer to the Connext DDS
54+
API online documentation. (Eg.
55+
[Modern C++ Distributed Logger](https://community.rti.com/static/documentation/connext-dds/7.2.0/doc/api/connext_dds/distributed_logger/api_cpp2/index.html)).
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#
2+
# (c) 2023 Copyright, Real-Time Innovations, Inc. All rights reserved.
3+
#
4+
# RTI grants Licensee a license to use, modify, compile, and create derivative
5+
# works of the Software. Licensee has the right to distribute object form
6+
# only for use with RTI products. The Software is provided "as is", with no
7+
# warranty of any type, including any warranty for fitness for any purpose.
8+
# RTI is under no obligation to maintain or support the Software. RTI shall
9+
# not be liable for any incidental or consequential damages arising out of the
10+
# use or inability to use the software.
11+
#
12+
cmake_minimum_required(VERSION 3.11)
13+
project (DistLoggerExample)
14+
15+
# Find RTI Connext dependencies
16+
list(APPEND CMAKE_MODULE_PATH
17+
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../resources/cmake/Modules"
18+
)
19+
include(ConnextDdsConfigureCmakeUtils)
20+
connextdds_configure_cmake_utils()
21+
22+
find_package(
23+
RTIConnextDDS "7.2.0"
24+
REQUIRED
25+
COMPONENTS
26+
core
27+
distributed_logger
28+
)
29+
30+
# Main application
31+
add_executable(${PROJECT_NAME}
32+
"${CMAKE_CURRENT_SOURCE_DIR}/DistLoggerExample.cxx"
33+
)
34+
35+
target_link_libraries(${PROJECT_NAME}
36+
PRIVATE
37+
RTIConnextDDS::cpp2_api
38+
RTIConnextDDS::distributed_logger_cpp2
39+
)
40+
41+
target_include_directories(${PROJECT_NAME}
42+
PRIVATE
43+
"${CMAKE_CURRENT_SOURCE_DIR}"
44+
"${CONNEXTDDS_INCLUDE_DIRS}"
45+
)
46+
47+
set_target_properties(${PROJECT_NAME}
48+
PROPERTIES CXX_STANDARD 11)
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// (c) 2023 Copyright, Real-Time Innovations, Inc. All rights reserved.
3+
//
4+
// RTI grants Licensee a license to use, modify, compile, and create derivative
5+
// works of the Software. Licensee has the right to distribute object form
6+
// only for use with RTI products. The Software is provided "as is", with no
7+
// warranty of any type, including any warranty for fitness for any purpose.
8+
// RTI is under no obligation to maintain or support the Software. RTI shall
9+
// not be liable for any incidental or consequential damages arising out of the
10+
// use or inability to use the software.
11+
//
12+
13+
#include <iostream>
14+
15+
#include <rti/util/util.hpp> // for rti::util::sleep()
16+
#include <rti/distlogger/DistLogger.hpp>
17+
18+
using namespace std;
19+
using namespace dds::domain;
20+
using namespace rti::dist_logger;
21+
22+
23+
void distlogger_example_main(
24+
const string application_kind,
25+
const int domain_id,
26+
const int sleep,
27+
const uint iterations)
28+
{
29+
// First, create the options to personalize Distributed Logger.
30+
// If no options are provided, default ones will be created.
31+
DistLoggerOptions options;
32+
options.domain_id(domain_id);
33+
options.application_kind(application_kind);
34+
35+
// Then, set the created options.
36+
// You can only call set_options before getting the Distributed Logger
37+
// instance. Once an instance has been created, attempting to call
38+
// set_options will throw an exception.
39+
DistLogger::set_options(options);
40+
41+
// Instantiate Distributed Logger
42+
DistLogger dist_logger = DistLogger::get_instance();
43+
44+
// RTI Distributed Logger provides the ability to interact with its
45+
// topics directly. However, for the sake of simplicity in this example,
46+
// you may use RTI Tools such as RTI Spy or RTI Admin Console to visualize
47+
// the logging.
48+
for (uint i = 1; i <= iterations; ++i) {
49+
cout << "\nIteration #" << i << endl;
50+
51+
// Log messages using the appropiate log levels for your messages.
52+
dist_logger.debug("This is a debug message");
53+
dist_logger.warning("This is a warning message");
54+
dist_logger.error("This is an error message");
55+
56+
rti::util::sleep(dds::core::Duration(sleep));
57+
}
58+
59+
// The DistLogger instance must be finalized for clean-up
60+
// before the the participant factory is finalized.
61+
DistLogger::finalize();
62+
}
63+
64+
65+
int main(int argc, char *argv[])
66+
{
67+
const string application = "Modern C++ Distributed Logger Example";
68+
69+
int domain_id = 0;
70+
int sleep = 1;
71+
uint iterations = 50;
72+
73+
for (int i = 1; i < argc;) {
74+
const string &param = argv[i++];
75+
76+
if ((param == "-d" || param == "--domain_id") && i < argc) {
77+
domain_id = atoi(argv[i++]);
78+
} else if ((param == "-i" || param == "--iterations") && i < argc) {
79+
iterations = atoi(argv[i++]);
80+
} else if ((param == "-s" || param == "--sleep") && i < argc) {
81+
sleep = atoi(argv[i++]);
82+
} else {
83+
cout << argv[0] << " [options]\n"
84+
<< "\t-d, --domain_id <domain ID> (default: 0)\n"
85+
<< "\t-s, --sleep <seconds between iterations> (default: 1)\n"
86+
<< "\t-i, --iterations <number of iterations> (default: 50)\n"
87+
<< "\t-h, --help Display this message.\n"
88+
<< endl;
89+
return -1;
90+
}
91+
}
92+
93+
try {
94+
distlogger_example_main(application, domain_id, sleep, iterations);
95+
96+
// Finalize Domain Participant Factory
97+
dds::domain::DomainParticipant::finalize_participant_factory();
98+
} catch (const exception &ex) {
99+
// This will catch DDS exceptions
100+
cerr << "Exception in distlogger_example_main: " << ex.what() << endl;
101+
return -1;
102+
}
103+
104+
return 0;
105+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Example Code: Modern C++ Distributed Logger Application
2+
3+
## Example Structure
4+
5+
The following files are part of the example:
6+
7+
- `DistLoggerExample.cxx`
8+
- `distlogSupport.h`
9+
10+
> **Note**:
11+
>
12+
> The `distlogSupport.h` header is necessary to use Modern C++ Distributed
13+
> Logger in RTI Connextdds 7.2.0.
14+
>
15+
> **Note**:
16+
>
17+
> The `CMakeLists.txt` file in this example uses the latest version
18+
> of `FindRTIConnextDDS.cmake` from the
19+
> [cmake-utils](https://github.com/rticommunity/rticonnextdds-cmake-utils)
20+
> repository to find the Modern C++ Distributed Logger libraries.
21+
> If you are using RTI Connext 7.2.0, you may want to use a newer version from
22+
> that repository as well.
23+
24+
## Building the Example
25+
26+
In order to build this example, you need to define the variable `CONNEXTDDS_DIR`
27+
You can do so by exporting it manually, by sourcing the `rtisetenv` script for
28+
your architecture, or by passing it to the `cmake` command as arguments:
29+
30+
```sh
31+
mkdir build
32+
cd build
33+
cmake -DCONNEXTDDS_DIR=<Connext DDS Directory> \ # If not exported
34+
-DBUILD_SHARED_LIBS=ON|OFF \
35+
-DCMAKE_BUILD_TYPE=Debug|Release ..
36+
cmake --build .
37+
```
38+
39+
> **Note**:
40+
>
41+
> You do not need to define `CONNEXTDDS_ARCH` if you only have one architecture
42+
> target installed in your system.
43+
>
44+
> **Note**:
45+
>
46+
> When using a multi-configuration generator, make sure you specify
47+
> the `--config` parameter in your call to `cmake --build .`. In general,
48+
> it's a good practice to always provide it.
49+
50+
This will produce a binary directory (*build*) where the application
51+
can be found.
52+
53+
> **Note:**
54+
>
55+
> When you need to cross-compile the example, the above
56+
> command will not work, the assigned compiler won't be the cross-compiler and
57+
> errors may happen when linking against the cross-compiled Connext binaries. To
58+
> fix this, you have to create a file with the architecture name and call CMake
59+
> with a specific flag called `-DCMAKE_TOOLCHAIN_FILE`. An example of the file to
60+
> create with the toolchain settings (e.g. for an ARM architectures):
61+
62+
```cmake
63+
set(CMAKE_SYSTEM_NAME Linux)
64+
set(toolchain_path "<path to>/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian")
65+
set(CMAKE_C_COMPILER "${toolchain_path}/bin/arm-linux-gnueabihf-gcc")
66+
set(CMAKE_CXX_COMPILER "${toolchain_path}/bin/arm-linux-gnueabihf-g++")
67+
```
68+
69+
Then you can call CMake like this:
70+
71+
```sh
72+
cmake -DCONNEXTDDS_DIR=<connext dir> \
73+
-DCMAKE_TOOLCHAIN_FILE=<toolchain file created above> \
74+
-DCONNEXTDDS_ARCH=<connext architecture> ..
75+
```
76+
77+
## Running the Example
78+
79+
### Example Application
80+
81+
Run the application in a terminal as follows:
82+
83+
On *Windows* systems run:
84+
85+
```sh
86+
DistLoggerExample.exe [options]
87+
```
88+
89+
On *UNIX* systems run:
90+
91+
```sh
92+
./DistLoggerExample [options]
93+
```
94+
95+
where the options are:
96+
97+
- `-d, --domain`: Domain ID.
98+
99+
**Default**: 0.
100+
101+
- `-s, --sleep`: Number of seconds to sleep between iterations.
102+
103+
**Default**: 1.
104+
105+
- `-i, --iterations`: Number of logging iterations.
106+
107+
**Default**: 50.
108+
109+
- `-h, --help`: Displays application usage and exits.
110+
111+
You should see the messages that are being logged on each iteration printed
112+
on the terminal.
113+
114+
### Visualizing the log messages
115+
116+
Once the example application is running, open RTI Spy or
117+
RTI Admin Console.
118+
You should be able to visualize the logging messages being sent
119+
by the application.
120+
121+
To learn more about RTI Tools, refer to their section in the
122+
[Connext DDS documentation](https://community.rti.com/documentation).
123+
124+
## Customizing the Build
125+
126+
### Configuring Build Type and Generator
127+
128+
By default, CMake will generate build files using the most common generator for
129+
your host platform (e.g., Makefiles on Unix-like systems and Visual Studio
130+
Solutions on Windows). You can use the following CMake variables to modify the
131+
default behavior:
132+
133+
- `-DCMAKE_BUILD_TYPE` - specifies the build mode. Valid values are `Release`
134+
and `Debug`. See the [CMake documentation for more details
135+
(Optional)](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html).
136+
137+
- `-DBUILD_SHARED_LIBS` - specifies the link mode. Valid values are `ON` for
138+
dynamic linking and `OFF` for static linking. See [CMake documentation for
139+
more details
140+
(Optional)](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html).
141+
142+
- `-G` - CMake generator. The generator is the native build system used to
143+
build the source code. All the valid values are described in the CMake
144+
documentation for [CMake
145+
Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
146+
147+
For example, to build an example in Debug/Dynamic mode run CMake as follows:
148+
149+
```sh
150+
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON .. -G "Visual Studio 15 2017" -A x64
151+
```
152+
153+
### Configuring Connext Installation Path and Architecture
154+
155+
The CMake build infrastructure will try to guess the location of your Connext
156+
installation and the Connext architecture based on the default settings
157+
for your host platform. If you installed Connext in a custom location, you
158+
can use the `CONNEXTDDS_DIR` variable to indicate the path to your RTI Connext
159+
installation folder. For example:
160+
161+
```sh
162+
cmake -DCONNEXTDDS_DIR=/home/rti/rti_connext_dds-x.y.z ..
163+
```
164+
165+
Also, if you installed libraries for multiple target architectures on your system
166+
(i.e., you installed more than one target `.rtipkg` file), you can use the
167+
`CONNEXTDDS_ARCH` variable to indicate the architecture of the specific libraries
168+
you want to link against. For example:
169+
170+
```sh
171+
cmake -DCONNEXTDDS_ARCH=x64Linux3gcc5.4.0 ..
172+
```

0 commit comments

Comments
 (0)