4. Example Application¶
Connext TSS provides an example application, hello_goodbye, that runs on either Connext DDS Professional or Connext DDS Micro. It demonstrate how to use the Connext TSS libraries with an application that uses a separate library to provide all Connext TSS plugins.
The actual FACE application includes only the minimum necessary code to build a FACE UoP using Connext TSS.
The example demonstrate how a TSS integrator can package additional functionality (plus the Connext TSS plugins) into a linkable library that can be used by FACE UoP. They also show how to combine multiple connections in the same application and how to setup a callback to process received data.
4.1. hello_goodbye¶
4.1.1. Source Code Overview¶
The data type used by the example can be found in
examples/hello_goodbye/idl/HelloGoodbye.idl
. It contains
two types, HelloWorld
and GoodbyeWorld
, and each type
contains a keyed field.
Note
RTI Connext TSS supports user data types in IDL files only. To convert other FACE data model formats to IDL, contact RTI Support or your local account team for assistance.
The source in the app
directory contains the main source for
the FACE application: app/HelloGoodbyeExample.cpp
.
There are four functions defined in this file:
publisher_main()
This function implements the logic for when the application is launched as a publisher. The example shows how to call various FACE TSS functions, as well as the calling convention for providing data samples. It publishes samples of typeHelloWorld
.<user-type>::send_event()
This function is the callback that will be registered with the Connext TSS library for receiving data. Note that the function is named from the perspective of the TSS that “sends the event” to the application. The actual registration of the callback is done in the functionsubscriber_main()
.subscriber_main()
This function implements the logic for when the application is launched as a subscriber. The example shows how to call various FACE TSS functions as well as the calling convention for providing data samples. The subscriber uses thesend_event()
function to process the data. It subscribes to samples of typeHelloWorld
.main()
The main function for the example.
The application source has three important headers included:
#include "FACE/TS.hpp"
Defines the FACE TSS API.
#include "gen/HelloGoodbye.hxx"
This file is generated by rtiddsgen from the IDL file containing the data type definition,idl/HelloWorld.idl
.The header file contains the definition of the
HelloGoodbye
type for the C++ language. The application includes this header file because the FACE API operates on actual data types. So the application must use this generated definition to pass the expected type to the Connext TSS library, and ultimately the Connext DDS core.
#include "gen/HelloGoodbye_TSS.hpp"
This file is generated by rtiddsgen from the IDL file containing the type specific part of the FACE TS API.
In the example code, you’ll see publisher_main()
and subscriber_main()
use the type HelloWorld
. Its structure is passed
to the FACE TSS API calls.
The source files in the gen
directory was generated by rtiddsgen.
They are the type-specific plugins necessary to configure and
interface with Connext DDS and Connext TSS:
HelloGoodbye.c (.h)
Type definition for Connext DDS.HelloGoodbyePlugin.c (.h)
Type plugin for Connext DDS.HelloGoodbyeSupport.c (.h)
Type support for Connext DDS.HelloGoodbye.hxx
FACE type definition.HelloGoodbye_Config.c
Function to get configuration data for Connext TSS.HelloGoodbye_QosSupport.c
QoS configuration per DDS entity for Connext TSS.HelloGoodbye_TypeSupport.c
Function to get type plugin for Connext TSS.HelloGoodbye_TSS.cpp (.hpp)
Typed implementation of FACE TS interface.
See TSS Capabilities for details on the TSS plugins.
4.1.2. Prerequisites¶
RTITSSARCH
environment variable is set to the name of the target architecture (e.g., x64Linux3gcc4.8.2).- If running with Connext DDS Professional, it must be installed and
built for
RTITSSARCH
, and it must conform with the intended FACE profile. TheNDDSHOME
environment variable is set to the location of the Connext DDS Professional installation. TheROXMLHOME
environment variable is set to the location of the libroxml installation, and theLD_LIBRARY_PATH
environment variable includes the location of the libroxml shared library. - If running with Connext DDS Micro, it must be installed and
built for
RTITSSARCH
, and it must conform with the intended FACE profile. TheRTIMEHOME
environment variable is set to the location of the Connext DDS Micro installation. - Connext TSS libraries have been built for
RTITSSARCH
and either Connext DDS Professional or Micro. RTITSSHOME
environment variable points to the location of the Connext TSS installation.JREHOME
environment variable points to the location of a JRE 1.6 or 1.7 installation.- CMake is installed.
4.1.3. Build the example¶
hello_goodbye
contains a CMake script to generate the
necessary plugins and build the application.
When invoking CMake, use the same command line definitions as when building the RTI Connext TSS libraries:
RTI_CONNEXT_TYPE
RTI_TSS_ENABLE_FACE_COMPLIANCE
CMAKE_BUILD_TYPE
cd ${RTITSSHOME}/examples/hello_goodbye
mkdir build
cd build
cmake -DRTI_CONNEXT_TYPE=<pro|micro> -DRTI_TSS_ENABLE_FACE_COMPLIANCE=<your_face_profile> -DCMAKE_BUILD_TYPE=<your_build_type> ../
cmake --build .
Alternatively, use cmake-gui to see and configure additional CMake settings.
cd ${RTITSSHOME}/examples/hello_goodbye
mkdir build_gui
cd build_gui
cmake-gui ../
cmake --build .
The generated plugins will be in the gen
directory:
Note
By default, each run of CMake to build this example will call rtiddsgen to
replace, or overwrite, all files in the gen
directory.
To keep the generated source from being replaced, use the CMake command-line definition ‘-DRTI_REPLACE_GEN=false’.
The resulting executable is output as
../bin/${RTITSSARCH}/${RTI_CONNEXT_TYPE}/hello_goodbye_app
.
Note
Each build is for a single combination of Connext DDS type, FACE profile, and
CMake build type. Additional builds for different configuration combinations are
best done out-of-source (i.e., from a directory separate from the source, like the
build
and build-gui
directories above), but note that the resulting
applications are copied to the same output directory.
4.1.4. Run the example¶
For Connext DDS Professional, by default the example must be run from the
hello_goodbye
directory where the default HelloGoodbye_Qos.xml
XML
QoS configuration file is located. The location of this file can be configured
in gen/HelloGoodbye_Config.c
.
The example can be run as a publisher or a subscriber.
4.1.4.1. Run as a publisher¶
To run the example as a publisher, launch the executable with
the -pub
command-line option:
./bin/${RTITSSARCH}/${RTI_CONNEXT_TYPE}/hello_goodbye_app -pub
The output of a publisher will look like this:
---------------------------------------------------------
RTI Connext TSS HelloWorld Example (Connext DDS Micro)
---------------------------------------------------------
Sending unlimited samples ...
sending message 0
sending message 1
sending message 2
sending message 3
sending message 4
sending message 5
4.1.4.2. Run as a subscriber¶
To run the example as a subscriber, use the -sub
command-line option:
./bin/${RTITSSARCH}/${RTI_CONNEXT_TYPE}/hello_goodbye_app -sub
Alternatively, to run a subscriber in callback mode,
use the +sub
command-line option:
./bin/${RTITSSARCH}/${RTI_CONNEXT_TYPE}/hello_goodbye_app +sub
An optional argument is the number of messages to send/receive before
exiting. This is provided by the -num <NUM SAMPLES>
arguments.
The output of a subscriber receiving samples from a publisher will look like this:
---------------------------------------------------------
RTI Connext TSS HelloWorld Example (Connext DDS Micro)
---------------------------------------------------------
Receiving unlimited samples ...
received data: id[1] msg[Hello World 1]
received data: id[0] msg[Hello World 2]
received data: id[1] msg[Hello World 3]
received data: id[0] msg[Hello World 4]
received data: id[1] msg[Hello World 5]
Note that if there is no data available, the Receive_Message
call will
return a FACE::NOT_AVAILABLE
error (ordinal value is 2), but the example
will continue polling without shutting down.
4.2. Further Modifications¶
4.2.1. DDS QoS¶
In general, QoS for underlying DDS entities are configured in the generated _QoSPlugin.c source files. XML profiles may also be used for Connext DDS Professional.
4.2.2. Adding Connections¶
Each created connection creates an underlying DDS writer and/or reader, so resource limits QoS may need to be increased for additional connections.
4.2.3. Multiple IDLs¶
When using data types from more than one IDL file, the _TypeSupport.c files will
need to be modified to define just one RTI_TSS_get_type_support()
function
between them. This is already done for a single IDL file containing multiple
types.
For example, given Foo.idl
and Bar.idl
, both their generated
Foo_TypeSupport.c and Bar_TypeSupport.c define RTI_TSS_get_type_support()
,
and that is resolved by defining just one function but with contents of both
bodies:
RTI_TSS_TypeSupportPlugin*
RTI_TSS_get_type_support(const char* type_name) {
struct Logger* logger = Logger_getInstance();
static RTI_TSS_TypeSupportPlugin* FACE_DM_Foo_type_plugin = NULL;
static RTI_TSS_TypeSupportPlugin* FACE_DM_Bar_type_plugin = NULL;
if( strcmp( type_name, "FACE::DM::Foo" ) == 0 ) {
/* set and return Foo plugin */
}
if( strcmp( type_name, "FACE::DM::Bar" ) == 0 ) {
/* set and return Bar plugin */
}
4.2.4. DDS Interoperability¶
Considerations when interoperating with other DDS endpoints (TSS or non-TSS):
- The DDS domain must be the same. Configured in _QosPlugin.c
- QoS must be compatible. Configured in _QosPlugin.c.
- Type and topic names must match. Configured in _Config.c.
4.3. Troubleshooting¶
This section has tips for working around some common issues.
4.3.1. Function returned an error¶
The example applications may return an error message of the format:
<function> returned an error: <return_code>
For example, the following error message is FACE::TS::Receive_Message()
returning the FACE::RETURN_CODE_TYPE
with value 2.
Receive_Message returned an error: 2
The return code can be found in a header file, and the return code of each function can be found in either source or the API Reference documentation.
So for the above example, searching the headers in include/FACE
reveals the FACE::RETURN_CODE_TYPE
enum in include/FACE/common.hpp
, where 2 maps to NOT_AVAILABLE
:
typedef enum RETURN_CODE_TYPE
{
NO_ERROR ,
NO_ACTION ,
NOT_AVAILABLE ,
ADDR_IN_USE ,
INVALID_PARAM ,
INVALID_CONFIG ,
PERMISSION_DENIED ,
INVALID_MODE ,
TIMED_OUT ,
MESSAGE_STALE ,
CONNECTION_IN_PROGRESS ,
CONNECTION_CLOSED ,
DATA_BUFFER_TOO_SMALL
} RETURN_CODE_TYPE;
4.3.2. Callback not implemented¶
Callback mode is currently not supported for Safety Base profile.