официальный адрес:https://www.eprosima.com/index.php/company-all/news/146-fast-rtps-is-now-fast-dds
APIадрес:https://fast-dds.docs.eprosima.com/en/latest/
FastDDS
ПредшественникFast-RTPS
,добился многих DDS спецификация. Это высокопроизводительная платформа публикации и подписки в режиме реального времени.
FastDDS
(Fast Data Distribution Service) — высокопроизводительный масштабируемый сервис распределения данных, реализующий OMG DDS
(Object Management Group Data Distribution Сервис) стандартный. Это проект с открытым исходным кодом, целью которого является предоставление решений для передачи данных и обмена сообщениями в реальном времени.
FastDDS
К основным особенностям и функциям относятся:
1. Высокая производительность: Fast DDS использует механизм распределения данных, основанный на модели публикации-подписки, для поддержки быстрого и надежного обмена данными. Целью его разработки является обеспечение передачи данных с малой задержкой и высокой пропускной способностью для удовлетворения сценариев приложений с высокими требованиями к работе в режиме реального времени.
2. Масштабируемость. Fast DDS обладает хорошей масштабируемостью и может адаптироваться к системам различного размера и сложности. Он поддерживает несколько режимов связи и топологий и предоставляет гибкие возможности конфигурации для удовлетворения различных потребностей приложений.
3. Безопасность. Fast DDS обеспечивает надежную передачу данных и механизмы аутентификации для обеспечения конфиденциальности и целостности данных. Он поддерживает шифрование и контроль доступа для защиты конфиденциальных данных от несанкционированных лиц.
4. Поддержка нескольких языков. Fast DDS поддерживает несколько языков программирования, включая C++, Java, Python и т. д., что позволяет разработчикам использовать Fast DDS для разработки в различных средах программирования.
5. Широкие возможности настройки: Fast DDS предоставляет множество вариантов конфигурации и расширяемый механизм подключаемых модулей, позволяющий пользователям настраивать расширения и функциональные улучшения в соответствии с конкретными потребностями.
FastDDS
Он имеет широкий спектр применений в области передачи данных в реальном времени, особенно подходит для распределенных систем, систем управления и мониторинга в реальном времени, робототехники, Интернета вещей и других областей. Он предоставляет разработчикам надежную и высокопроизводительную платформу распространения данных, которая упрощает процесс разработки и интеграции обмена данными в реальном времени.
FastDDSиметьbin、source、docker image
Три способа установки。
Используется здесьbin
Установить,Версия 2.8.1.
скачатьадрес:https://www.eprosima.com/index.php/component/ars/repository/eprosima-fast-dds/eprosima-fast-dds-2-8-1
В установочном пакете,install.sh
Будет автоматически Установить Различные зависимости,Затем войдите в каталог src,Соберите следующие библиотеки соответственно:
осуществлятьinstall.h
нуждатьсяcmake 3.11
выше версия,Если версия ниженуждаться Сначала обновитеcmake:http://t.csdn.cn/LezV9
# Скачать cmake
wget https://cmake.org/files/v3.22/cmake-3.22.1.tar.gz
sudo tar -xvzf cmake-3.22.1.tar.gz -C /usr/share
cd /usr/share/cmake-3.22.1
# Установить cmake
sudo chmod 777 ./configure
sudo ./configure
sudo make
sudo make install
sudo update-alternatives --install /usr/bin/cmake cmake /usr/local/bin/cmake 1 --force
cmake --version
Установите фастддс:
sudo ./install.sh
# Доступные файлы: git、build-essential、cmake、libssl-dev、libasio-dev、libtinyxml2-dev、openjdk-8-jre-headless、foonathan_memory_vendor、fastcdr、fastrtps(Fast DDS)、fastddsgen。
# Если вы хотите протестировать примеры в FastDDS,Эту опцию необходимо включить в скрипте install.sh.,По умолчанию ВЫКЛ.
Установить Также предоставляются пакеты./uninstall.sh
Скрипт,Можно удалить в любое время.
ссылка:https://www.jianshu.com/p/b9eb5dd9559f
# Скачать образец
git clone https://ghproxy.com/https://github.com/wanghuohuo0716/fastdds_helloworld.git
cd fastdds_helloworld
mkdir -p include/idl_generate/
cd idl/
fastddsgen -d ../include/idl_generate/ HelloWorld.idl # Опция -d указывает каталог, в котором сохраняются сгенерированные файлы заголовков.
# После генерации файла интерфейса на основе файла IDL программа FastDDS компилируется в том же терминале.
cd ..
mkdir build && cd build
cmake ..
make
Запустите узлы издателя и подписчика:
cd build/
./DDSHelloWorldPublisher
./DDSHelloWorldSubscriber
mkdir ddstest
touch HelloWorld.idl
touch HelloWorldPublisher.cpp
touch HelloWorldSubscriber.cpp
touch CMakeLists.txt
HelloWorld.idl
module HelloWorldModule {
struct HelloWorld
{
unsigned long index;
string message;
};
};
HelloWorldPublisher.cpp
/**
* @file HelloWorldPublisher.cpp
*
*/
#include "./build/HelloWorld.h"
#include "./build/HelloWorldPubSubTypes.h"
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/DataWriterListener.hpp>
using namespace eprosima::fastdds::dds;
class HelloWorldPublisher
{
private:
HelloWorld hello_;
DomainParticipant *participant_;
Publisher *publisher_;
Topic *topic_;
DataWriter *writer_;
TypeSupport type_;
class PubListener : public DataWriterListener
{
public:
PubListener()
: matched_(0)
{
}
~PubListener() override
{
}
void on_publication_matched(
DataWriter *,
const PublicationMatchedStatus &info) override
{
if (info.current_count_change == 1)
{
matched_ = info.total_count;
std::cout << "Publisher matched." << std::endl;
}
else if (info.current_count_change == -1)
{
matched_ = info.total_count;
std::cout << "Publisher unmatched." << std::endl;
}
else
{
std::cout << info.current_count_change << " is not a valid value for PublicationMatchedStatus current count change." << std::endl;
}
}
std::atomic_int matched_;
} listener_;
public:
HelloWorldPublisher()
: participant_(nullptr), publisher_(nullptr), topic_(nullptr), writer_(nullptr), type_(new HelloWorldPubSubType())
{
}
virtual ~HelloWorldPublisher()
{
if (writer_ != nullptr)
{
publisher_->delete_datawriter(writer_);
}
if (publisher_ != nullptr)
{
participant_->delete_publisher(publisher_);
}
if (topic_ != nullptr)
{
participant_->delete_topic(topic_);
}
DomainParticipantFactory::get_instance()->delete_participant(participant_);
}
// Initialize the publisher
bool init()
{
hello_.index(0);
hello_.message("HelloWorld, this is FastDDS."); // define message
DomainParticipantQos participantQos;
participantQos.name("Participant_publisher");
participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);
if (participant_ == nullptr)
{
return false;
}
// Register the Type
type_.register_type(participant_);
// Create the publications Topic
topic_ = participant_->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);
if (topic_ == nullptr)
{
return false;
}
// Create the Publisher
publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);
if (publisher_ == nullptr)
{
return false;
}
// Create the DataWriter
writer_ = publisher_->create_datawriter(topic_, DATAWRITER_QOS_DEFAULT, &listener_);
if (writer_ == nullptr)
{
return false;
}
return true;
}
// Send a publication
bool publish()
{
if (listener_.matched_ > 0)
{
hello_.index(hello_.index() + 1);
writer_->write(&hello_);
return true;
}
return false;
}
// Run the Publisher
void run(uint32_t samples)
{
uint32_t samples_sent = 0;
while (samples_sent < samples)
{
if (publish())
{
samples_sent++;
std::cout << "Message: " << hello_.message() << " with index: " << hello_.index() << " SENT" << std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
};
int main(int argc, char **argv)
{
std::cout << "Starting publisher." << std::endl;
int samples = 10; // pub count
HelloWorldPublisher *mypub = new HelloWorldPublisher();
if (mypub->init())
{
mypub->run(static_cast<uint32_t>(samples));
}
delete mypub;
return 0;
}
HelloWorldSubscriber.cpp
/**
* @file HelloWorldSubscriber.cpp
*
*/
#include "./build/HelloWorld.h"
#include "./build/HelloWorldPubSubTypes.h"
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
using namespace eprosima::fastdds::dds;
class HelloWorldSubscriber
{
private:
DomainParticipant *participant_;
Subscriber *subscriber_;
DataReader *reader_;
Topic *topic_;
TypeSupport type_;
class SubListener : public DataReaderListener
{
public:
SubListener()
: samples_(0)
{
}
~SubListener() override
{
}
void on_subscription_matched(
DataReader *,
const SubscriptionMatchedStatus &info) override
{
if (info.current_count_change == 1)
{
std::cout << "Subscriber matched." << std::endl;
}
else if (info.current_count_change == -1)
{
std::cout << "Subscriber unmatched." << std::endl;
}
else
{
std::cout << info.current_count_change
<< " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl;
}
}
void on_data_available(
DataReader *reader) override
{
SampleInfo info;
if (reader->take_next_sample(&hello_, &info) == ReturnCode_t::RETCODE_OK)
{
if (info.valid_data)
{
samples_++;
std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()
<< " RECEIVED." << std::endl;
}
}
}
HelloWorld hello_;
std::atomic_int samples_;
} listener_;
public:
HelloWorldSubscriber()
: participant_(nullptr), subscriber_(nullptr), topic_(nullptr), reader_(nullptr), type_(new HelloWorldPubSubType())
{
}
virtual ~HelloWorldSubscriber()
{
if (reader_ != nullptr)
{
subscriber_->delete_datareader(reader_);
}
if (topic_ != nullptr)
{
participant_->delete_topic(topic_);
}
if (subscriber_ != nullptr)
{
participant_->delete_subscriber(subscriber_);
}
DomainParticipantFactory::get_instance()->delete_participant(participant_);
}
// Initialize the subscriber
bool init()
{
DomainParticipantQos participantQos;
participantQos.name("Participant_subscriber");
participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);
if (participant_ == nullptr)
{
return false;
}
// Register the Type
type_.register_type(participant_);
// Create the subscriptions Topic
topic_ = participant_->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);
if (topic_ == nullptr)
{
return false;
}
// Create the Subscriber
subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);
if (subscriber_ == nullptr)
{
return false;
}
// Create the DataReader
reader_ = subscriber_->create_datareader(topic_, DATAREADER_QOS_DEFAULT, &listener_);
if (reader_ == nullptr)
{
return false;
}
return true;
}
// Run the Subscriber
void run(uint32_t samples)
{
while (listener_.samples_ < samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
};
int main(int argc, char **argv)
{
std::cout << "Starting subscriber." << std::endl;
int samples = 10; // sub count
HelloWorldSubscriber *mysub = new HelloWorldSubscriber();
if (mysub->init())
{
/* instant sub */
while (1)
{
mysub->run(static_cast<uint32_t>(samples));
}
}
delete mysub;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(HelloWorldExample)
set(CMAKE_CXX_STANDARD 11)
find_package(fastcdr REQUIRED)
find_package(fastrtps REQUIRED)
# generate idl_gen
file(GLOB IDL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.idl")
foreach(IDL_FILE ${IDL_SOURCES})
get_filename_component(IDL_BASE_NAME ${IDL_FILE} NAME_WE)
set(GENERATED_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${IDL_BASE_NAME}.cxx" "${CMAKE_CURRENT_BINARY_DIR}/${IDL_BASE_NAME}.h")
add_custom_command(
OUTPUT ${GENERATED_SOURCES}
COMMAND fastddsgen -d ./ ${IDL_FILE}
DEPENDS ${IDL_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating C++ files from ${IDL_FILE}"
)
list(APPEND GENERATED_CPP_SOURCES ${GENERATED_SOURCES})
endforeach()
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# generate lib
file(GLOB DDS_HELLOWORLD_SOURCES_CXX "./build/*.cxx")
add_library(HelloWorld_IDL_lib ${DDS_HELLOWORLD_SOURCES_CXX})
add_executable(HelloWorldPublisher HelloWorldPublisher.cpp ${GENERATED_CPP_SOURCES})
target_link_libraries(HelloWorldPublisher HelloWorld_IDL_lib fastcdr fastrtps)
add_executable(HelloWorldSubscriber HelloWorldSubscriber.cpp ${GENERATED_CPP_SOURCES})
target_link_libraries(HelloWorldSubscriber HelloWorld_IDL_lib fastcdr fastrtps)
# Скомпилируйте и запустите
mkdir build && cd build
cmake ..
make
./HelloWorldPublisher
./HelloWorldSubscriber