目錄
- 一、FastDDS和Fast-RTPS區(qū)別
- 二、FastDDS安裝
- 三、FastDDS使用
一、FastDDS和Fast-RTPS區(qū)別
eProsima Fast RTPS 是一個(gè)高性能的發(fā)布訂閱框架,使用基于發(fā)布者、訂閱者和數(shù)據(jù)主題的解耦模型在分布式系統(tǒng)中共享數(shù)據(jù)。 Fast RTPS 實(shí)現(xiàn)了許多 DDS 規(guī)范,例如 DDS 安全性、DDS-XTypes、RPC over DDS、DDS TCP PSM 和現(xiàn)代 C DDS 映射,但Fast RTPS中一些核心 DDS API 尚未完全符合標(biāo)準(zhǔn)。
在過去幾年中,eProsima 不斷致力于新功能、創(chuàng)新工具和標(biāo)準(zhǔn) API 的開發(fā),以使 Fast RTPS 成為當(dāng)今最完整的開源 DDS 中間件。
現(xiàn)在(2020.5),eProsima 可以自豪地說,eProsima Fast RTPS 實(shí)施符合 OMG DDS 1.4 和 RTPS 2.2 標(biāo)準(zhǔn)。
作為這一刻的象征,F(xiàn)ast RTPS 更名為 Fast DDS!
二、FastDDS安裝
2.1 安裝包下載
FastDDS提供了三種安裝方式,分別是bin、Source、docker image 3 種方式。
推薦使用bin安裝方式,F(xiàn)astDDS的bin安裝方式實(shí)際也是源碼編譯安裝。
在官網(wǎng)填寫信息后,選擇bin安裝方式,進(jìn)入下載界面(該鏈接不需要填寫信息?。螺d安裝包eProsima Fast DDS 2.8.1 - Linux (32 & 64)

該安裝包有install.sh腳本,install.sh會(huì)自動(dòng)apt安裝各種依賴,然后進(jìn)入src目錄下,分別從源碼構(gòu)建foonathan_memory_vendor、fastcdr、fastrtps、fastddsgen。

-
foonathan_memory_vendor,一個(gè) STL 兼容的 C++ 內(nèi)存分配器 庫。 -
fastcdr,一個(gè)根據(jù) CDR 標(biāo)準(zhǔn)進(jìn)行數(shù)據(jù)序列化的 C++ 庫。 -
fastrtps,eProsima Fast DDS庫的核心庫。 -
fastddsgen,一個(gè)使用 IDL 文件中定義的數(shù)據(jù)類型生成源代碼的 Java 應(yīng)用程序。
如果這些組件中的任何一個(gè)不需要,可以簡單地重命名或從src 目錄中刪除。
2.2 安裝步驟
注意編譯需要CMake3.11以上的版本,安裝編譯需要時(shí)間比較久,大概15分鐘(8代i7編譯)。
下載該安裝包到Download目錄后,解壓縮至新建文件夾并安裝
cd Download
mkdir fastdds2.8.1
tar -zxvf eProsima_Fast-DDS-v2.8.1-Linux.tgz -C fastdds2.8.1/
sudo ./install.sh
注意,如果要測(cè)試FastDDS中的examples,需要在install.sh腳本腳本中打開該選項(xiàng),默認(rèn)為OFF。

install.sh腳本首先安裝各種依賴,包括git、build-essential、cmake、libssl-dev、libasio-dev、libtinyxml2-dev、openjdk-8-jre-headless。

接著install.sh腳本編譯安裝foonathan_memory_vendor。

然后install.sh腳本編譯安裝fastcdr。

隨后install.sh腳本編譯安裝fastrtps(Fast DDS)。

最后install.sh腳本拷貝fastddsgen二進(jìn)制文件到系統(tǒng)目錄中。

2.3 測(cè)試
- IDL文件生成接口文件
git clone 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選項(xiàng)指示生成的頭文件保存目錄
- 編譯FastDDS的程序
根據(jù)IDL文件生成接口文件后,同一個(gè)終端內(nèi)接著編譯FastDDS程序。
cd ..
mkdir build && cd build
cmake ..
make
- 運(yùn)行Publisher和Subscriber
cd build/
./DDSHelloWorldPublisher
cd build/
./DDSHelloWorldSubscriber
可以看到終端輸出

2.4 添加環(huán)境變量
如果2.3步驟可以正常執(zhí)行,不需要再手動(dòng)添加環(huán)境變量了。
當(dāng)使用eProsima Fast DDS運(yùn)行應(yīng)用程序?qū)嵗龝r(shí),它必須與安裝包的庫鏈接,可以臨時(shí)添加環(huán)境變量
export LD_LIBRARY_PATH=/usr/local/lib/
也可以永久添加
echo 'export LD_LIBRARY_PATH=/usr/local/lib/' >> ~/.bashrc
2.5 卸載
該安裝包同樣提供/uninstall.sh卸載腳本,直接執(zhí)行該腳本即可:
cd fastddss2.8.1
sudo ./uninstall.sh
注意:如果任何其他組件已經(jīng)以某種其他方式安裝在系統(tǒng)中,它們也將被刪除。為避免這種情況,請(qǐng)?jiān)趫?zhí)行之前編輯./uninstall.sh腳本。
三、FastDDS使用
3.1 創(chuàng)建CMake工程項(xiàng)目
新建一個(gè)CMake工程項(xiàng)目,在fastdds_helloworld目錄中創(chuàng)建idl文件夾、src文件夾和include文件夾,接著在include文件夾中創(chuàng)建idl_generate文件夾。
mkdir -p fastdds_helloworld/src
cd fastdds_helloworld
mkdir idl
mkdir -p include/idl_generate
工作區(qū)目錄結(jié)構(gòu)如下,

