Reorganize repository
* Move the project top-level CMakeLists.txt to the root of the project; this allows building Cyclone as part of ROS2 without any special tricks; * Clean up the build options: ENABLE_SSL: whether to check for and include OpenSSL support if a library can be found (default = ON); this used to be called DDSC_ENABLE_OPENSSL, the old name is deprecated but still works BUILD_DOCS: whether to build docs (default = OFF) BUILD_TESTING: whether to build test (default = OFF) * Collect all documentation into top-level "docs" directory; * Move the examples to the top-level directory; * Remove the unused and somewhat misleading pseudo-default cyclonedds.xml; * Remove unused cmake files Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
4e80559763
commit
9cf4b97f1a
102 changed files with 627 additions and 1925 deletions
316
docs/manual/GettingStartedGuide/helloworld.rst
Normal file
316
docs/manual/GettingStartedGuide/helloworld.rst
Normal file
|
@ -0,0 +1,316 @@
|
|||
..
|
||||
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the Eclipse Public License v. 2.0 which is available at
|
||||
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
v. 1.0 which is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
|
||||
.. _`HelloWorld`:
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\newpage
|
||||
|
||||
#########################################
|
||||
Building Eclipse Cyclone DDS applications
|
||||
#########################################
|
||||
|
||||
.. .. contents::
|
||||
|
||||
***********************************
|
||||
Building the *Hello World!* example
|
||||
***********************************
|
||||
|
||||
To test the :ref:`installation <TestYourInstallation>`, a small
|
||||
*Hello World!* application is used. This application will also be used
|
||||
as an introduction to DDS.
|
||||
|
||||
This chapter explains how to build this example, without details
|
||||
regarding the source code. The next chapter will explain what has
|
||||
to be done to code the *Hello World!* example.
|
||||
|
||||
The procedure used to build the *Hello World!* example can also be
|
||||
used for building your own applications.
|
||||
|
||||
:Windows: ...
|
||||
|
||||
:Linux: It is advised to have copied the Eclipse Cyclone DDS examples to a user-friendly
|
||||
location as described in :ref:`this <CopyLinuxExamplesToUserFriendlyLocation>`
|
||||
paragraph when actively building the Eclipse Cyclone DDS examples on Linux.
|
||||
This chapter refers to the Eclipse Cyclone DDS examples installed
|
||||
in the user-defined location.
|
||||
|
||||
|
||||
Build Files
|
||||
===========
|
||||
|
||||
Three files are available *Hello World!* root directory to support
|
||||
building the example. Both
|
||||
:ref:`Windows native <WindowsNativeBuild>` (HelloWorld.sln) and
|
||||
:ref:`Linux native <LinuxNativeBuild>` (Makefile) build files
|
||||
will only be available for this *Hello World!* example. All the
|
||||
other examples make use of the :ref:`CMake <CMakeIntro>` build
|
||||
system and thus only have the CMakeLists.txt build related file.
|
||||
|
||||
.. _`LinuxNativeBuild`:
|
||||
|
||||
Linux Native Build
|
||||
==================
|
||||
|
||||
A Linux native :code:`Makefile` is provided in the
|
||||
:code:`examples/helloworld` directory within the destination location
|
||||
entered in the
|
||||
:ref:`vdds_install_examples script <CopyLinuxExamplesToUserFriendlyLocation>`.
|
||||
In a terminal, go to that directory and type
|
||||
::
|
||||
|
||||
make
|
||||
|
||||
The build process should have access to the include files and
|
||||
the ddsc library. The Makefile expects them to be present at
|
||||
system default locations so that it can find them automatically.
|
||||
If this isn't the case on your machine, then please
|
||||
update the commented out :code:`CFLAGS` and :code:`LDFLAGS` within the
|
||||
:code:`Makefile` to point to the proper locations.
|
||||
|
||||
This will build the HelloworldSubscriber and HelloworldPublisher
|
||||
executables in the helloworld source directory (not the bin
|
||||
directory that contains the pre-build binaries).
|
||||
|
||||
The *Hello World!* example can now be executed,
|
||||
like described in :ref:`Test your installation <TestYourInstallation>`,
|
||||
using the binaries that were just build. Be sure to use the right directories.
|
||||
|
||||
|
||||
.. _`WindowsNativeBuild`:
|
||||
|
||||
Windows Native Build
|
||||
====================
|
||||
|
||||
For the Windows Native Build, a Visual Studio solution file is
|
||||
available in the :code:`examples/helloworld` directory. Use a
|
||||
file explorer to navigate to that directory and double click on
|
||||
the :code:`HelloWorld.sln` file. Visual Studio should now start
|
||||
with the HelloWorld solution that contains three projects.
|
||||
|
||||
+----------------------+-------------------------------------------------+
|
||||
| Project | Description |
|
||||
+======================+=================================================+
|
||||
| HelloWorldPublisher | Information to build the example publisher. |
|
||||
+----------------------+-------------------------------------------------+
|
||||
| HelloWorldSubscriber | Information to build the example subcriber. |
|
||||
+----------------------+-------------------------------------------------+
|
||||
| HelloWorldType | Information to (re)generate |
|
||||
| | :ref:`HelloWorldData_Msg <HelloWorldDataFiles>` |
|
||||
| | data type. |
|
||||
+----------------------+-------------------------------------------------+
|
||||
|
||||
Creating the *Hello World!* example executables is as simple as
|
||||
selecting the required configuration and building the solution.
|
||||
|
||||
:code:`helloworld\vs\directories.props` contains the location of where
|
||||
the Eclipse Cyclone DDS header files and libraries are be placed. These locations
|
||||
are based on the default installation directory structure. When Eclipse Cyclone DDS
|
||||
is installed in a different directory, the following paths in
|
||||
:code:`helloworld\vs\directories.props` should be changed, like:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<CycloneDDS_lib_dir>C:/Path/To/CycloneDDS/Installation/lib</CycloneDDS_lib_dir>
|
||||
<CycloneDDS_inc_dir>C:/Path/To/CycloneDDS/Installation/include</CycloneDDS_inc_dir>
|
||||
<CycloneDDS_idlc_dir>C:/Path/To/CycloneDDS/Installation/share/CycloneDDS/idlc</CycloneDDS_idlc_dir>
|
||||
|
||||
To run the example, Visual Studio should run both the publisher
|
||||
and subscriber simultaneously. It is capable of doing so, but
|
||||
it's not its default setting. To change it, open the HelloWorld
|
||||
solution property page by right clicking the solution and
|
||||
selecting :code:`Properties`. Then go to :code:`Common Properties`
|
||||
-> :code:`Startup Project`, select :code:`Multiple startup project`
|
||||
and set :code:`Action "Start"` for HelloWorldPublisher and
|
||||
HelloWorldSubscriber. Finish the change by selecting :code:`OK`.
|
||||
|
||||
Visual Studio is now ready to actually run the *Hello World!*
|
||||
example, which can be done by selecting :code:`Debug` ->
|
||||
:code:`Start without debugging`.
|
||||
Both the HelloworldSubscriber and the HelloworldPublisher will be
|
||||
started and the HelloworldPublisher will write a message that is
|
||||
received by the HelloworldSubscriber.
|
||||
|
||||
.. _`BuildingWithCMake`:
|
||||
|
||||
*******************
|
||||
Building With CMake
|
||||
*******************
|
||||
|
||||
In the earlier chapters, building the *Hello World!* example is done
|
||||
natively. However, the *Hello World!* example can also be build using the
|
||||
`CMake tool <http://cmake.org>`_. This is what is recommended. In fact,
|
||||
all the other examples don't provide native makefiles, only CMake files.
|
||||
|
||||
|
||||
.. _`CMakeIntro`:
|
||||
|
||||
CMake
|
||||
=====
|
||||
|
||||
`CMake <http://cmake.org>`_ is an open-source, cross-platform
|
||||
family of tools designed to build, test and package software.
|
||||
CMake is used to control the software compilation process using
|
||||
simple platform and compiler independent configuration files,
|
||||
and generate native makefiles and workspaces that can be used
|
||||
in the compiler environment of your choice.
|
||||
|
||||
In other words, CMake's main strength is build portability.
|
||||
CMake uses the native tools, and other than requiring itself,
|
||||
does not require any additional tools to be installed. The same
|
||||
CMake input files will build with GNU make, Visual studio 6,7,8
|
||||
IDEs, borland make, nmake, and XCode.
|
||||
|
||||
An other advantage of CMake is building out-of-source. It simply
|
||||
works out-of-the-box. There are two important reasons to choose
|
||||
this:
|
||||
|
||||
1. Easy cleanup (no cluttering the source tree). Simply remove
|
||||
the build directory if you want to start from scratch.
|
||||
2. Multiple build targets. It's possible to have up-to-date
|
||||
Debug and Release targets, without having to recompile the
|
||||
entire tree. For systems that do cross-platform compilation,
|
||||
it is easy to have up-to-date builds for the host and target
|
||||
platform.
|
||||
|
||||
There are a few other benefits to CMake, but that is out of the
|
||||
scope of this document.
|
||||
|
||||
.. _`CycloneDdsPackage`:
|
||||
|
||||
Hello World! CMake (CycloneDDS Package)
|
||||
=======================================
|
||||
|
||||
After the CMake digression, we're back with the *Hello World!*
|
||||
example. Apart from the native build files, CMake build files
|
||||
are provided as well. See
|
||||
:code:`examples/helloworld/CMakeLists.txt`
|
||||
|
||||
.. literalinclude:: ../../../examples/helloworld/CMakeLists.export
|
||||
:linenos:
|
||||
:language: cmake
|
||||
|
||||
It will try to find the :code:`CycloneDDS` CMake package. When it
|
||||
has found it, every path and dependencies are automatically set.
|
||||
After that, an application can use it without fuss. CMake will
|
||||
look in the default locations for the code:`CycloneDDS` package.
|
||||
|
||||
.. _`IdlcGenerate`:
|
||||
|
||||
The :code:`CycloneDDS` package provides the :code:`ddsc` library
|
||||
that contains the DDS API that the application needs. But apart
|
||||
from that, it also contains helper functionality
|
||||
(:code:`idlc_generate`) to generate library targets from IDL
|
||||
files. These library targets can be easily used when compiling
|
||||
an application that depends on a data type described
|
||||
in an IDL file.
|
||||
|
||||
Two applications will be created, :code:`HelloworldPublisher`
|
||||
and :code:`HelloworldSubscriber`. Both consist only out of one
|
||||
source file.
|
||||
|
||||
Both applications need to be linked to the :code:`ddsc` library
|
||||
in the :code:`CycloneDDS` package and :code:`HelloWorldData_lib`
|
||||
that was generated by the call to :code:`idlc_generate`.
|
||||
|
||||
|
||||
.. _`HelloWorldBuilding`:
|
||||
|
||||
Hello World! Configuration
|
||||
==========================
|
||||
|
||||
The *Hello World!* example is prepared to be built by CMake
|
||||
through the use of its :code:`CMakeLists.txt` file. The first
|
||||
step is letting CMake configure the build environment.
|
||||
|
||||
It's good practice to build examples or applications
|
||||
out-of-source. In order to do that, create a :code:`build`
|
||||
directory in the :code:`examples/helloworld` directory and go
|
||||
there, making our location :code:`examples/helloworld/build`.
|
||||
|
||||
Here, we can let CMake configure the build environment for
|
||||
us by typing:
|
||||
::
|
||||
|
||||
cmake ../
|
||||
|
||||
.. note::
|
||||
CMake does a pretty good job at guessing which generator to use, but some
|
||||
environments require that you supply a specific generator. For example, only
|
||||
64-bit libraries are shipped for Windows, but CMake will generate a 32-bit
|
||||
project by default, resulting in linker errors. When generating a
|
||||
Visual Studio project keep in mind to append **Win64** to the generator.
|
||||
The example below shows how to generate a Visual Studio 2015 project.
|
||||
::
|
||||
|
||||
cmake -G "Visual Studio 14 2015 Win64" ..
|
||||
|
||||
.. note::
|
||||
CMake generators can also create IDE environments. For instance,
|
||||
the "Visual Studio 14 2015 Win64" will generate a Visual Studio
|
||||
solution file. Other IDE's are also possible, like Eclipse.
|
||||
|
||||
CMake will use the CMakeLists.txt in the helloworld directory
|
||||
to create makefiles that fit the native platform.
|
||||
|
||||
Since everything is prepared, we can actually build the
|
||||
applications (HelloworldPublisher and HelloworldSubscriber in
|
||||
this case).
|
||||
|
||||
|
||||
Hello World! Build
|
||||
==================
|
||||
|
||||
After the configuration step, building the example is as easy
|
||||
as typing:
|
||||
::
|
||||
|
||||
cmake --build .
|
||||
|
||||
.. note::
|
||||
On Windows, it is likely that you have to supply the config
|
||||
of Visual Studio:
|
||||
::
|
||||
|
||||
cmake --build . --config "Release"
|
||||
|
||||
while being in the build directory created during the
|
||||
configuration step: :code:`examples/helloworld/build`.
|
||||
|
||||
The resulting Publisher and Subscriber applications can be found
|
||||
in:
|
||||
|
||||
:Windows: :code:`examples\helloworld\build\Release`.
|
||||
:Linux: :code:`examples/helloworld/build`.
|
||||
|
||||
The *Hello World!* example can now be executed,
|
||||
like described in :ref:`Test your installation <TestYourInstallation>`,
|
||||
using the binaries that were just build. Be sure to use the right directories.
|
||||
|
||||
|
||||
*******
|
||||
Summary
|
||||
*******
|
||||
|
||||
We've seen that a Eclipse Cyclone DDS application can be build by using a Makefile on Linux
|
||||
or a Visual Studio Solutions on Windows. Also CMake can be used to build a Eclipse Cyclone DDS
|
||||
application. In fact, it is the preferred way of building.
|
||||
|
||||
In the end, a predefined way of generating and building the source code should
|
||||
be followed when building Eclipse Cyclone DDS applications. The figure below shows how a
|
||||
typical Eclipse Cyclone DDS application is build.
|
||||
|
||||
.. image:: ../_static/pictures/BuildSchema.png
|
||||
:scale: 30 %
|
||||
:align: center
|
||||
|
||||
Next chapter will provide an overview of all steps mentioned in the figure above.
|
438
docs/manual/GettingStartedGuide/helloworld_indepth.rst
Normal file
438
docs/manual/GettingStartedGuide/helloworld_indepth.rst
Normal file
|
@ -0,0 +1,438 @@
|
|||
..
|
||||
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the Eclipse Public License v. 2.0 which is available at
|
||||
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
v. 1.0 which is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
|
||||
.. _`HelloWorldInDepth`:
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\newpage
|
||||
|
||||
|
||||
###########################
|
||||
Hello World! in more detail
|
||||
###########################
|
||||
|
||||
.. .. contents::
|
||||
|
||||
The previous chapter focused on building the *Hello World!* example while
|
||||
this chapter will focus on the code itself; what has to be done to code
|
||||
this small example.
|
||||
|
||||
.. _`HelloWorldDataType`:
|
||||
|
||||
*********************
|
||||
Hello World! DataType
|
||||
*********************
|
||||
|
||||
Data-Centric Architecture
|
||||
=========================
|
||||
|
||||
By creating a Data-centric architecture, you get a loosely
|
||||
coupled information-driven system. It emphasizes a data layer
|
||||
that is common for all distributed applications within the
|
||||
system. Because there is no direct coupling among the
|
||||
applications in the DDS model, they can be added and removed
|
||||
easily in a modular and scalable manner. This makes that the
|
||||
complexity of a data-centric architecture doesn't really
|
||||
increase when more and more publishers/subscribers are added.
|
||||
|
||||
The *Hello World!* example has a very simple 'data layer' of only
|
||||
one data type :code:`HelloWorldData_Msg` (please read on).
|
||||
The subscriber and publisher are not aware of each other.
|
||||
The former just waits until somebody provides the data it
|
||||
requires, while the latter just publishes the data without
|
||||
considering the number of interested parties. In other words,
|
||||
it doesn't matter for the publisher if there are none or
|
||||
multiple subscribers (try running the *Hello World!* example
|
||||
by starting multiple HelloworldSubscribers before starting a
|
||||
HelloworldPublisher). A publisher just writes the data. The
|
||||
DDS middleware takes care of delivering the data when needed.
|
||||
|
||||
******************
|
||||
HelloWorldData.idl
|
||||
******************
|
||||
|
||||
To be able to sent data from a writer to a reader, DDS needs to
|
||||
know the data type. For the *Hello World!* example, this data type
|
||||
is described using `IDL <http://www.omg.org/gettingstarted/omg_idl.htm>`_
|
||||
and is located in HelloWorldData.idl. This IDL file will be compiled by
|
||||
a IDL compiler which in turn generates a C language source and header
|
||||
file. These generated source and header file will be used by the
|
||||
HelloworldSubscriber and HelloworldPublisher in order to communicate
|
||||
the *Hello World!* message between the HelloworldPublisher
|
||||
and the HelloworldSubscriber.
|
||||
|
||||
Hello World! IDL
|
||||
================
|
||||
|
||||
There are a few ways to describe the structures that make up the
|
||||
data layer. The HelloWorld uses the IDL language to describe the
|
||||
data type in HelloWorldData.idl:
|
||||
|
||||
.. literalinclude:: ../../../examples/helloworld/HelloWorldData.idl
|
||||
:linenos:
|
||||
:language: idl
|
||||
|
||||
An extensive explanation of IDL lies outside the scope of this
|
||||
example. Nevertheless, a quick overview of this example is given
|
||||
anyway.
|
||||
|
||||
First, there's the :code:`module HelloWorldData`. This is a kind
|
||||
of namespace or scope or similar.
|
||||
Within that module, there's the :code:`struct Msg`. This is the
|
||||
actual data structure that is used for the communication. In
|
||||
this case, it contains a :code:`userID` and :code:`message`.
|
||||
|
||||
The combination of this module and struct translates to the
|
||||
following when using the c language.
|
||||
::
|
||||
|
||||
typedef struct HelloWorldData_Msg
|
||||
{
|
||||
int32_t userID;
|
||||
char * message;
|
||||
} HelloWorldData_Msg;
|
||||
|
||||
When it is translated to a different language, it will look
|
||||
different and more tailored towards that language. This is the
|
||||
advantage of using a data oriented language, like IDL, to
|
||||
describe the data layer. It can be translated into different
|
||||
languages after which the resulting applications can communicate
|
||||
without concerns about the (possible different) programming
|
||||
languages these application are written in.
|
||||
|
||||
.. _`IdlCompiler`:
|
||||
|
||||
Generate Sources and Headers
|
||||
============================
|
||||
|
||||
Like already mentioned in the `Hello World! IDL`_ chapter, an IDL
|
||||
file contains the description of data type(s). This needs to be
|
||||
translated into programming languages to be useful in the
|
||||
creation of DDS applications.
|
||||
|
||||
To be able to do that, there's a pre-compile step that actually
|
||||
compiles the IDL file into the desired programming language.
|
||||
|
||||
A java application :code:`org.eclipse.cyclonedds.compilers.Idlc`
|
||||
is supplied to support this pre-compile step. This is available
|
||||
in :code:`idlc-jar-with-dependencies.jar`
|
||||
|
||||
The compilation from IDL into c source code is as simple as
|
||||
starting that java application with an IDL file. In the case of
|
||||
the *Hello World!* example, that IDL file is HelloWorldData.idl.
|
||||
::
|
||||
|
||||
java -classpath "<install_dir>/share/CycloneDDS/idlc/idlc-jar-with-dependencies.jar" org.eclipse.cyclonedds.compilers.Idlc HelloWorldData.idl
|
||||
|
||||
:Windows: The :code:`HelloWorldType` project within the HelloWorld solution.
|
||||
:Linux: The :code:`make datatype` command.
|
||||
|
||||
This will result in new :code:`generated/HelloWorldData.c` and
|
||||
:code:`generated/HelloWorldData.h`
|
||||
files that can be used in the *Hello World!* publisher and
|
||||
subscriber applications.
|
||||
|
||||
The application has to be rebuild when the data type source
|
||||
files were re-generated.
|
||||
|
||||
Again, this is all for the native builds. When using CMake, all
|
||||
this is done automatically.
|
||||
|
||||
.. _`HelloWorldDataFiles`:
|
||||
|
||||
HelloWorldData.c & HelloWorldData.h
|
||||
===================================
|
||||
|
||||
As described in the :ref:`Hello World! DataType <HelloWorldDataType>`
|
||||
paragraph, the IDL compiler will generate this source and header
|
||||
file. These files contain the data type of the messages that are sent
|
||||
and received.
|
||||
|
||||
While the c source has no interest for the application
|
||||
developers, HelloWorldData.h contains some information that they
|
||||
depend on. For example, it contains the actual message structure
|
||||
that is used when writing or reading data.
|
||||
::
|
||||
|
||||
typedef struct HelloWorldData_Msg
|
||||
{
|
||||
int32_t userID;
|
||||
char * message;
|
||||
} HelloWorldData_Msg;
|
||||
|
||||
It also contains convenience macros to allocate and free memory
|
||||
space for the specific data types.
|
||||
::
|
||||
|
||||
HelloWorldData_Msg__alloc()
|
||||
HelloWorldData_Msg_free(d,o)
|
||||
|
||||
It contains an extern variable that describes the data type to
|
||||
the DDS middleware as well.
|
||||
::
|
||||
|
||||
HelloWorldData_Msg_desc
|
||||
|
||||
***************************
|
||||
Hello World! Business Logic
|
||||
***************************
|
||||
|
||||
Apart from the
|
||||
:ref:`HelloWorldData data type files <HelloWorldDataFiles>` that
|
||||
the *Hello World!* example uses to send messages, the *Hello World!*
|
||||
example also contains two (user) source files
|
||||
(:ref:`subscriber.c <HelloWorldSubscriberSource>` and
|
||||
:ref:`publisher.c <HelloWorldPublisherSource>`), containing the
|
||||
business logic.
|
||||
|
||||
.. _`HelloWorldSubscriberSource`:
|
||||
|
||||
*Hello World!* Subscriber Source Code
|
||||
=====================================
|
||||
|
||||
Subscriber.c contains the source that will wait for a *Hello World!*
|
||||
message and reads it when it receives one.
|
||||
|
||||
.. literalinclude:: ../../../examples/helloworld/subscriber.c
|
||||
:linenos:
|
||||
:language: c
|
||||
|
||||
We will be using the DDS API and the
|
||||
:ref:`HelloWorldData_Msg <HelloWorldDataFiles>` type
|
||||
to receive data. For that, we need to include the
|
||||
appropriate header files.
|
||||
::
|
||||
|
||||
#include "dds/dds.h"
|
||||
#include "HelloWorldData.h"
|
||||
|
||||
The main starts with defining a few variables that will be used for
|
||||
reading the *Hello World!* message.
|
||||
The entities are needed to create a reader.
|
||||
::
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t topic;
|
||||
dds_entity_t reader;
|
||||
|
||||
Then there are some buffers that are needed to actually read the
|
||||
data.
|
||||
::
|
||||
|
||||
HelloWorldData_Msg *msg;
|
||||
void *samples[MAX_SAMPLES];
|
||||
dds_sample_info_t info[MAX_SAMPLES];
|
||||
|
||||
To be able to create a reader, we first need a participant. This
|
||||
participant is part of a specific communication domain. In the
|
||||
*Hello World!* example case, it is part of the default domain.
|
||||
::
|
||||
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
|
||||
The another requisite is the topic which basically describes the
|
||||
data type that is used by the reader. When creating the topic,
|
||||
the :ref:`data description <HelloWorldDataFiles>` for the DDS
|
||||
middleware that is present in the
|
||||
:ref:`HelloWorldData.h <HelloWorldDataFiles>` is used.
|
||||
The topic also has a name. Topics with the same data type
|
||||
description, but with different names, are considered
|
||||
different topics. This means that readers/writers created with a
|
||||
topic named "A" will not interfere with readers/writers created
|
||||
with a topic named "B".
|
||||
::
|
||||
|
||||
topic = dds_create_topic (participant, &HelloWorldData_Msg_desc,
|
||||
"HelloWorldData_Msg", NULL, NULL);
|
||||
|
||||
When we have a participant and a topic, we then can create
|
||||
the reader. Since the order in which the *Hello World!* Publisher and
|
||||
*Hello World!* Subscriber are started shouldn't matter, we need to create
|
||||
a so called 'reliable' reader. Without going into details, the reader
|
||||
will be created like this
|
||||
::
|
||||
|
||||
dds_qos_t *qos = dds_create_qos ();
|
||||
dds_qset_reliability (qos, DDS_RELIABILITY_RELIABLE, DDS_SECS (10));
|
||||
reader = dds_create_reader (participant, topic, qos, NULL);
|
||||
dds_delete_qos(qos);
|
||||
|
||||
We are almost able to read data. However, the read expects an
|
||||
array of pointers to valid memory locations. This means the
|
||||
samples array needs initialization. In this example, we have
|
||||
an array of only one element: :code:`#define MAX_SAMPLES 1`.
|
||||
So, we only need to initialize one element.
|
||||
::
|
||||
|
||||
samples[0] = HelloWorldData_Msg__alloc ();
|
||||
|
||||
Now everything is ready for reading data. But we don't know if
|
||||
there is any data. To simplify things, we enter a polling loop
|
||||
that will exit when data has been read.
|
||||
|
||||
Within the polling loop, we do the actual read. We provide the
|
||||
initialized array of pointers (:code:`samples`), an array that
|
||||
holds information about the read sample(s) (:code:`info`), the
|
||||
size of the arrays and the maximum number of samples to read.
|
||||
Every read sample in the samples array has related information
|
||||
in the info array at the same index.
|
||||
::
|
||||
|
||||
ret = dds_read (reader, samples, info, MAX_SAMPLES, MAX_SAMPLES);
|
||||
|
||||
The :code:`dds_read` function returns the number of samples it
|
||||
actually read. We can use that to determine if the function actually
|
||||
read some data. When it has, then it is still possible that the
|
||||
data part of the sample is not valid. This has some use cases
|
||||
when there is no real data, but still the state of the related
|
||||
sample has changed (for instance it was deleted). This will
|
||||
normally not happen in the *Hello World!* example. But we check
|
||||
for it anyway.
|
||||
::
|
||||
|
||||
if ((ret > 0) && (info[0].valid_data))
|
||||
|
||||
If data has been read, then we can cast the void pointer to the
|
||||
actual message data type and display the contents. The polling
|
||||
loop is quit as well in this case.
|
||||
::
|
||||
|
||||
msg = (HelloWorldData_Msg*) samples[0];
|
||||
printf ("=== [Subscriber] Received : ");
|
||||
printf ("Message (%d, %s)\n", msg->userID, msg->message);
|
||||
break;
|
||||
|
||||
When data is received and the polling loop is stopped, we need to
|
||||
clean up.
|
||||
::
|
||||
|
||||
HelloWorldData_Msg_free (samples[0], DDS_FREE_ALL);
|
||||
dds_delete (participant);
|
||||
|
||||
All the entities that are created using the participant are also
|
||||
deleted. This means that deleting the participant will
|
||||
automatically delete the topic and reader as well.
|
||||
|
||||
|
||||
.. _`HelloWorldPublisherSource`:
|
||||
|
||||
*Hello World!* Publisher Source Code
|
||||
====================================
|
||||
|
||||
Publisher.c contains the source that will write an *Hello World!* message
|
||||
on which the subscriber is waiting.
|
||||
|
||||
.. literalinclude:: ../../../examples/helloworld/publisher.c
|
||||
:linenos:
|
||||
:language: c
|
||||
|
||||
We will be using the DDS API and the
|
||||
:ref:`HelloWorldData_Msg <HelloWorldDataFiles>` type
|
||||
to sent data. For that, we need to include the
|
||||
appropriate header files.
|
||||
::
|
||||
|
||||
#include "dds/dds.h"
|
||||
#include "HelloWorldData.h"
|
||||
|
||||
Just like with the
|
||||
:ref:`reader in subscriber.c <HelloWorldSubscriberSource>`,
|
||||
we need a participant and a topic to be able to create a writer.
|
||||
We use the same topic name as in subscriber.c. Otherwise the
|
||||
reader and writer are not considered related and data will not
|
||||
be sent between them.
|
||||
::
|
||||
|
||||
dds_entity_t participant;
|
||||
dds_entity_t topic;
|
||||
dds_entity_t writer;
|
||||
|
||||
participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
|
||||
topic = dds_create_topic (participant, &HelloWorldData_Msg_desc,
|
||||
"HelloWorldData_Msg", NULL, NULL);
|
||||
writer = dds_create_writer (participant, topic, NULL, NULL);
|
||||
|
||||
The DDS middleware is a publication/subscription implementation.
|
||||
This means that it will discover related readers and writers
|
||||
(i.e. readers and writers sharing the same data type and topic name)
|
||||
and connect them so that written data can be received by readers
|
||||
without the application having to worry about it. There is a catch though:
|
||||
this discovery and coupling takes a small amount of
|
||||
time. There are various ways to work around this problem. The following
|
||||
can be done to properly connect readers and writers:
|
||||
|
||||
* Wait for the publication/subscription matched events
|
||||
|
||||
* The Subscriber should wait for a subscription matched event
|
||||
* The Publisher should wait for a publication matched event.
|
||||
|
||||
The use of these events will be outside the scope of this example
|
||||
|
||||
* Poll for the publication/subscription matches statusses
|
||||
|
||||
* The Subscriber should poll for a subscription matched status to be set
|
||||
* The Publisher should poll for a publication matched status to be set
|
||||
|
||||
The Publisher in this example uses the polling schema.
|
||||
|
||||
* Let the publisher sleep for a second before writing a sample. This
|
||||
is not recommended since a second may not be enough on several networks
|
||||
|
||||
* Accept that the reader miss a few samples at startup. This may be
|
||||
acceptable in cases where the publishing rate is high enough.
|
||||
|
||||
As said, the publisher of this example polls for the publication matched status.
|
||||
To make this happen, the writer must be instructed to 'listen' for this status.
|
||||
The following line of code makes sure the writer does so.
|
||||
::
|
||||
|
||||
dds_set_status_mask(writer, DDS_PUBLICATION_MATCHED_STATUS);
|
||||
|
||||
Now the polling may start:
|
||||
::
|
||||
|
||||
while(true)
|
||||
{
|
||||
uint32_t status;
|
||||
ret = dds_get_status_changes (writer, &status);
|
||||
DDS_ERR_CHECK(ret, DDS_CHECK_REPORT | DDS_CHECK_EXIT);
|
||||
|
||||
if (status == DDS_PUBLICATION_MATCHED_STATUS) {
|
||||
break;
|
||||
}
|
||||
/* Polling sleep. */
|
||||
dds_sleepfor (DDS_MSECS (20));
|
||||
}
|
||||
|
||||
After this loop, we are sure that a matching reader has been started.
|
||||
Now, we commence to writing the data. First the data must be initialized
|
||||
::
|
||||
|
||||
HelloWorldData_Msg msg;
|
||||
|
||||
msg.userID = 1;
|
||||
msg.message = "Hello World";
|
||||
|
||||
Then we can actually sent the message to be received by the
|
||||
subscriber.
|
||||
::
|
||||
|
||||
ret = dds_write (writer, &msg);
|
||||
|
||||
After the sample is written, we need to clean up.
|
||||
::
|
||||
|
||||
ret = dds_delete (participant);
|
||||
|
||||
All the entities that are created using the participant are also
|
||||
deleted. This means that deleting the participant will
|
||||
automatically delete the topic and writer as well.
|
21
docs/manual/GettingStartedGuide/index.rst
Normal file
21
docs/manual/GettingStartedGuide/index.rst
Normal file
|
@ -0,0 +1,21 @@
|
|||
..
|
||||
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the Eclipse Public License v. 2.0 which is available at
|
||||
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
v. 1.0 which is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
|
||||
.. _`GettingStarted`:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
installation.rst
|
||||
helloworld.rst
|
||||
helloworld_indepth.rst
|
||||
next_steps.rst
|
||||
uninstall.rst
|
122
docs/manual/GettingStartedGuide/installation.rst
Normal file
122
docs/manual/GettingStartedGuide/installation.rst
Normal file
|
@ -0,0 +1,122 @@
|
|||
..
|
||||
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the Eclipse Public License v. 2.0 which is available at
|
||||
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
v. 1.0 which is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
|
||||
.. _`Installation`:
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\newpage
|
||||
|
||||
##############################
|
||||
Installing Eclipse Cyclone DDS
|
||||
##############################
|
||||
|
||||
.. .. contents::
|
||||
|
||||
|
||||
.. _`SystemRequirements`:
|
||||
|
||||
*******************
|
||||
System requirements
|
||||
*******************
|
||||
|
||||
At the time of writing, Eclipse Cyclone DDS is known to run on Linux, macOS and Windows. The build-process is not yet able to generate native packages.
|
||||
|
||||
|
||||
***************
|
||||
Linux and macOS
|
||||
***************
|
||||
|
||||
|
||||
.. _`CopyLinuxExamplesToUserFriendlyLocation`:
|
||||
|
||||
Post install steps
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The installation package installs examples in system directories. In order to have a better user
|
||||
experience when building the Eclipse Cyclone DDS examples, it is advised to copy the examples to a
|
||||
user-defined location. This is to be able to build the examples natively and experiment with the
|
||||
example source code.
|
||||
|
||||
For this, the installation package provides the vdds_install_examples
|
||||
script, located in /usr/bin.
|
||||
|
||||
Create an user writable directory where the examples should go. Navigate
|
||||
to that directory and execute the script. Answer 'yes' to the questions
|
||||
and the examples will be installed in the current location.
|
||||
|
||||
Type :code:`vdds_install_examples -h` for more information.
|
||||
|
||||
|
||||
.. _`LinuxSetLibPath`:
|
||||
|
||||
Paths
|
||||
=====
|
||||
|
||||
To be able to run Eclipse Cyclone DDS executables, the required libraries (like libddsc.so) need to
|
||||
be available to the executables. Normally, these are installed in system default locations and it
|
||||
works out-of-the-box. However, if they are not installed in those locations, it is possible that the
|
||||
library search path has to be changed. This can be achieved by executing the command: ::
|
||||
|
||||
export LD_LIBRARY_PATH=<install_dir>/lib:$LD_LIBRARY_PATH
|
||||
|
||||
|
||||
*******
|
||||
Windows
|
||||
*******
|
||||
|
||||
|
||||
.. _`WindowsSetLibPath`:
|
||||
|
||||
Paths
|
||||
~~~~~
|
||||
|
||||
To be able to run Eclipse Cyclone DDS executables, the required libraries (like ddsc.dll) need to be
|
||||
available to the executables. Normally, these are installed in system default locations and it
|
||||
works out-of-the-box. However, if they are not installed on those locations, it is possible that the
|
||||
library search path has to be changed. This can be achieved by executing the command: ::
|
||||
|
||||
set PATH=<install_dir>/bin;%PATH%
|
||||
|
||||
|
||||
.. _`TestYourInstallation`:
|
||||
|
||||
**********************
|
||||
Test your installation
|
||||
**********************
|
||||
|
||||
Eclipse Cyclone DDS includes a simple :ref:`Hello World! <HelloWorld>` application which can be run
|
||||
in order to test your installation. The *Hello World!* application consists of two executables: a so
|
||||
called HelloworldPublisher and a HelloworldSubscriber.
|
||||
|
||||
To run the example application, please open two console windows and navigate to the appropriate
|
||||
directory in both console windows. Run the HelloworldSubscriber in one of the console windows by the
|
||||
typing following command:
|
||||
|
||||
:Windows: :code:`HelloworldSubscriber.exe`
|
||||
:Linux: :code:`./HelloworldSubscriber`
|
||||
|
||||
and the HelloworldPublisher in the other console window by typing:
|
||||
|
||||
:Windows: :code:`HelloworldPublisher.exe`
|
||||
:Linux: :code:`./HelloworldPublisher`
|
||||
|
||||
|
||||
The output HelloworldPublisher should look like
|
||||
|
||||
.. image:: ../_static/pictures/HelloworldPublisherWindows.png
|
||||
|
||||
while the HelloworldSubscriber will be looking like this
|
||||
|
||||
.. image:: ../_static/pictures/HelloworldSubscriberWindows.png
|
||||
|
||||
For more information on how to build this application your own and the code which has
|
||||
been used, please have a look at the :ref:`Hello World! <HelloWorld>` chapter.
|
43
docs/manual/GettingStartedGuide/next_steps.rst
Normal file
43
docs/manual/GettingStartedGuide/next_steps.rst
Normal file
|
@ -0,0 +1,43 @@
|
|||
..
|
||||
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the Eclipse Public License v. 2.0 which is available at
|
||||
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
v. 1.0 which is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
|
||||
.. _`WhatsNext`:
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\newpage
|
||||
|
||||
############
|
||||
What's next?
|
||||
############
|
||||
|
||||
Want to know more about DDS? The primary source of information is the
|
||||
OMG website at http://www.omg.org and specifically the `DDS Getting
|
||||
Started <http://www.omg.org/gettingstarted/omg_idl.htm>`_ page and the
|
||||
`DDS specification <http://www.omg.org/spec/DDS/>`_ itself. The
|
||||
specification is a bit wordy and of course deals with minute details,
|
||||
but it is surprisingly easy to follow for a specification.
|
||||
|
||||
There are also various resources on the web dealing with DDS in general,
|
||||
as the various vendors have posted tutorials, presentations, general
|
||||
information and documentation on their products. While the details
|
||||
between the various implementations do differ, they have much more in
|
||||
common than what separates them, and so this information is also
|
||||
applicable to Eclipse Cyclone DDS. The one thing in which
|
||||
Eclipse Cyclone DDS really differs is in the details of API, but that's
|
||||
just syntax.
|
||||
|
||||
Obviously there are also things specific to Eclipse Cyclone DDS. The
|
||||
level of documentation of Eclipse is not nearly what it should be, but
|
||||
that will improve over time.
|
||||
|
||||
And last but note least: please always feel welcome to ask questions on
|
||||
GitHub!
|
22
docs/manual/GettingStartedGuide/uninstall.rst
Normal file
22
docs/manual/GettingStartedGuide/uninstall.rst
Normal file
|
@ -0,0 +1,22 @@
|
|||
..
|
||||
Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
|
||||
This program and the accompanying materials are made available under the
|
||||
terms of the Eclipse Public License v. 2.0 which is available at
|
||||
http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
v. 1.0 which is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
|
||||
.. _`Uninstall`:
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\newpage
|
||||
|
||||
################################
|
||||
Uninstalling Eclipse Cyclone DDS
|
||||
################################
|
||||
|
||||
TBD.
|
Loading…
Add table
Add a link
Reference in a new issue