1.概述
1.1 简介
DDS规范的目的可以概括为“在正确的时间将正确信息有效且稳健地传递到正确的位置。(The purpose of the DDS specification can be summarized as enabling the “Efficient and Robust Delivery of the Right Information to the Right Place at the Right Time.”)
DCPS模型(Data-Centric Publish-Subscribe)
被广泛应用到实时性的系统中
两个概念:
Publisher–希望向此数据空间提供信息的应用程序声明其意图
Subscriber–想要访问此数据空间部分的应用程序声明他们的意图
数据模型被定义成数据结构体,每一个结构体都有 topic、type
topic:提供了唯一标识全局数据空间中的某些数据项的标识符。
type:提供了告诉中间件如何操作数据所需的结构信息,并允许中间件提供类型安全级别。
2.DCPS
2.1 概述
PIM(The Platform Independent Model )–平台无关模型
PSM(The Platform Specific Model)–基于PIM的OMG IDL平台的平台特定模型
2.2 PIM
2.2.1概述和设计原理
2.2.1.1格式和约定
记录类的表格格式如下所示:
将错误定义成类型为ReturnCode_t的返回码,具体类型见下表:
2.2.1.2 概念大纲
2.2.1.2.1 概述
- 发送方:Publisher and DataWriter
Publisher是负责数据分发的对象。它可以发布不同数据类型的数据。DataWriter充当发布者的类型访问者。DataWriter是应用程序用来向Publisher传递给定类型的数据对象的存在和数值的必需对象。当数据对象值通过适当的数据写者传递给Publisher时,Publisher有责任执行分发(Publisher将根据自己的QoS或相应数据写入者的QoS执行此操作)。一次发布是通过DataWriter与Publisher的关联定义的。此关联表明应用程序有发布数据的意图,该数据由Publisher提供的上下文中的DataWriter进行描述。
- 接收方:Subscriber and DataReader
Subscriber是负责接收已发布的数据并使其可用于(根据Subscriber的QoS)接收应用程序的对象。它可以接收和分发不同特定类型的数据。应用程序必须使用附加到Subscriber的某一类型的DataReader访问接收的数据。因此,一次订阅是通过DataReader与Subscriber的关联定义的。该关联表明应用程序有订阅数据的意图,该数据由Subscriber提供的上下文中的DataReader进行描述。
- Topic
Topic关联一个name(在domain里面是唯一的),数据类型和与数据本身相关的QoS。
当application想要发布数据时,需要建一个Publisher和一个DataWriter,或者用已有的。同样的,当application想要接收数据时,需要建一个Subscriber和一个 DataReader,或者用已有的。
2.2.1.2.2 整体概念模型
- 支持QoS:每个Entity(实体)都支持它特定的QoS
- 接受Listener:通知应用程序相关的异步事件,例如订阅的数据到达,违反QoS设置等事件。每个DCPS实体支持其自己的专用类型监听器。
- 接受StatusCondition(以及数据读取者的一组读取条件 对象),条件(与WaitSet对象一起)为中间件和应用程序之间的备用通信方式提供支持(即,基于等待而不是基于通知)
所有这些DCPS实体都附属于域参与者(DomainParticipant)。 域参与者表示域中应用程序的本地成员身份。数据域是一个分布式的概念,它链接所有的应用程序,使得这些应用程序能够相互通信。
DomainParticipant是服务的入口,对共享物理网络的应用程序进行隔离。
DomainEntity是为了声明域参与者不能包含其他域参与成员。
每一次数据更改都是单独且独立地传播,与其他更改不相关。但是,应用程序可能会要求发送方将多次修改当做一次完整的数据发送出去,并在接收方进行对应的解析。此功能将以发布者/订阅者(Publisher/Subscriber)为基础而实现。也就是说,这些关系只能在隶属于同一发布者(Publisher)的数据写入者(DataWriter)对象中指定,并在隶属于同一订阅者(Subscriber)的数据读取者(DataReader)对象中接收恢复。
根据定义,Topic 对应单个数据类型。但是,多个Topic可能指的是相同的数据类型。因此,Topic标识单个类型的数据,范围从单个实例到该给定类型的整个实例集合。
通过key值来区分同一个topic的不同实例。同一个key的不同数据表示同一个实例的连续数值,不同key的不同数值表示不同实例。如果没有key,表示Topic只有一个实例。
Topic objects are created using the create operations provided by DomainParticipant.
Topic对象是通过域参与者 提供的创建方法创建的。
Pubulisher的交互:application有数据要发布,调用关联的数据写入者 的相应操作(这将触发其所属的发布者)
Subscriber的交互:订阅的消息的到达时机可能是当application忙于执行其他操作或是application等待该信息时。因此,有异步通知和同步访问两种形式。
- Listener:用于为同步数据访问提供回调
- WaitSet:与一个或多个Condition对象关联,提供异步数据访问。
2.2.2 平台无关模型(PIM)描述
DCPS模型有五个模块:
- Infrastructure Module:定义了抽象类和由其他模块细化的接口。它还为中间件提供了两种交互方式(基于通知和等待)的支持。
- Domain Module:包含DomainParticipant类,它充当中间件服务的入口点,并充当许多类的工厂。DomainParticipant类还充当组成服务的其他对象的容器。
- Topic Module:包含Topic,ContentFilteredTopic,MultiTopic类和TopicListener接口,也就是主题定义模块包含应用程序所需用来定义Topic对象并将QoS策略附加到对象上的全部内容。
- Publication Module:包含Publisher和DataWriter类以及PublisherListener和DataWriterListener接口,也就是包含发布端所需的全部内容。
- Subscription Module:包含Subscriber,DataReader,ReadCondition和QueryCondition类,以及SubscriberListener和DataReaderListener接口,也就是包含订阅方所需的全部内容。
接下来对各个Module进行详细介绍:
2.2.2.1 Infrastructure Module
2.2.2.1.1 Entity 类
支持QoS策略,Listener和 status condition的所有DCPS对象的抽象基类。
StatusKind是一个枚举类型,用于标识每个具体的Status类型。
接下来是对上面表格里面的函数进行介绍:
1. set_qos (abstract):
- 用于设置实体的QoS策略,必须由每个派生的实体类(DomainParticipant,Topic,Publisher,DataWriter,Subscriber,DataReader)提供;
- 通过qos_list参数指定的策略集应用于现有QoS之上,替换先前设置的任何策略值;
- 有些QoS是可变的,有些事不可变的,调用set_qos尝试更改 “不可变”策略的值,此操作将失败并返回IMMUTABLE_POLICY;
- 如果通过set_qos方法指定一组QoS值,与现有QoS值组合将导致不一致的策略,则set_qos方法也将失败,返回INCONSISTENT_POLICY;
- 如果应用程序为服务不支持的QoS策略提供非默认值,则set_qos方法将失败并返回UNSUPPORTED;
- 成功返回OK,不成功的话策略不会被改变;
get_qos(抽象方法)
- 用于访问实体的现有QoS策略集,必须由每个派生的实体类(DomainParticipant,Topic,Publisher,DataWriter,Subscriber,DataReader)提供;
set_listener(抽象方法)
- 允许设置附加到实体的现有监听器;
- 只有在指定掩码指示的通信状态更改时才会调用监听程序;
- ‘nil’这个值代表监听器不执行任何操作;
- 每个实体只能附加一个监听器。如果已经设置了监听器,set_listener方法将使用新的替换它。因此,如果将值“nil”当做set_listener方法的监听器参数,则将删除任何现有监听器;
- 必须由每个派生的实体类(DomainParticipant,Topic,Publisher,DataWriter,Subscriber,DataReader)提供,以便监听器具有适合特定实体的具体类型。
get_listener(抽象方法)
- 此方法允许访问附加到实体的现有监听器;
- 此方法必须由每个派生的实体类(DomainParticipant,Topic,Publisher,DataWriter,Subscriber,DataReader)提供,以便监听器具有适合特定实体的具体类型。
get_statuscondition
- 可以访问与实体关联的StatusCondition ,返回值放在WaitSet里面
get_status_changes
- 检索所有实体中被‘触发’的通信状态列表,自从上次读取状态以来值更改的状态列表
- 首次创建实体或未启用实体时,所有通信状态都处于“未触发”状态,因此get_status_changes方法返回的列表将为空。
- 只是实体自身触发的状态,不包括应用于包含的实体的状态。
enable
- 可以使用该方法启用或禁用实体对象
get_instance_handle
- 返回InstanceHandle_t,表示这个实体
2.2.2.1.2 DomainEntity类
DomainEntity是除DomainParticipant外,所有DCPS实体的抽象基类。
DomainEntity可以是其他所有实体的容器,就是没有DomainParticipant
2.2.2.1.3 QosPolicy类
- 所有具体的QosPolicy类都派生自此基类,具有一个属性name,用于唯一标识每个QoS策略;
- QosPolicy值的类型可以是int、float或结构体等;
- 每个实体都有一个QosPolicy列表;
- 每个实体被创建的时候,QosPolicy就被设置好了,或者可以使用set_qos方法进行更改(有些QosPolicy具有“不可变”语义,设置好了不能改);
- 由于每个QosPolicy都是独立的,所以存在有冲突的可能,所以每次通过set_qos方法修改策略时,都会执行一致性检查(Consistency checking );
- 在某个策略设置为给定值后需要更改时,不强制要求立即应用新值,允许服务在过渡阶段后应用它;
2.2.2.1.4 Listener接口
- 监听器接口为服务提供了一种机制,此机制可以异步地通知应用程序通信状态的相关变化;
- 可应用的实体:DomainParticipant,Topic,Publisher,DataWriter,Subscriber和DataReader
2.2.2.1.5 Status 类
- Status类是所有通信状态对象的抽象根类
- 每个具体实体与一组Status对象相关联,其值表示该实体的“通信状态”;
- 可以通过实体上的相应方法访问这些状态值;
- 这些状态值的更改既会激活相应的StatusCondition对象,又会触发合适的Listener对象的调用,从而异步通知应用程序。
2.2.2.1.6 WaitSet类
- WaitSet允许应用程序等待:直到一个或多个附加的Condition对象的trigger_value为TRUE,否则等待到超时到期;
- 它不一定与单个DomainParticipant相关联,并且可以用于等待与不同DomainParticipant对象关联的Condition对象。
attach_condition
detach_condition
wait
get_conditions
2.2.2.1.7 Condition类
- Condition类是所有可以附加到WaitSet的条件的根类。
- Condition类专用于:GuardCondition (2.2.2.1.8), StatusCondition (2.2.2.1.9), and ReadCondition(2.2.2.5.8).
- Condition的trigger_value可以为TRUE或FALSE,由服务自动设置。
get_trigger_value
2.2.2.1.8 GuardCondition类
- 一个特殊的Condition,其trigger_value完全在应用程序的控制之下。
- 首次创建时,trigger_value设置为FALSE。
- 目的是为应用程序提供手动唤醒WaitSet的方法。通过将GuardCondition附加到WaitSet,然后调用set_trigger_value方法设置trigger_value来实现。
用法:set_trigger_value(bool value);
1.set_trigger_value
2.2.2.1.9 StatusCondition 类
- StatusCondition 是一种特殊的Condition,和每个实体进行关联
- StatusCondition的trigger_value取决于该实体的通信状态(例如,数据到达,信息丢失等),由StatusCondition上的enabled_statuses集“过滤”。
set_enabled_statuses
get_enabled_statuses
get_entity
–此方法返回与StatusCondition关联的实体。请注意,每个StatusCondition只关联一个实体。