【OpenDDS开发指南V3.20】第一章:介绍
OpenDDS 是用于實時系統規范 v1.4(OMG Document formal/2015-04-10)的 OMG 數據分發服務 (DDS) 和實時發布訂閱有線協議DDS Interoperability Wire Protocol Specificatio (DDSI- RTPS)v2.3(OMG Document formal/2019-04-03)。
OpenDDS 還實現了 DDS 安全規范 v1.1(OMG Document formal/2018-04-01)和 DDS XTypes v1.3(OMG Document formal/2020-02-04)。
OpenDDS 由 Object Computing, Inc. (OCI) 贊助,可在 https://www.opendds.org/ 獲得。本開發人員指南基于 OpenDDS 的 3.20 版本。
DDS 定義了一種服務,用于在分布式應用程序的參與者之間有效地分發應用程序數據。此服務不綁定到 CORBA。該規范提供了一個平臺獨立模型 (PIM) 以及一個將 PIM 映射到 OMG IDL 實現的平臺特定模型 (PSM)。
有關 DDS 的更多詳細信息,開發人員應參考 DDS 規范(OMG Document formal/2015-04-10),因為它包含對所有服務功能的深入介紹。
注意:OpenDDS 當前實現了 OMG DDS 1.4 版規范。 有關更多信息,請參閱 https://www.opendds.org/ 中的合規信息。
DCPS 概述
在本節中,我們將介紹 DCPS 層的主要概念和實體,并討論它們如何交互和協同工作。
基本概念
圖 1-1 顯示了 DDS DCPS 層的概覽。 以下小節定義了此圖中顯示的概念。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VcUUwFh1-1652410199857)(https://note.youdao.com/yws/res/2874/WEBRESOURCE8b0550fd5df1608881ecff7b6d1cbb7d)]
Domain(域)
Domain是 DCPS 中的基本劃分單元。
每個其他實體都屬于一個Domain,并且只能與同一Domain中的其他實體交互。
應用程序代碼可以自由地與多個Domain交互,但必須通過屬于不同Domain的單獨實體來進行。
DomainParticipant(域參與者)
域參與者是應用程序在特定域中交互的入口點。
域參與者是許多涉及寫入或讀取數據的對象的工廠。
Topic
主題是發布和訂閱應用程序之間交互的基本方式。
每個主題在域中都有一個唯一的名稱和它發布的特定數據類型。
每個主題數據類型都可以指定零個或多個構成其鍵的字段。發布數據時,發布過程始終指定主題。 訂閱者通過主題請求數據。
在 DCPS 術語中,您針對某個主題的不同實例發布單獨的數據樣本。每個實例都與鍵的唯一值相關聯。 發布過程通過對每個樣本使用相同的鍵值,在同一實例上發布多個數據樣本。
DataWriter
發布應用程序代碼使用數據寫入器將值傳遞給 DDS。每個數據編寫器都綁定到一個特定的主題。
應用程序使用數據編寫器的類型特定接口發布關于該主題的示例。 數據寫入者負責編組數據并將其傳遞給發布者進行傳輸。
Publisher(發布者)
發布者負責獲取發布的數據并將其傳播給域中的所有相關訂閱者。 所采用的確切機制留給服務實現。
Subscriber(訂閱者)
訂閱者從發布者接收數據并將其傳遞給與其連接的任何相關數據讀取器。
DataReader(數據讀取器)
數據讀取器從訂閱者那里獲取數據,將其分解為適合該主題的類型,然后將樣本交付給應用程序。 每個數據閱讀器都綁定到一個特定的主題。 應用程序使用數據讀取器的特定類型接口來接收樣本。
Built-In Topics(內置主題)
DDS 規范定義了許多內置于 DDS 實現的主題。
訂閱這些內置主題使應用程序開發人員可以訪問正在使用的域的狀態,包括注冊了哪些主題、連接和斷開了哪些數據讀取器和數據寫入器,以及各種實體的 QoS 設置。
訂閱時,應用程序會收到指示域內實體更改的樣本。 下表顯示了 DDS 規范中定義的內置主題:
| DCPSParticipant | 每個實例代表一個域參與者 |
| DCPSTopic | 每個實例代表一個普通(非內置)主題 |
| DCPSPublication | 每個實例代表一個數據寫入器 |
| DCPSSubscription | 每個實例代表一個數據讀取器 |
服務質量政策
DDS 規范定義了許多服務質量 (QoS) 策略,應用程序使用這些策略來指定其對服務的 QoS 要求。
參與者指定他們需要從服務中獲得什么行為,而服務決定如何實現這些行為。
這些策略可以應用于各種 DCPS實體(主題、數據寫入器、數據讀取器、發布者、訂閱者、域參與者),盡管并非所有策略都對所有類型的實體都有效。
訂閱者和發布者使用請求與提供 (RxO) 模型進行匹配。
訂閱者請求一組最低要求的策略。 發布者向潛在訂閱者提供一組 QoS 策略。 然后,DDS 實現嘗試將請求的策略與提供的策略匹配; 如果這些策略是兼容的,那么就形成了關聯。
OpenDDS 目前實施的策略將在第 3 章詳細討論。
監聽
DCPS 層為每個實體定義了一個回調接口,允許應用程序進程“監聽”與該實體相關的某些狀態更改或事件。 例如,當有數據值可供讀取時,會通知數據讀取器偵聽器。
條件
條件和等待集允許在 DDS 中檢測感興趣的事件時替代偵聽器。
一般模式是應用程序創建特定類型的 Condition 對象,例如 StatusCondition,并將其附加到 WaitSet。
-
應用程序在 WaitSet 上等待,直到一個或多個條件變為真。
-
應用程序調用對相應實體對象的操作以提取必要的信息。
-
DataReader 接口還具有采用ReadCondition 參數的操作。
-
QueryCondition 對象作為 ContentSubscription Profile 實現的一部分提供。 QueryCondition 接口擴展了 ReadCondition 接口。
penDDS 實施
規范
OpenDDS 符合 OMG DDS 和 OMG DDSI-RTPS 規范。
該合規性的詳細信息如下。 OpenDDS 還實現了 OMG DDS 安全規范。 符合該規范的詳細信息在第 14.8 節中。
XTypes 合規性的詳細信息在第 16.8 和 16.9 節中。
DDS 規范
DDS 規范的第 2 節定義了 DDS 實施的五個合規點:
OpenDDS 符合整個 DDS 規范(包括所有可選配置文件)。 這包括實施所有服務質量政策,并附有以下說明:
- RELIABILITY.kind = RELIABLE 受RTPS_UDP 傳輸、TCP 傳輸或IP 多播傳輸(配置為可靠時)支持。
- TRANSPORT_PRIORITY 未實現為可更改的。 盡管 DDS 規范的 1.5 版尚未發布,但 OpenDDS 包含了為該版本計劃的一些更改,這些更改是穩健實施所需的:
- DDS15-257:IDL 類型 BuiltinTopicKey_t 是一個包含
16 個八位字節的數組
- DDS15-257:IDL 類型 BuiltinTopicKey_t 是一個包含
DDSI-RTPS 規范
OpenDDS 實現符合 OMG DDSI-RTPS 規范的要求。
OpenDDS RTPS 實施說明
OMG DDSI-RTPS 規范(formal/2019-04-03)提供了實施聲明,但并非合規性要求。 在使用 OpenDDS RTPS 功能進行傳輸和/或發現時,應考慮以下事項。
DDSI-RTPS 規范的章節編號隨每個項目一起提供,以供進一步參考。
OpenDDS 中未實現的項目:
OpenDDS 可能仍然會丟棄任何相關閱讀器不需要的樣本(由于內容過濾)——這是在傳輸層之上完成的
– OpenDDS 將使用 Directed Write 參數,如果它出現在傳入消息中(例如,由不同 DDS 實現生成的消息)
IDL 規范
OMG IDL 在 OpenDDS 代碼庫和下游以幾種不同的方式使用
使用它的地方:
- OpenDDS 附帶的文件(例如 dds/DdsDcpsTopic.idl)定義了中間件庫和應用程序之間的 API 部分。 這稱為 OMG IDL 平臺特定模型 (PSM)。
- 除了 C++ 或 Java 的源代碼文件之外,OpenDDS 的用戶還可以編寫 IDL 文件。
本節只描述后者的使用。
IDL 規范(4.2 版)使用術語“構建塊”來定義某些工具可能支持的整個 IDL 語法的子集。
OpenDDS 支持以下構建塊,下面列出了注釋/警告:
- 核心數據類型
- 對“固定”數據類型(定點小數)的支持不完整。
- 匿名類型
- 當匿名類型作為序列/數組實例直接作為結構字段類型出現時,對匿名類型的支持有限。 建議使用顯式命名的類型。
- 注釋
- 有關支持的內置注釋的詳細信息,請參閱第 2.1.1 和 16.6 節。
- 還支持用戶定義的注釋類型。
- 擴展數據類型
- 整數類型 int8、int16、int32 和 int64 以及無符號版本
- 支持它們,例如 uint32。
- 不支持構建塊的其余部分。
DDS 規范的擴展
DDS IDL 模塊(C++ 命名空間、Java 包)中的數據類型、接口和常量直接對應于 DDS 規范,只有極少數例外:
? DDS::SampleInfo 包含一個以“opendds_reserved”開頭的額外字段
? 特定類型的DataReader(包括那些用于內置主題的)具有額外的操作read_instance_w_condition() 和take_instance_w_condition()。
OpenDDS 模塊/命名空間/包中的各種類和接口提供了額外的擴展行為。 其中包括 Recorder 和 Replayer 等功能(參見第 12 章)以及:
? OpenDDS::DCPS::TypeSupport 添加了 DDS 規范中沒有的 unregister_type() 操作。
? OpenDDS::DCPS::ALL_STATUS_MASK、NO_STATUS_MASK 和 DEFAULT_STATUS_MASK 是 DDS::Entity、DDS::StatusCondition 和各種 create_*() 操作使用的 DDS::StatusMask 類型的有用常量。
OpenDDS 架構
本節簡要概述了 OpenDDS 的實現、它的特性以及它的一些組件。 $DDS_ROOT 環境變量應該指向 OpenDDS 發行版的基本目錄。 OpenDDS 的源代碼可以在 $DDS_ROOT/dds/ 目錄下找到。 DDS 測試可以在 $DDS_ROOT/tests/ 下找到。
設計理念
OpenDDS 實現和 API 基于對 OMG IDL PSM 的相當嚴格的解釋。
在幾乎所有情況下,OMG 的 IDL-to-C++ 語言映射都用于定義 DDS 規范中的 IDL 如何映射到 OpenDDS 向客戶端公開的 C++ API。
與 OMG IDL PSM 的主要偏差是本地接口用于實體和各種其他接口。 這些在 DDS 規范中被定義為不受約束的(非本地)接口。 將它們定義為本地接口可以提高性能,減少內存使用,簡化客戶端與這些接口的交互,并使客戶端更容易構建自己的實現.
可擴展傳輸框架 (ETF)
OpenDDS 使用 DDS 規范定義的 IDL 接口來初始化和控制服務的使用。
數據傳輸是通過特定于 OpenDDS 的傳輸框架完成的,該框架允許服務與各種傳輸協議一起使用。
這被稱為可插拔傳輸,并使 OpenDDS 的可擴展性成為其架構的重要組成部分。 OpenDDS 目前支持 TCP/IP、UDP/IP、IP 多播、共享內存和 RTPS_UDP 傳輸協議,如圖 1-2 所示。
傳輸通常通過配置文件指定,并附加到發布者和訂閱者進程中的各種實體。 有關配置 ETF 組件的詳細信息,請參閱第 7.4.4 節
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-iJVPmlo9-1652410199858)(https://note.youdao.com/yws/res/2971/WEBRESOURCE0f1e9d5a37f72b244d07554ab3b0cd27)]
ETF 使應用程序開發人員能夠實現他們自己的定制傳輸。 實現自定義傳輸涉及專門化傳輸框架中定義的許多類。
udp 傳輸提供了開發人員在創建自己的實現時可以使用的良好基礎。 有關詳細信息,請參閱 $DDS_ROOT/dds/DCPS/transport/udp/ 目錄。
DDS Discovery
DDS 應用程序必須通過某個中央代理或某個分布式方案來發現彼此。
OpenDDS 的一個重要特性是 DDS 應用程序可以配置為使用 DCPSInfoRepo 或 RTPS 發現來執行發現,但在數據寫入器和數據讀取器之間使用不同的傳輸類型進行數據傳輸。
DDS 規范(正式/2015-04-10)將發現的細節留給實現。
在 DDS 實現之間的互操作性的情況下,OMG DDSI-RTPS(正式/2014-09-01)規范提供了對等發現風格的要求。
OpenDDS 提供了兩個發現選項:
DCPSInfoRepo 的集中式發現
OpenDDS 實現了一個名為 DCPS 信息存儲庫 (DCPSInfoRepo) 的獨立服務來實現集中式發現方法。
它被實現為 CORBA 服務器。
當客戶請求訂閱某個主題時,DCPS 信息庫會定位該主題并通知任何現有發布者新訂閱者的位置。每當在非 RTPS 配置中使用 OpenDDS 時,都需要運行 DCPSInfoRepo 進程。
RTPS 配置不使用 DCPSInfoRepo。 DCPSInfoRepo 不參與數據傳播,其作用僅限于發現彼此的 OpenDDS 應用程序。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-b68Jxii6-1652410199858)(https://note.youdao.com/yws/res/2983/WEBRESOURCEb3ef55e501340bf47c2752d76a29db3f)]
應用程序開發人員可以自由運行多個信息存儲庫,每個存儲庫管理自己的非重疊 DCPS 域集。
還可以使用多個存儲庫來操作域,從而形成分布式虛擬存儲庫。 這稱為存儲庫聯合。 為了讓各個存儲庫參與聯合,每個存儲庫都必須在啟動時指定自己的聯合標識符值(32 位數值)。 有關存儲庫聯合的更多信息,請參見 9.2。
使用 RTPS 的點對點發現
OpenDDS 功能可以滿足需要對等發現模式的 DDS 應用程序。
這種發現方式只能通過使用當前版本的 RTPS 協議來完成。
這種簡單的發現形式是通過對運行在應用程序進程中的 DDS 應用程序數據讀取器和數據寫入器的簡單配置來完成的,如圖 1-4 所示。
當每個參與進程為其數據讀取器和寫入器激活 OpenDDS 中的 DDSI-RTPS 發現機制時,使用默認或配置的網絡端口創建網絡端點,以便 DDS 參與者可以開始宣傳其數據讀取器和數據寫入器的可用性。
一段時間后,那些根據標準相互尋找的人將找到彼此,并根據可擴展傳輸框架 (ETF) 中討論的配置的可插拔傳輸建立連接。在第 7.4.1.1 節和第 7.4.5.5 節中討論了這種靈活配置方法的更詳細描述。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dGl90RQQ-1652410199858)(https://note.youdao.com/yws/res/2991/WEBRESOURCE97d86e139a72c587a19c7a3ec93069db)]
以下是開發人員在開發和部署使用 RTPS 發現的應用程序時需要考慮的其他實施限制:
有關 RTPS 發現如何發生的更多詳細信息,可以在實時發布-訂閱有線協議 DDS 互操作性有線協議規范 (DDSI-RTPS) v2.2 的第 8.5 節中找到非常好的閱讀參考(OMG 文件正式/2014-09-01)。
Threading
OpenDDS 創建自己的 ORB(當需要時)以及運行該 ORB 的單獨線程。
它還使用自己的線程來處理傳入和傳出的傳輸 I/O。創建一個單獨的線程以在意外連接關閉時清理資源。
您的應用程序可能會通過 DCPS 的偵聽器機制從這些線程中回調。通過 DDS 發布樣本時,OpenDDS 通常會嘗試使用調用線程將樣本發送給任何連接的訂閱者。如果發送調用阻塞,則樣本可能會排隊等待在單獨的服務線程上發送。此行為取決于第 3 章中描述的 QoS 策略。
訂閱者中的所有傳入數據都由服務線程讀取,并排隊等待應用程序讀取。從服務線程調用 DataReader 偵聽器。
配置
OpenDDS 包括一個基于文件的配置框架,用于配置全局項目,例如調試級別、內存分配和發現,以及發布者和訂閱者的傳輸實現細節。配置也可以直接在代碼中實現,但是,為了便于維護和減少運行時錯誤,建議將配置外部化。完整的配置選項集在第 7 章中描述。
Installation
如何構建 OpenDDS 的步驟可以在 $DDS_ROOT/INSTALL.md 中找到。
要使用 DDS 安全性構建 OpenDDS,請參閱下面的第 14.1 節。為避免編譯您不會使用的 OpenDDS 代碼,有些功能可以排除在構建之外。
下面討論這些特征。
需要小尺寸配置或與面向安全的平臺兼容的用戶應考慮使用 OpenDDS 安全配置文件,該配置文件在本指南的第 13 章中進行了描述。
啟用或禁用功能的構建配置腳本支持大多數功能
配置腳本創建具有正確內容的配置文件,然后運行MPC。
如果您正在使用配置腳本,請使用“–help”命令行選項運行它并查找您希望啟用/禁用的功能。如果您不使用配置腳本,請繼續閱讀以下有關直接運行 MPC 的說明。對于下面描述的功能,MPC 用于啟用(默認)功能或禁用該功能。
對于名為 feature 的功能,使用以下步驟從構建中禁用該功能:
或者,將行 feature=0 添加到文件 $ACE_ROOT/bin/MakeProjectCreator/config/default.features 并使用 MPC 重新生成項目文件。
要顯式啟用該功能,請使用上面的 feature=1。
注意:您還可以使用 $DDS_ROOT/configure 腳本來啟用或禁用功能。 要禁用該功能,請將 --no-feature 傳遞給腳本,以啟用 pass --feature。 在這種情況下,使用“-”而不是特征名稱中的“_”。 例如,要禁用下面討論的功能 content_subscription,請將 --no-content subscription 傳遞給配置腳本。
禁用內置主題支持的構建
功能名稱:built_in_topics
通過禁用內置主題支持,您可以將核心 DDS 庫的占用空間減少多達 30%。有關內置主題的描述,請參見第 6 章。
禁用合規配置文件功能的構建
DDS 規范定義了合規性配置文件,以提供一個通用術語來指示 DDS 實現可能支持或可能不支持的某些功能集。
下面給出了這些配置文件,以及用于禁用對該配置文件或該配置文件組件的支持的 MPC 功能的名稱。
許多配置文件選項涉及 QoS 設置。如果您嘗試使用與禁用的配置文件不兼容的 QoS 值,則會發生運行時錯誤。如果配置文件涉及類,如果您嘗試使用該類并且配置文件被禁用,則會發生編譯時錯誤。
內容訂閱配置文件
功能名稱:content_subscription 此配置文件添加了第 5 章中討論的類 ContentFilteredTopic、QueryCondition 和 MultiTopic。此外,可以使用下表中給出的功能排除單個類。
| ContentFilteredTopic | content_filtered_topic |
| QueryCondition | query_condition |
| MultiTopic | multi_topic |
持久性配置文件
功能名稱:persistence_profile
此配置文件添加了 QoS 策略 DURABILITY_SERVICE 以及 DURABILITY QoS 策略類型的設置“TRANSIENT”和“PERSISTENT”。
所有權概況
功能名稱:ownership_profile
此配置文件添加:
? OWNERSHIP 類型的設置“EXCLUSIVE”
? 支持 OWNERSHIP_STRENGTH 政策
? 為HISTORY QoS 策略設置深度> 1。
注意:一些用戶可能希望排除對獨占 OWNERSHIP 策略及其關聯的 OWNERSHIP_STRENGTH 的支持,而不影響對 HISTORY 的使用。 為了支持這種配置,OpenDDS 還具有 MPC 特性 owner_kind_exclusive(配置腳本選項 --no-ownership-kind-exclusive)。
對象模型配置文件
功能名稱:object_model_profile
此配置文件包括對“GROUP”的 PRESENTATION access_scope 設置的支持。
注意:目前,禁用 object_model_profile 時,也會排除“TOPIC”的 PRESENTATION access_scope。
構建使用 OpenDDS 的應用程序
本節適用于任何直接或間接包含 OpenDDS 標頭的 C++ 代碼。 對于 Java 應用程序,請參閱下面的第 10 章。 包含 OpenDDS 標頭的 C++ 源代碼可以使用以下任一構建系統構建:MPC 或 CMake。
MPC:Makefile、項目和工作區創建者
OpenDDS 本身是使用 MPC 構建的,因此設置為使用 OpenDDS 的開發系統已經具有 MPC 可用。 OpenDDS 配置腳本創建一個帶有環境設置的“setenv”腳本(Windows 上的 setenv.cmd;Linux/macOS 上的 setenv.sh)。
此環境包含使用 MPC 所需的 PATH 和 MPC_ROOT 設置。 MPC 的源代碼樹(在 MPC_ROOT 中)包含一個“docs”目錄,其中包含 HTML 和純文本文檔(USAGE 和 README 文件)。
2.1 節中的示例演練使用 MPC 作為其構建系統。 OpenDDS 源代碼樹包含許多使用 MPC 構建的測試和示例。 這些可以用作應用程序 MPC 文件的起點。
cmake
應用程序也可以使用 CMake ( https://cmake.org) 構建。
請參閱 OpenDDS 源代碼樹中包含的文檔:docs/cmake.md
OpenDDS 源代碼樹還包括使用 CMake 的示例。它們列在 cmake.md 文件中。
自定義構建系統
強烈建議 OpenDDS 的用戶選擇上面列出的兩個選項之一(MPC 或 CMake),以便在任何受支持的平臺上生成一致的構建文件。如果無法做到這一點,OpenDDS 的用戶必須確保自定義構建設置中的所有代碼生成器、編譯器和鏈接器設置都生成與 API 和 ABI 兼容的代碼。
為此,請從 MPC 或 CMake 生成的項目文件(makefile 或 Visual Studio 項目文件)開始,并確保在自定義構建系統中表示所有相關設置。這通常通過檢查項目文件和運行帶有詳細輸出的構建的組合來完成,以查看工具鏈(代碼生成器、編譯器、鏈接器)是如何被調用的。
通過 https://objectcomputing.com/products/opendds/consultingsupport 聯系 Object Computing, Inc. (OCI),讓我們的專業軟件工程師為您解決此問題。
總結
以上是生活随笔為你收集整理的【OpenDDS开发指南V3.20】第一章:介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 67、ulimit的使用
- 下一篇: 有点憋,说两句