eProsima Micro XRCE-DDS Client¶
In eProsima Micro XRCE-DDS, a Client can communicate with the DDS Network as any other DDS actor could do. Clients can either publish and subscribe to data Topics in the DDS Global Data Space, or act as a client/service application following a request-reply pattern.
This section explains how the Client-Agent communication happens through streams that can be either best-effort or reliable.
After this, it is explained how users can configure Clients applications and the communication with the Agent
via sets of CMake flags (-D<parameter>=<value>
) that enable/disable profiles and/or allow customize
the size of several parameters.
Finally, a table is presented to explain the creation mode options of the Clients on the Agent’s side.
The section is organized as follows:
eProsima Micro XRCE-DDS provides the user with a C API to create eProsima Micro XRCE-DDS Clients applications. Find the full Client API in the dedicated page.
Streams¶
The Client-Agent communication is performed by streams. The streams can be seen as communication channels. There are two types of streams: best-effort and reliable. The user can define a maximum of 127 best-effort streams and 128 reliable streams, but for the majority of purposes, only one stream in either best-effort or reliable mode is used.
- Best-effort streams
Best-effort streams send and receive the data leaving the reliability to the transport layer. As a result, they consume fewer resources than reliable streams. Also, no history is stored and so the message size sent or received by a best-effort stream must be less or equal than the MTU defined in the transport layer.
- Reliable streams
Reliable streams perform the communication without loss, regardless of the transport layer used, and allow for message fragmentation to send and receive messages longer than the MTU.
To avoid loss of data, reliable streams use additional messages to confirm the delivery. Moreover, reliable streams have a history associated, used to store messages that can not be processed due to issues such as delivery order or incomplete fragments or messages that can not be confirmed yet. The size of the history can be tailored to fit the specific requirements of the application. The size of the stream corresponds to the MTU defined in the transport layer times the history.
If the history is full:
The messages written to the Agent will be discarded until the history is freed and has space to store the new messages.
The messages received from the agent will be discarded. The library will try to recover the discarded messages requesting them to the agent (increasing the bandwidth consumption in the process).
Summarizing:
A short history causes more messages to be discarded, increasing the data traffic because they need to be sent again. At the same time, it consumes less memory.
A long history will reduce the traffic of confirmation messages when the loss rate is high.
This internal management of the communication implies that a reliable stream is more expensive than a best-effort stream, in both memory and bandwidth, but it is possible to play with these values using the history size.
The streams are probably the highest memory load part of the application. For that, the choice of a right configuration for the application is highly recommendable, especially when the target is a limited resource device. The Memory optimization page explains more in detail how to achieve this.
Profiles¶
The Client library follows a profile concept that enables to choose, add or remove some features at compile-time, thus allowing to customize the Client library size, if there are features that are not used.
The profiles can be chosen using CMake arguments and start with the prefix UCLIENT_PROFILE
(-D<parameter>=<value>
) before the compilation.
By means of these profiles, the user can choose which transport to use, and whether to enable or not the discovery and framing functionalities.
Definition |
Description |
Values |
Default |
---|---|---|---|
|
Enables or disables the possibility to connect with the Agent by UDP. |
|
|
|
Enables or disables the possibility to connect with the Agent by TCP. |
|
|
|
Enables or disables the possibility to connect with the Agent by Serial. |
|
|
|
Enables or disables the possibility to connect with the Agent by CAN FD. |
|
|
|
Enables or disables the possibility to connect with the Agent by Custom Transport. |
|
|
|
Enables or disables the functions of the discovery feature |
|
|
|
Enables or disables the stream framing protocol. |
|
|
|
Enables or disables the multithread locking operation of the library. |
|
|
|
Enables or disables a basic local memory transport operation between entities in the same application. |
|
|
Transport profiles¶
The implementation of the transport depends on the platform. As mentioned in the Introductory page, the Client is supported by the following platforms: Linux, Windows, FreeRTOS, Zephyr and NuttX. Linux and all three RTOSes present a POSIX-compliant API to some degree. Find below a table summarizing the compatibility of each these Operating Systems, according to their POSIX compliance, with the transports supported by the eProsima Micro XRCE-DDS Client.
The table below shows the current implementation.
Transport |
POSIX |
Windows |
---|---|---|
UDP |
X |
X |
TCP |
X |
X |
Serial |
X |
|
CAN FD |
X |
|
Custom |
X |
X |
Each available transport can be activated or desactivated via the opportune CMake flag:
UCLIENT_PROFILE_<transport>
, where <transport> = UDP, TCP, SERIAL, CAN
, or
UCLIENT_PROFILE_CUSTOM_TRANSPORT
in the case Custom transport is to be used.
eProsima Micro XRCE-DDS provides a user API that allows interfacing with the lowest level transport layer at runtime. In this way, a user is enabled to implement its own transports based on one of the two communication approaches: stream-oriented or packet-oriented.
By means of this API, a user can set four callbacks which will be in charge of opening and closing the transport, and writing and reading from it. This custom transport API is enabled by setting the CMake argument UCLIENT_PROFILE_CUSTOM_TRANSPORT=<bool>
to true. In the case that stream-oriented transport is used UCLIENT_PROFILE_STREAM_FRAMING=<bool>
should also be enabled.
Find out more in the Transport section of the Client API.
Discovery profile¶
The discovery profile allows discovering Agents in the network by UDP.
The reachable Agents will respond to the discovery call sending information about themselves, as their IP and port.
This can happen in two ways: multicast or unicast.
The discovery phase can be performed before the uxr_create_session call to determine the Agent to connect with.
The declaration of these functions can be found in uxr/client/profile/discovery/discovery.h
.
This profile is enabled when the UCLIENT_DISCOVERY_PROFILE
is ON
.
Find out more in the dedicated section of the API.
Note
This feature is only available on Linux.
Framing profile¶
The framing profile enables HDLC Framing for using stream-oriented transports such as Serial transports or Custom transports that require framing.
Multithread profile¶
The multithread profile enables the thread-safe operation with the Micro XRCE-DDS Client library. It lockguards all the critical sections of the API and allows the usage from concurrent tasks.
Configurations¶
There are several definitions for configuring and building the Client library at compile-time.
These definitions allow users to create a version of the library according to their requirements.
These parameters can be selected as CMake flags (-D<parameter>=<value>
) before the compilation.
By means of these flags, the user can change the default value of all the parameters listed below.
Definition |
Description |
Values |
Default |
---|---|---|---|
|
Configures the maximum output best-effort streams that a session could |
|
|
|
Configures the maximum output reliable streams that a session could have. |
|
|
|
Configures the maximum input best-effort streams that a session could |
|
|
|
Configures the maximum input reliable streams that a session could have. |
|
|
|
This value indicates the number of attempts that |
|
|
|
This value represents how long it will take to send a new |
|
|
|
In a reliable communication, this value represents how long it will take for |
|
|
|
This value must correspond to the memory endianness of the device in |
|
|
|
This value corresponds to the Maximum Transmission Unit (MTU) that can |
|
|
|
This value corresponds to the Maximum Transmission Unit (MTU) that can |
|
|
|
This value corresponds to the Maximum Transmission Unit (MTU) that can |
|
|
|
This value corresponds to the Maximum Transmission Unit (MTU) that can |
|
|
|
This value corresponds to the Max number of entities involved in shared memory. |
|
|
|
This value corresponds to the Max number data buffers stored in shared memory. |
|
|
|
Enables Micro XRCE-DDS Client hard liveliness check. |
|
|
|
Sets Micro XRCE-DDS Client hard liveliness check timeout in milliseconds. Maximum value is 999999 ms. |
|
|
Note
The MTU of the CAN transport is fixed to 64 bytes, which is the maximum payload supported by CAN FD frames. Take this into account to calculate the size of the streams for the requirements of the application.
Read Access Delivery Control¶
The Read Access Delivery Control handles the read operation from a datareader previously created
on the Agent to fetch data from the middleware.
It comes with an optional control
argument, that allows the Client setting the following parameters:
max_bytes_per_second
: Maximum rate at which data messages may be returned, measured in bytes per secpond.max_elapsed_time
: Maximum amount of time that can be spent by the Agent in delivering the topic, measured in seconds.max_samples
: Maximum number of topics that the Agent can send to the Client.min_pace_period
: Minimum elapsed time between two topics deliveries, measured in milliseconds,.
For more information, consult the Read access of the Client API.
Creation Mode: Client¶
The creation of Entities on the Agent which can act on behalf of the Clients in the DDS world can be done in three ways: by XML, by reference or by binary. In this section, we explain these three creation modes and provide guidance on their usage.
- XML
In the XML case, when creating the entities in the Client application, the user must provide each
entity
with a const char* <entity>_xml parameter containing a string of text with XML syntax, matching the DDS rules for creating a DDS entity with an XML profile, as explained here.For instance, when creating a participant or a topic, the profiles shall look as follows:
<!-- PARTICIPANT --> const char* participant_xml = "<dds>" "<participant>" "<rtps>" "<name>[PARTICIPANT NAME]</name>" "</rtps>" "</participant>" "</dds>"; <!-- TOPIC --> const char* topic_xml = "<dds>" "<topic>" "<name>[TOPIC NAME]</name>" "<dataType>[TOPIC TYPE]</dataType>" "</topic>" "</dds>"
As detailed in the Getting started section, participants, topics, datawriters, datareaders, requesters and repliers work similarly. Publishers and subscribers, instead, inherit their XML fields from their associated dataWriters and dataReaders.
Creation by XML has the advantage of being configurable direclty within the Client application, but comes with the drawback of offering a very limited set of options as regards the QoS with which the DDS entities profiles can be configured. Indeed, only best-effort or reliable communication streams can be set with this creation mode. In many cases, these QoS configurations alone may not be enough. For these cases, eProsima Micro XRCE-DDS allows the users to use the creation by references mode.
- References
Creation by references happens by feeding the Agent with an XML profile containing a string of text similar to the snippets provided above, with a label associated to it. Therefore, when creating an entity, the Client will only need to provide a reference to this label in spite of the complete XML profile. This creation mode comes with two advantages:
It consumes less Client memory, making the application more lightweight.
It allows the Clients to write their own XML QoS and run the Agent with a custom configuration which can benefit of the full set of QoS available in DDS.
For instance, when creating a participant or a topic, the profiles shall look as follows:
<!-- PARTICIPANT --> const char* participant_ref = "participant_label"; <!-- TOPIC --> const char* topic_ref = "topic_label"
Binary
Creation by binary provides a comprehensive API in the Micro XRCE-DDS Client library that can be used to generate and send over the XRCE-DDS middleware binary representations of the entities that are being created. This creation mode comes with two advantages:
It consumes less Client memory than XML mode, making the application more lightweight.
It provides much more flexibility than the REF mode in the client side.
For instance, when creating a participant or a topic, the profiles shall look as follows:
uxrQoS_t qos = { .reliability = UXR_RELIABILITY_RELIABLE, .durability = UXR_DURABILITY_TRANSIENT_LOCAL, .history = UXR_HISTORY_KEEP_LAST, .depth = 0 }; uxr_buffer_create_topic_bin(&session, reliable_out, topic_id, participant_id, "ExampleTopic", "ExampleType", UXR_REPLACE); uxr_buffer_create_datawriter_bin(&session, reliable_out, datawriter_id, publisher_id, topic_id, qos, UXR_REPLACE);
Find more information in the Creation Mode: Agent section in the eProsima Micro XRCE-DDS Agent page.
Creation Policy Table¶
The following table summarizes the behaviour of the Agent under entity creation request.
Creation flags |
Entity exists |
Result |
---|---|---|
Don’t care |
NO |
Entity is created. |
|
YES |
No action is taken, and |
|
YES |
Existing entity is deleted, requested entity is created and |
|
YES |
If entity matches no action is taken and
UXR_STATUS_OK_MATCHED is returned.If entity does not match any action is taken and
UXR_STATUS_ERR_MISMATCH is returned. |
|
YES |
If entity matches no action is taken and
UXR_STATUS_OK_MATCHED is returned.If entity does not match, exiting entity is deleted, requested entity is created and
UXR_STATUS_OK is returned. |