-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bf047ac
Showing
9 changed files
with
850 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
#Advanced Functionalities | ||
|
||
This section covers slightly more advanced, but useful features that enrichen your implementation. | ||
|
||
|
||
## Topics and Keys | ||
|
||
The RTPS standard contemplates the use of keys to define multiple data sources/sinks within a single topic. | ||
|
||
There are two ways of implementing keys into your topic: | ||
|
||
* Defining a `@Key` field in the IDL file when using FastRTPSGen (see the examples that come with the distribution). | ||
* Manually implementing and using a getKey() method. | ||
|
||
Publishers and Subscribers using topics with keys must be configured to use them, otherwise they will have no effect: | ||
|
||
```cpp | ||
//Publicher-Subscriber Layer configuration | ||
PubAttributes.topic.topicKind = WITH_KEY | ||
``` | ||
|
||
The RTPS Layer requires you to call the getKey() method manually within your callbacks. | ||
|
||
## Sending large data | ||
|
||
The default size *eProsima Fast RTPS* uses to create sockets is a conservative value of 65kb. If your topic data is bigger, it must be fragmented. | ||
|
||
Fragmented messages are sent over multiple packets, as understood by the particular transport layer. To make this possible, you must configure the Publisher to work in asynchronous mode. | ||
|
||
```cpp | ||
PublisherAttributes Wparam; | ||
Wparam.qos.m_publishMode.kind = ASYNCHRONOUS_PUBLISH_MODE; // Allows fragmentation | ||
``` | ||
|
||
In the Writer-Subscriber layer, you have to configure the Writer: | ||
|
||
```cpp | ||
WriterAttributes Wparam; | ||
Wparam.mode= ASYNCHRONOUS_WRITER; // Allows fragmentation | ||
``` | ||
|
||
Note that in best-effort mode messages can be lost if you send big data too fast and the buffer is filled at a faster rate than what the client can process messages. | ||
|
||
## Tuning Realiable mode | ||
|
||
RTPS uses Heartbeat messages to make matched endpoints exchange meta-data on what pieces of data they hold so the missing ones can be re-sent (on Reliable mode of course). | ||
You can modify the frequency of this meta-data exchange by specifying a custom heartbeat period. | ||
|
||
The heartbeat period in the Publisher-Subscriber level is configured as part of the `ParticipantAttributes`: | ||
|
||
```cpp | ||
PublisherAttributes pubAttr; | ||
pubAttr.times.heartbeatPeriod.seconds = 0; | ||
pubAttr.times.heartbeatPeriod.fraction = 500; //500 ms | ||
``` | ||
|
||
In the Writer-Reader layer, this belong to the `WriterAttributes`: | ||
|
||
```cpp | ||
WriterAttributes Wattr; | ||
Wattr.times.heartbeatPeriod.seconds = 0; | ||
Wattr.times.heartbeatPeriod.fraction = 500; | ||
``` | ||
|
||
A smaller heartbeat period increases the amount of overhead messages in the network, but speeds up the system response when a piece of data | ||
is lost. | ||
|
||
## Flow Controllers | ||
|
||
*eprosima Fast RTPS* supports user configurable flow controllers on a Publisher and Participant level. These | ||
controllers can be used to limit the amount of data to be sent under certain conditions depending on the | ||
kind of controller implemented. | ||
|
||
The current release implement throughput controllers, which can be used to limit the total message throughput to be sent | ||
over the network per time measurement unit. In order to use them, a descriptor must be passed into the Participant or Publisher Attributes. | ||
|
||
```cpp | ||
PublisherAttributes WparamSlow; | ||
ThroughputControllerDescriptor slowPublisherThroughputController{300000, 1000}; //Limit to 300kb per second | ||
WparamSlow.terminalThroughputController = slowPublisherThroughputController; | ||
``` | ||
In the Writer-Reader layer, the throughput controllers is built-in and the descriptor deafaults to infinite throughput. To change the values: | ||
```cpp | ||
WriterAttributes WParams; | ||
WParams.throughputController.size = 300000; //300kb | ||
WParams.throughputController.timeMS = 1000; //1000ms | ||
``` | ||
|
||
Note that specifying a throughput controller with a size smaller than the socket size can cause messages to never become sent. | ||
|
||
## Transport Layer | ||
|
||
Unless you specify other configuration, *eprosima Fast RTPS* will use its built in UDPv4 Transport Layer with a default configuration. You can change this default configuration or switch to UDPv6 | ||
by providing an alternative configuration when you create the Participant. | ||
|
||
```cpp | ||
RTPSParticipantAttributes Pparams; | ||
auto my_transport = std::make_shared<UDPv6Transport::TransportDescriptor>(); //Create a descriptor for the new transport | ||
my_transport->receiveBufferSize = 65536; //Configuration parameters | ||
my_transport->granularMode = false; | ||
Pparams.useBuiltinTransport = false; //Disable the built-in Transport Layer. | ||
Pparams.userTransports.push_back(my_transport); //Link the Transport Layer to the Participant | ||
``` | ||
|
||
Note that unless you manualy disable the built-in transport layer, the Participant will use your custom transport configuration along the built-in one. | ||
|
||
This distribution comes with an example of how to change the configuration of the transport layer. It is in folder `examples\UserDefinedTransportExample` | ||
|
||
## Matching endpoints the manual way. | ||
|
||
By default, when you create a Participant or a RTPS Participant the built-in protocols for automatic discovery of endpoints will be active. You can disable them by configuring the Participant: | ||
|
||
```cpp | ||
ParticipantAttributes Pparam; | ||
Pparam.rtps.builtin.use_SIMPLE_EndpointDiscoveryProtocol = false; | ||
Pparam.builtin.use_SIMPLE_RTPSParticipantDiscoveryProtocol = false; | ||
``` | ||
|
||
If you disable the built-in discovery protocols, you will need to manually match Readers and Writers. To inform a Writer about a remote Reader, you can either provide an XML configuration file or use the `RemoteReaderAttributes` structure: | ||
|
||
```cpp | ||
RemoteReaderAttributes ratt; | ||
Locator_t loc; //Add the locator that represents a channel the Reader listens to | ||
loc.set_IP4_address(127,0,0,1); | ||
loc.port = 22222; | ||
ratt.endpoint.unicastLocatorList.push_back(loc) | ||
ratt.guid = c_Guid_Unknown; //GUID_t is left blank, but must be configured when using Reliable Mode. | ||
writer->matched_writer_add(ratt); | ||
``` | ||
Registering a remote Writer into a Reliable mode Reader works the same way: | ||
```cpp | ||
RemoteWriterAttributes watt; | ||
//Configure watt | ||
reader->matched_reader_add(watt); | ||
``` | ||
If you decide to provide the information via XML, you have to specify the file where you want to load from: | ||
|
||
```cpp | ||
participant_attributes.rtps.builtin.use_STATIC_EndpointDiscoveryProtocol = true; | ||
participant_attributes.rtps.builtin.setStaticEndpointXMLFilename("my_xml_configuration.xml"); | ||
``` | ||
You can use this sample XML as a base for building your configuration files: | ||
|
||
```xml | ||
<staticdiscovery> | ||
<participant> | ||
<name>RTPSParticipant</name> | ||
<reader> | ||
<userId>3</userId> | ||
<entityId>4</entityId> | ||
<expectsInlineQos>false</expectsInlineQos> | ||
<topicName>TEST_TOPIC_NAME</topicName> | ||
<topicDataType>HelloWorldType</topicDataType> | ||
<topicKind>NO_KEY</topicKind> | ||
<reliabilityQos>RELIABLE_RELIABILITY_QOS</reliabilityQos> | ||
<unicastLocator | ||
address="127.0.0.1" | ||
port="31377"> | ||
</unicastLocator> | ||
<multicastLocator | ||
address="127.0.0.1" | ||
port="31378"> | ||
</multicastLocator> | ||
<durabilityQos>TRANSIENT_LOCAL_DURABILITY_QOS</durabilityQos> | ||
</reader> | ||
</participant> | ||
</staticdiscovery> | ||
``` | ||
|
||
## Making the most of the built-in protocols | ||
|
||
|
||
As specified in the Built-In protocols section, the Participant or RTPS Participant has a series of meta-data endpoints for use during the discovery process. | ||
It is possible to create a custom listener that listens to the Endpoint Discovery Protocol meta-data. This allows you to create your own network analysis tools. | ||
|
||
```cpp | ||
CustomReaderListener *my_readerListenerSub = new(CustomReaderListener); // Custom user ReaderListeners | ||
CustomReaderListener *my_readerListenerPub = new(CustomReaderListener); | ||
std::pair<StatefulReader*,StatefulReader*> EDPReaders = my_participant->getEDPReaders(); //Get access to the EDP endpoints | ||
EDPReaders.first()->setListener(my_readerListenerSub); // Perform attachments | ||
EDPReaders.second()->setListener(my_readerListenerPub); | ||
``` | ||
The callbacks defined in the ReaderListener you attach to the EDP will execute for each data message after the built-in protocols have processed it. | ||
## Additional Quality of Service options | ||
As a user, you can implement your own quality of service (QoS) restrictions in your application. *eProsima Fast RTPS* comes bundles with a set of examples of how to implement common client-wise QoS settings: | ||
* Deadline: Rise an alarm when the frequency of message arrival for a topic falls below a certain threshold. | ||
* Ownership Srength: When multiple data sources come online, filter duplicates by focusing on the higher priority sources. | ||
* Filtering: Filter incoming messages based on content, time, or both. | ||
These examples come with their own `Readme.txt` that explains how the implementations work. | ||
This marks the end of this document. We recommend you to take a look at the doxygen API reference and the embedded examples that come with the distribution. If you need more help, send us an email it `support@eprosima.com`. | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#Code generation using fastrtpsgen | ||
|
||
*eprosima Fast RTPS* comes with a built-in code generation tool, fastrtpsgen, which eases the process of | ||
translating an IDL specification of a topic to a working implementation of the methods needed to create | ||
publishers and subscribers of that type. This tool can be instructed to generate a sample application using | ||
this data type, providing a Makefile to compile it on Linux and a Visual Studio project for Windows. | ||
|
||
*fastrtpsgen* can be invoked by calling fastrtpsgen on Linux or fastrtpsgen.bat on Windows. | ||
|
||
fastrtpsgen -d <outputdir> -example <platform> -replace <IDLfile> | ||
|
||
The `-replace` argument is needed to replace the currently existing files in case the files for the IDL have been | ||
generated previously. | ||
|
||
When the `-example` argument is added, the tool will generate an automated example and the files to build | ||
it for the platform currently invoked. The `-help` argument provides a list of currently supported Visual Studio | ||
versions and platforms. | ||
|
||
## Output | ||
|
||
*fastrtpsgen* outputs the several files. Assuming the IDL file had the name *“Mytype”*, these files are: | ||
|
||
* MyType.cxx/.h: Type definition. | ||
* MyTypePublisher.cxx/.h: Definition of the Publisher as well as of a PublisherListener. The user must | ||
fill the needed methods for his application. | ||
* MyTypeSubscriber.cxx/.h: Definition of the Subscriber as well as of a SubscriberListener. The behavior | ||
of the subscriber can be altered changing the methods implemented on these files. | ||
* MyTypePubSubType.cxx/.h: Serialization and Deserialization code for the type. It also defines the | ||
getKey method in case the topic uses keys. | ||
* MyTypePubSubMain.cxx: Main file of the example application in case it is generated. | ||
* Makefiles or Visual studio project files. | ||
|
||
## Compilation | ||
|
||
If you are using the binary distribution of *eProsima Fast RTPS*, *fastrtpsgen* is already compiled for you. | ||
If you are building from sources, you will need to compile the tool manually using 'gradle' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#eProsima Fast RTPS | ||
<img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSd0PDlVz1U_7MgdTe0FRIWD0Jc9_YH-gGi0ZpLkr-qgCI6ZEoJZ5GBqQ" align="left" hspace="8" vspace="2" width="100" height="100" > | ||
|
||
*eprosima Fast RTPS* is a C++ implementation of the RTPS (Real Time Publish Subscribe) protocol, which provides publisher-subscriber communications over unreliable transports such as UDP, | ||
as defined and maintained by the Object Management Group (OMG) consortium. RTPS is also the wire interoperability protocol defined for the Data Distribution | ||
Service (DDS) standard, again by the OMG. *eProsima Fast RTPS* holds the benefit of being standalone and up-to-date, as most vendor solutions either implement RTPS as a tool to implement | ||
DDS or use past versions of the specification. | ||
|
||
Some of the main features of this library are: | ||
|
||
* Configurable best-effort and reliable publish-subscribe communication policies for real-time | ||
applications. | ||
* Plug and play connectivity so that any new applications are automatically discovered by any other | ||
members of the network. | ||
* Modularity and scalability to allow continuous growth with complex and simple devices in the | ||
network. | ||
* Configurable network behavior and interchangeable transport layer: Choose the best protocol and | ||
system input/output channel combination for each deployment. | ||
* Two API Layers: a high-level Publisher-Subscriber one focused on usability and a lower-level Writer-Reader one that provides finer access to the inner workings of the RTPS protocol. | ||
|
||
## Installation Guide | ||
You can get either a binary distribution of *eprosima Fast RTPS* or compile the library yourself from source. | ||
|
||
### Installation from binaries | ||
The latest, up to date binary release of *eprosima Fast RTPS* can be obtained from the <a href='http://www.eprosima.com'>company website</a>. | ||
|
||
### Installation from Source | ||
To compile *eprosima Fast RTPS* from source, at least Cmake version 2.8.12 and Boost 1.61 are needed. | ||
Clone the project from GitHub: | ||
|
||
$ git clone https://github.com/eProsima/Fast-RTPS | ||
|
||
If you are on Linux, execute: | ||
|
||
$ cmake ../ -DEPROSIMA_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install | ||
$ make | ||
$ make install | ||
|
||
If you are on Windows, choose your version of Visual Studio: | ||
|
||
> cmake ../ -G"Visual Studio 14 2015 Win64" -DEPROSIMA_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=installationpath | ||
> cmake --build . --target install | ||
|
||
If you want to compile the performance tests, you will need to add the argument `-DPERFORMANCE_TESTS=ON` when calling Cmake. | ||
|
||
## Getting Help | ||
|
||
If you need support you can reach us by mail at `support@eProsima.com` or by phone at `+34 91 804 34 48`. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#Getting Started | ||
|
||
## Brief introduction to the RTPS protocol | ||
|
||
At the top of RTPS we find the Domain, which defines a separate plane of communication. A domain contains any number of Participants, elements capable of sending and receiving data. To do this, the participants use their Endpoints: | ||
|
||
* Reader: Endpoint able to receive data. | ||
* Writer: Endpoint able to send data. | ||
|
||
A Participant can have any number of writer and reader endpoints. | ||
|
||
|
||
![Diagram](http://www.eprosima.com/images/diagrams/RTPS-structure.png) | ||
|
||
|
||
Communication revolves around Topics, which define the data being exchanged. Topics don’t belong to any participant in particular; instead, all interested participants keep track of changes to the topic data, and make sure to keep each other up to date. | ||
The unit of communication is called a Change, which represents an update to a topic. Endpoints register these changes on their History, a data structure that serves as a cache for recent changes. | ||
When you publish a change through a writer endpoint, the following steps happen behind the scenes: | ||
|
||
* The change is added to the writer’s history cache. | ||
* The writer informs any readers it knows about. | ||
* Any interested (subscribed) readers request the change. | ||
* After receiving data, readers update their history cache with the new change. | ||
|
||
By choosing Quality of Service policies, you can affect how these history caches are managed in several ways, but the communication loop remains the same. | ||
|
||
## Building your first application | ||
|
||
To build a minimal application, you must first define the topic. Write an IDL file containing the specification you want. In this case, a single string is sufficient. | ||
|
||
|
||
// HelloWorld.idl | ||
struct HelloWorld | ||
{ | ||
string msg; | ||
}; | ||
|
||
Now we need to translate this file to something Fast RTPS understands. For this we have a code generation tool called fastrtpsgen, which can do two different things: | ||
|
||
* Generate C++ definitions for your custom topic. | ||
* Optionally, generate a working example that uses your topic data. | ||
|
||
You may want to check out the fastrtpsgen user manual, which comes with the distribution of the library. But for now the following commands will do: | ||
|
||
On Windows: | ||
|
||
fastrtpsgen.bat -example x64Win64VS2015 HelloWorld.idl | ||
|
||
On Linux: | ||
|
||
fastrtpsgen -example x64Linux2.6gcc HelloWorld.idl | ||
|
||
The `-example` option creates an example application, which you can use to spawn any number of publishers and a subscribers associated with your topic. | ||
|
||
./HelloWorldPublisherSubscriber publisher | ||
./HelloWorldPublisherSubscriber subscriber | ||
|
||
On Windows: | ||
|
||
HelloWorldPublisherSubscriber.exe publisher | ||
HelloWorldPublisherSubscriber.exe subscriber | ||
|
||
You may need to set up a special rule in your Firewall for *eprosima Fast RTPS* to work correctly on Windows. | ||
|
||
Each time you press <Enter\> on the Publisher, a new datagram is generated, sent over the network | ||
and receiver by Subscribers currently online. If more than one subscriber is available, it can be seen that the | ||
message is equally received on all listening nodes. | ||
|
||
You can modify any values on your custom, IDL-generated data type before sending. | ||
|
||
```cpp | ||
HelloWorld myHelloWorld; | ||
myHelloWorld.message("HelloWorld"); | ||
mp_publisher->write((void*)&myHelloWorld); | ||
``` | ||
Take a look at the `examples/` folder for ideas on how to improve this basic application through different configuration options, and for examples of advanced Fast RTPS features. | ||
Oops, something went wrong.