其中idl文件夾存放idl文件,include/idl_generate文件夾存放idl文件生成的頭文件。
3.2 編寫IDL文件
3.2.1 定義IDL數(shù)據(jù)類型
創(chuàng)建IDL文件
cd idl && touch HelloWorld.idl
定義 HelloWorld 數(shù)據(jù)類型,它有兩個(gè)元素:
- 類型為
uint32_t的index - 類型為
std::string的message
struct HelloWorld
{
unsigned long index;
string message;
};
3.2.2 生成定義數(shù)據(jù)類型的源代碼
接著利用fastdds的工具fastddsgen,生成在 C++中實(shí)現(xiàn)此數(shù)據(jù)類型的源代碼,在idl/ 目錄運(yùn)行以下命令:
fastddsgen -d ./../include/idl_generate/ HelloWorld.idl
其中-d選項(xiàng)指定生成源代碼存放的目錄路徑./../include/idl_generate/。
fastddsgen是一個(gè)Java應(yīng)用程序(已經(jīng)在前述安裝步驟中成功安裝),用來解析idl文件,生成數(shù)據(jù)類型定義的的源代碼。
3.2.3 生成類型源碼解析
fastddsgen工具會(huì)為HelloWorld.idl文件生成四個(gè)文件,分別是
HelloWorld.hHelloWorld.cxxHelloWorldPubSubTypes.hHelloWorldPubSubTypes.cxx
其中HelloWorld.h,HelloWorld.cxx中會(huì)根據(jù)idl文件中定義的結(jié)構(gòu)體生成對(duì)應(yīng)的類,即 類型定義:
class HelloWorld
{
public:
****
private:
uint32_t m_index;
std::string m_message;
};
其中HelloWorldPubSubTypes.h,HelloWorldPubSubTypes.cxx文件在定義HelloWorld類的基礎(chǔ)上添加了一些了對(duì)HelloWorld 類型的序列化和反序列化代碼:
#include "HelloWorld.h"
class HelloWorldPubSubType : public eprosima::fastdds::dds::TopicDataType
{
public:
typedef HelloWorld type;
eProsima_user_DllExport HelloWorldPubSubType();
eProsima_user_DllExport virtual ~HelloWorldPubSubType() override;
***
unsigned char* m_keyBuffer;
};
3.3 Publisher代碼
在3.1節(jié)的基礎(chǔ)上,利用fastdds實(shí)現(xiàn)一個(gè)Publisher還需要以下三個(gè)步驟:
- 包含頭文件
- 實(shí)現(xiàn)
Publisher的類 - 實(shí)例化
Publisher并發(fā)布數(shù)據(jù)
其中實(shí)現(xiàn)Publisher的類是核心!
3.3.1 頭文件
3.3.1.1 包含數(shù)據(jù)類型頭文件
包含HelloWorldPubSubTypes.h文件,該文件定義了數(shù)據(jù)類型的序列化和反序列化函數(shù),并且已經(jīng)包含了數(shù)據(jù)類型定義的頭文件#include "HelloWorld.h"。
#include "HelloWorldPubSubTypes.h"
3.3.1.2 包含F(xiàn)astDDS頭文件
這些頭文件提供了使用 Fast DDS的API。
#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>
-
DomainParticipantFactory:允許創(chuàng)建和銷毀 DomainParticipant 對(duì)象。 -
DomainParticipant:充當(dāng)所有其他實(shí)體對(duì)象的容器,并充當(dāng)發(fā)布者、訂閱者和主題對(duì)象的工廠。 -
TypeSupport:為participant提供序列化、反序列化和獲取特定數(shù)據(jù)類型的key的函數(shù)。 -
Publisher:是負(fù)責(zé)創(chuàng)建 DataWriter的對(duì)象。 -
DataWriter:允許應(yīng)用程序設(shè)置要在給定主題下發(fā)布的數(shù)據(jù)的值。 -
DataWriterListener:允許重新定義 DataWriterListener 的功能。
3.3.1.3 命名空間
添加在應(yīng)用程序中使用的eProsima Fast DDS 類和函數(shù)的命名空間。
using namespace eprosima::fastdds::dds;
3.3.2 創(chuàng)建Publisher類
fastdds根據(jù)DDS規(guī)范提供了相應(yīng)概念的類定義,如DomainParticipant,Publisher,Topic和DataWriter等。
在使用這些實(shí)體類之前,需要理解這些實(shí)體類之間的關(guān)系,根據(jù)下圖進(jìn)行分析。

fastdds對(duì)這些DDS概念實(shí)例化是分層的,這些實(shí)體之間的關(guān)系如下圖:

fastdds提供DomainParticipant類創(chuàng)建participant
topic是由participant創(chuàng)建和管理,創(chuàng)建時(shí)設(shè)置topic的名稱和綁定對(duì)應(yīng)得數(shù)據(jù)類型以及Qos配置。
datawriter是由publisher創(chuàng)建和管理的,datawriter是負(fù)責(zé)往topic上寫數(shù)據(jù)的。publisher在創(chuàng)建datawriter時(shí)會(huì)將對(duì)應(yīng)的topic綁定到datawriter上。
每個(gè)participant最多只能擁有一個(gè)publisher,而一個(gè)publisher可以管理多個(gè)datawriter,對(duì)于不同的datawriter而言,Publisher是公共的。
3.3.2.1 類定義與成員變量聲明
定義HelloWorldPublisher類,并聲明類成員變量
class HelloWorldPublisher
{
private:
HelloWorld hello_;
DomainParticipant* participant_;
Publisher* publisher_;
Topic* topic_;
DataWriter* writer_;
TypeSupport type_;
-
DomainParticipant:充當(dāng)所有其他實(shí)體對(duì)象的容器,并充當(dāng)發(fā)布者、訂閱者和主題對(duì)象的工廠。 -
Publisher:是負(fù)責(zé)創(chuàng)建 DataWriter的對(duì)象。 -
DataWriter:允許應(yīng)用程序設(shè)置要在給定主題下發(fā)布的數(shù)據(jù)的值。 -
TypeSupport:為participant提供序列化、反序列化和獲取特定數(shù)據(jù)類型的key的函數(shù)。 -
DataWriterListener:允許重新定義 DataWriterListener 的功能。
3.3.2.2 創(chuàng)建participant
利用DomainParticipantFactory創(chuàng)建participant,participant所在的Domain ID為0,采用默認(rèn)的participantQos策略。
DomainParticipantQos participantQos;
participantQos.name("Participant_publisher");
participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);
-
DomainParticipantFactory:允許創(chuàng)建和銷毀 DomainParticipant 對(duì)象。
3.3.2.3 register數(shù)據(jù)類型并創(chuàng)建topic
IDL接口文件中定義的數(shù)據(jù)類型需要在participant中注冊(cè),把數(shù)據(jù)類型注冊(cè)到participant上,這樣participant在創(chuàng)建topic時(shí),才能使用該數(shù)據(jù)類型。
type_ = new HelloWorldPubSubType()
type_.register_type(participant_);
topic_ = participant_->create_topic("HelloWorldTopicName", "HelloWorld", TOPIC_QOS_DEFAULT);
participant根據(jù)默認(rèn)Qos參數(shù)TOPIC_QOS_DEFAULT創(chuàng)建topic。
type_變量的值是IDL接口文件中數(shù)據(jù)類型。
type_是TypeSupport類型,可以為participant提供序列化、反序列化和獲取特定數(shù)據(jù)類型的key的函數(shù)。
3.3.2.4 創(chuàng)建publisher
participant根據(jù)PUBLISHER_QOS_DEFAULT創(chuàng)建publisher。
publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);
3.3.2.5 創(chuàng)建writer
publisher根據(jù)DATAWRITER_QOS_DEFAULT通過先前創(chuàng)建的listener_進(jìn)而創(chuàng)建datawtriter。
writer_ = publisher_->create_datawriter(topic_, DATAWRITER_QOS_DEFAULT, &listener_);
3.3.3 使用Publisher對(duì)象發(fā)送數(shù)據(jù)
HelloWorldPublisher類需要定義publish和run兩個(gè)函數(shù),前者是將數(shù)據(jù)發(fā)布出去,后者可以限定指定條件,如定時(shí)發(fā)送等,這樣設(shè)計(jì)更加利于程序后期的拓展性。
3.3.3.1 publish函數(shù)
publisher發(fā)布數(shù)據(jù)實(shí)際是調(diào)用datawriter的write函數(shù)將數(shù)據(jù)發(fā)送出去。
bool publish()
{
hello_.index(hello_.index() + 1);
if (writer_->write(&hello_))
return true;
return false;
}
3.3.3.2 run函數(shù)
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));
}
}
上述的demo代碼有兩個(gè)缺陷,data是private,外部無法修改變量。
應(yīng)該在publish函數(shù)中接收更新后的數(shù)據(jù)然后發(fā)布出去。
publisher類中是否要定義數(shù)據(jù)類型還是僅僅定義類型的指針???
PubListener這個(gè)類中的matched_表示與該datawriter通過topic建立連接的subscriber的數(shù)量,當(dāng)新建連接或斷開連接時(shí),就會(huì)觸發(fā)on_publication_matched()回調(diào)函數(shù),demo中利用該回調(diào)打印輸出,提示連接的建立與否。
可以通過matched_參數(shù)判斷是否有DataReader建立連接,若有才publish,沒有就不發(fā)布。
程序結(jié)束時(shí),清理內(nèi)存,銷毀的時(shí)候也是分層,從下往上,先銷毀datawriter,然后是publisher以及同級(jí)的topic,最后是participant
3.4 Subscriber代碼
3.4.1 頭文件
3.4.1.1 包含數(shù)據(jù)類型頭文件
包含HelloWorldPubSubTypes.h文件,該文件定義了數(shù)據(jù)類型的序列化和反序列化函數(shù),并且已經(jīng)包含了數(shù)據(jù)類型定義的頭文件#include "HelloWorld.h"。
#include "HelloWorldPubSubTypes.h"
3.4.1.2 包含F(xiàn)astDDS頭文件
這些頭文件提供了使用 Fast DDS的API。
#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>
-
DomainParticipantFactory:允許創(chuàng)建和銷毀 DomainParticipant 對(duì)象。 -
DomainParticipant:充當(dāng)所有其他實(shí)體對(duì)象的容器,并充當(dāng)發(fā)布者、訂閱者和主題對(duì)象的工廠。 -
TypeSupport:為participant提供序列化、反序列化和獲取特定數(shù)據(jù)類型的key的函數(shù)。 -
Subscriber:它是負(fù)責(zé)創(chuàng)建和配置 DataReader 的對(duì)象。 -
DataReader:它是負(fù)責(zé)實(shí)際接收數(shù)據(jù)的對(duì)象。它在應(yīng)用程序中注冊(cè)標(biāo)識(shí)要讀取的數(shù)據(jù)的主題(TopicDescription),并訪問訂閱者接收到的數(shù)據(jù)。 -
DataReaderListener:這是分配給數(shù)據(jù)讀取器的偵聽器。 -
DataReaderQoS:定義 DataReader 的 QoS 的結(jié)構(gòu)。 -
SampleInfo:“read”或“taken”的是每個(gè)SampleInfo附帶的信息。
3.4.1.3 命名空間
添加在應(yīng)用程序中使用的eProsima Fast DDS 類和函數(shù)的命名空間。
using namespace eprosima::fastdds::dds;
3.4.2 創(chuàng)建Subscriber類
與Publisher類類似。
fastdds根據(jù)DDS規(guī)范提供了相應(yīng)概念的類定義,如DomainParticipant,Subscriber,Topic和DataReader等。
在使用這些實(shí)體類之前,需要理解這些實(shí)體類之間的關(guān)系,根據(jù)下圖進(jìn)行分析。

fastdds對(duì)這些DDS概念實(shí)例化是分層的,這些實(shí)體之間的關(guān)系如下圖:

fastdds提供DomainParticipant類創(chuàng)建participant
topic是由participant創(chuàng)建和管理,創(chuàng)建時(shí)設(shè)置topic的名稱和綁定對(duì)應(yīng)得數(shù)據(jù)類型以及Qos配置。
datareader是由subscriber創(chuàng)建和管理的,datareader是負(fù)責(zé)讀topic上的數(shù)據(jù)。subscriber在創(chuàng)建datareader時(shí)會(huì)將對(duì)應(yīng)的topic綁定到datareader上。
每個(gè)participant最多只能擁有一個(gè)subscriber,而一個(gè)subscriber可以管理多個(gè)datareader,對(duì)于不同的datareader而言,subscriber是公共的。
3.4.2.1 類定義與成員變量聲明
定義HelloWorldSubscriber類,并聲明類成員變量
class HelloWorldSubscriber
{
private:
DomainParticipant* participant_;
Subscriber* subscriber_;
Topic* topic_;
DataReader* reader_;
TypeSupport type_;
class SubListener : public DataReaderListener
{
HelloWorld hello_;
***
} listener_;
***
}
-
DomainParticipant:充當(dāng)所有其他實(shí)體對(duì)象的容器,并充當(dāng)發(fā)布者、訂閱者和主題對(duì)象的工廠。 -
Subscriber:是負(fù)責(zé)創(chuàng)建 DataReader 的對(duì)象。 -
DataReader:它是負(fù)責(zé)實(shí)際接收數(shù)據(jù)的對(duì)象。 -
TypeSupport:為participant提供序列化、反序列化和獲取特定數(shù)據(jù)類型的key的函數(shù)。 -
DataReaderListener:這是分配給數(shù)據(jù)讀取器的偵聽器。
注意:這里的HelloWorld數(shù)據(jù)類型變量的聲明是在SubListener子類中定義的,并不是在HelloWorldSubscriber類中定義。
上述變量聲明中最核心的是聲明了一個(gè)listener_變量,該變量是SubListener子類的實(shí)例化對(duì)象。
SubListener子類公共繼承DataReaderListener類,從而可以在datareader和datawriter建立連接以及接收到新數(shù)據(jù)等事件時(shí)觸發(fā)相應(yīng)的回調(diào)函數(shù),進(jìn)而在SubListener子類內(nèi)部執(zhí)行相應(yīng)的處理邏輯。
3.4.2.2 創(chuàng)建participant
利用DomainParticipantFactory創(chuàng)建participant,participant所在的Domain ID為0,采用默認(rèn)的participantQos策略。
DomainParticipantQos participantQos;
participantQos.name("Participant_subscriber");
participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);
3.4.2.3 register數(shù)據(jù)類型并創(chuàng)建topic
IDL接口文件中定義的數(shù)據(jù)類型需要在participant中注冊(cè),把數(shù)據(jù)類型注冊(cè)到participant上,這樣participant在創(chuàng)建topic時(shí),才能使用該數(shù)據(jù)類型。
type_ = new HelloWorldPubSubType()
type_.register_type(participant_);
topic_ = participant_->create_topic("HelloWorldTopicName", "HelloWorld", TOPIC_QOS_DEFAULT);
3.4.2.4 創(chuàng)建subscriber
participant根據(jù)SUBSCRIBER_QOS_DEFAULT創(chuàng)建subscriber。
subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);
3.4.2.5 創(chuàng)建reader
subscriber根據(jù)DATAREADER_QOS_DEFAULT通過先前創(chuàng)建的listener_進(jìn)而創(chuàng)建datareader。
reader_ = subscriber_->create_datareader(topic_, DATAREADER_QOS_DEFAULT, &listener_);
3.4.3 使用Subscriber對(duì)象接收數(shù)據(jù)
class HelloWorldSubscriber
{
private:
***
class SubListener : public DataReaderListener
{
HelloWorld hello_;
***
} listener_;
***
}
上述變量聲明中最核心的是聲明了一個(gè)listener_變量,該變量是SubListener子類的實(shí)例化對(duì)象。
SubListener子類公共繼承DataReaderListener類,從而可以在datareader和datawriter建立連接以及接收到新數(shù)據(jù)等事件時(shí)觸發(fā)相應(yīng)的回調(diào)函數(shù),進(jìn)而在SubListener子類內(nèi)部執(zhí)行相應(yīng)的處理邏輯。
SubListener子類的第一個(gè)覆蓋(override)回調(diào)函數(shù)是 on_subscription_matched,當(dāng)datareader和datawriter建立連接時(shí),會(huì)觸發(fā)該回調(diào)函數(shù)。
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;
}
}
第二個(gè)覆蓋(override)回調(diào)函數(shù)是on_data_available,當(dāng)datareader接收到datawriter發(fā)送的新數(shù)據(jù)時(shí),會(huì)觸發(fā)該回調(diào)函數(shù)。
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;
}
}
}
這里定義了SampleInfo類的對(duì)象info,它確定新收到的數(shù)據(jù)狀態(tài),如數(shù)據(jù)是否已被讀取或采集。
3.5 CMakeList.txt
3.5.1 新建工程
cmake_minimum_required(VERSION 3.12.4)
project(DDSHelloWorld)
add_compile_options(-std=c++11)
在官方給的demo示例中,添加了C++版本至少為11,實(shí)際測(cè)試中去掉此項(xiàng)仍可正常編譯通過。
3.5.2 添加依賴
find_package(fastcdr REQUIRED)
find_package(fastrtps REQUIRED)
使用FastDDS只需要依賴fastcdr和fastrtps兩個(gè)庫即可,這兩個(gè)庫根據(jù)前面的安裝步驟,安裝在了/usr/local/share下。
3.5.3 生成IDL數(shù)據(jù)類型的庫文件
file(GLOB DDS_HELLOWORLD_SOURCES_CXX "./include/idl_generate/*.cxx")
add_library(HelloWorld_IDL_lib ${DDS_HELLOWORLD_SOURCES_CXX})
利用CMake中的file命令,將數(shù)據(jù)類型的源碼文件列表保存在CMake變量中,然后將fastddsgen生成的這些數(shù)據(jù)類型源碼編譯生成靜態(tài)庫文件。
將數(shù)據(jù)類型單獨(dú)編譯,能解耦可執(zhí)行文件編譯時(shí)源碼和類型文件一起編譯,有助于提高編譯效率,僅需要在運(yùn)行時(shí)鏈接數(shù)據(jù)類型的庫文件即可。
3.5.4 生成可執(zhí)行文件
# Publisher
add_executable(DDSHelloWorldPublisher src/HelloWorldPublisher.cpp)
target_link_libraries(DDSHelloWorldPublisher
HelloWorld_IDL_lib
fastrtps
fastcdr
)
# Subscriber
add_executable(DDSHelloWorldSubscriber src/HelloWorldSubscriber.cpp)
target_link_libraries(DDSHelloWorldSubscriber
HelloWorld_IDL_lib
fastrtps
fastcdr
)
生成Publisher和Subscriber可執(zhí)行文件。
參考:
官方C++版helloworld:https://fast-dds.docs.eprosima.com/en/v2.3.3/fastdds/getting_started/simple_app/simple_app.html
官方python版helloworld:https://fast-dds.docs.eprosima.com/en/v2.3.3/fastddsgen/pubsub_app/pubsub_app.html#fastddsgen-pubsub-app
官方快速開始教程:https://fast-dds.docs.eprosima.com/en/latest/fastdds/getting_started/getting_started.html
官方二進(jìn)制安裝教程:https://fast-dds.docs.eprosima.com/en/latest/installation/binaries/binaries_linux.html
官方代碼helloworld示例:https://github.com/eProsima/Fast-DDS-docs/blob/master/code/Examples
魚香ros的cmake工程:https://github.com/fishros/dds_tutorial
靜態(tài)編譯的cmake工程:https://blog.csdn.net/briblue/article/details/124081170
fastdds的helloworld代碼解釋:https://blog.csdn.net/u012739527/article/details/124705821
eProsima Fast DDS-Gen介紹:https://fast-dds.docs.eprosima.com/en/latest/fastddsgen/introduction/introduction.html
待做:
fastdds如何通過同一個(gè)類使用不同類型的數(shù)據(jù)接口,利用模板類?
是否已有一些基本類型可供fastdds的程序使用,不用自己新建idl文件?
fastdds的subscriber必須在listener中編寫回調(diào)函數(shù)么,不能像ROS一樣,在創(chuàng)建topic時(shí)綁定回調(diào)函數(shù)?
動(dòng)態(tài) HelloWorld 示例學(xué)習(xí):https://fast-dds.docs.eprosima.com/en/latest/fastdds/dynamic_types/examples.html
動(dòng)態(tài)主題類型:https://fast-dds.docs.eprosima.com/en/latest/fastdds/dynamic_types/dynamic_types.html