目录
- XML profiles
- TopicType
- Qos
- DeadlineQosPolicy
- DurabilityQosPolicy
- DurabilityServiceQosPolicy
- EntityFactoryQosPolicy
- GroupDataQosPolicy
- LatencyBudgetQosPolicy
- LifespanQosPolicy
- LivelinessQosPolicy
- OwnershipQosPolicy
- OwnershipStrengthQosPolicy
- PartitionQosPolicy
- PresentationQosPolicy
- ReaderDataLifecycleQosPolicy
- ReliabilityQosPolicy
- ResourceLimitsQosPolicy
- TimeBasedFilterQosPolicy
- TopicDataQosPolicy
- TransportPriorityQosPolicy
- UserDataQosPolicy
- WriterDataLifecycleQosPolicy
- Fast DDS中的扩展Qos
Qos (Quality of Service)用于指定服务的行为,允许用户指定每个实体怎样表现或运行。通过XML文件(Profiles)来配置或者在代码中直接指定。
XML profiles
xml配置文件可以有多个。
加载
Fast DDS在初始化阶段自动加载XML:
- 在当前可执行文件的路径下加载 DEFAULT_FASTRTPS_PROFILES.xml
- 加载环境变量FASTRTPS_DEFAULT_PROFILES_FILE指定的xml
- 加载配置参数指定的xml文件
- 直接加载xml格式的字符串
文件格式
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<profiles>
<domainparticipant_factory profile_name="domainparticipant_factory_profile">
<!-- ... -->
</domainparticipant_factory>
<participant profile_name="participant_profile">
<!-- ... -->
</participant>
<data_writer profile_name="datawriter_profile">
<!-- ... -->
</data_writer>
<data_reader profile_name="datareader_profile">
<!-- ... -->
</data_reader>
<topic profile_name="topic_profile">
<!-- ... -->
</topic>
<transport_descriptors>
<!-- ... -->
</transport_descriptors>
</profiles>
<library_settings>
<!-- ... -->
</library_settings>
<log>
<!-- ... -->
</log>
<types>
<!-- ... -->
</types>
</dds>
<dds>, <profiles>, <library_settings>, <types>, <log>
这些标签可以独立定义。<participant>, <data_reader>, <data_writer>, <topic>, <transport_descriptors>
这些标签必须作为<profiles>
的子元素
代码中修改
if (ReturnCode_t::RETCODE_OK ==
DomainParticipantFactory::get_instance()->load_XML_profiles_file("my_profiles.xml"))
{
DomainParticipantQos participant_qos;
DomainParticipantFactory::get_instance()->get_participant_qos_from_profile(
"participant_xml_profile",
participant_qos);
// Name obtained in another section of the code
participant_qos.name() = custom_name;
// Modify number of preallocations (this overrides the one set in the XML profile)
participant_qos.allocation().send_buffers.preallocated_number = 10;
// Create participant using the modified XML Qos
DomainParticipant* participant =
DomainParticipantFactory::get_instance()->create_participant(
0, participant_qos);
}
可配置内容
- DomainParticipantFactory profiles
- DomainParticipant profiles
- DataWriter profiles
- DataReader profiles
- Topic profiles
- transport_descriptor
- Intra-process delivery profiles
- Log profiles
- Dynamic Types profiles
TopicType
这个配置下面指定了HistoryQosPolicy和ResourceLimitsQosPolicy这两个Qos在DataWriters和DataReaders端的配置,也可以直接在topic下配置
HistoryQosPolicy
说明
在DDS (Data Distribution Service) 中,数据不是立即发送的,而是存储在Writer和Reader的内存中。History QoS (Quality of Service) 策略决定了这些实体如何管理它们的内存,以及当内存不足时如何处理新的数据。
将History的QoS配置放在topic下,是为了更精细地控制数据分配和内存管理。单独设置每个topic的HistoryQosPolicy允许开发者在Writer和Reader之间以更灵活的方式控制数据交换,可以针对每个topic单独设置历史存储策略,以满足应用程序的特定需求。
例如,对于某些topic,你可能希望保存所有历史数据(使用KEEP_ALL);对于其他topic,你可能只关心最新的数据(使用KEEP_LAST,并设置一个较小的depth)。将History的QoS配置放在topic下使得这种灵活配置成为可能。
适用的entities
- Topic
- DataWriter
- DataReader
在已经enabled的entities中不能改变
属性
成员 | 类型 | 默认值 | 意义 |
---|---|---|---|
kind | HistoryQosPolicyKind | KEEP_LAST_HISTORY_QOS | 保留数据的两种策略,具体参考HistoryQosPolicyKind |
depth | int32_t | 1 | 参看一致性规则 |
HistoryQosPolicyKind:
KEEP_LAST_HISTORY_QOS
:保留最新的值,丢弃旧的。具体要保留多少由第二个字段depth 值决定;但是受到ResourceLimitsQosPolicy
的限制,就是说ResourceLimitsQosPolicy
的优先级高,如果先达到了ResourceLimitsQosPolicy
的限制就会丢弃。KEEP_ALL_HISTORY_QOS
:保留所有值,直到发送给所有已经存在的subscribers。此时depth 字段就没有任何作用了,只受到ResourceLimitsQosPolicy
的限制
一致性规则
- 如果
HistoryQosPolicyKind
的值为KEEP_ALL_HISTORY_QOS
则 depth 这个字段没有作用; - 如果是
KEEP_LAST_HISTORY_QOS
,它的大小必须小于等于ResourceLimitsQosPolicy
的max_samples_per_instance
字段值;另外,max_samples
必须等于或高于max_samples_per_instance
和max_instances
的乘积。 - 如果设置
ReliabilityQosPolicy
的ReliabilityQosPolicyKind
的值为RELIABLE_RELIABILITY_QOS
,HistoryQosPolicy
的kind为KEEP_ALL_HISTORY_QOS
, 资源达到上限,行为取决于DurabilityQosPolicy
:- 如果
DurabilityQosPolicy
kind值为VOLATILE_DURABILITY_QOS
, DataWriter的 write()会丢弃history中最早的sample. Note that the removed sample may belong to different instances than the newly written one. - 如果
DurabilityQosPolicy
kind 值为TRANSIENT_LOCAL_DURABILITY_QOS
或者TRANSIENT_DURABILITY_QOS
, DataWriter 的write() 会阻塞直到history有空间存放新的sample.
- 如果
Qos配置
xml配置
<data_writer profile_name="dataWriter_topic_example">
<topic>
<historyQos>
<kind>KEEP_LAST</kind> <!-- string -->
<depth>20</depth> <!-- uint32 -->
</historyQos>
</topic>
</data_writer>
C++实现
// DataReader和Topic的用法一样
DataWriterQos writer_qos;
// 默认为:kind = KEEP_LAST and depth = 1
writer_qos.history().depth = 20;
// 如果是KEEP_ALL的话depth没有用
writer_qos.history().kind = KEEP_ALL_HISTORY_QOS;
writer_ = publisher_->create_datawriter(topic_, writer_qos);
ResourceLimitsQosPolicy
说明
它控制Fast DDS可以使用的资源,以满足应用程序和其他QoS设置施加的要求
适用的entities
- Topic
- DataWriter
- DataReader
属性
属性名 | 类型 | 默认值 |
---|---|---|
max_samples | int32_t | 5000 |
max_instances | int32_t | 10 |
max_samples_per_instance | int32_t | 400 |
allocated_samples | int32_t | 100 |
extra_samples | int32_t | 1 |
- max_samples:它控制DataWriter或DataReader可以管理的与之相关的所有instances的最大samples数。换句话说,它代表了中间件可以为DataReader或DataWriter存储的最大samples数。值小于或等于0表示资源无限。
- max_instances:控制DataWriter或DataReader管理的最大instances数。值小于或等于0表示资源无限。
- max_samples_per_instance:DataWriter或DataReader管理的一个instance内的最大samples数。值小于或等于0表示资源无限。
- allocated_samples:初始化时分配的samples数。
- extra_samples:将在pool中额外分配的samples数,因此池中的最大samples数将是max_samples加上extra_samples。即使history已满,这些额外的samples也会作为samples库。这个属性的理解:extra_samples属性允许用户设定在history已满的情况下,还可以在pool中分配的额外samples数量。举个例子,如果我们设定history depth为100,extra_samples为10,那么即使100个history samples已满,DDS仍然可以在pool中存储10个额外的样本。这些额外的样本可以作为一个“备用”的样本库,比如在需要替换某个历史样本或者需要进行某些比较操作时可以使用。这可以提高系统的灵活性。
一致性规则
为了保持ResourceLimitsQosPolicy中的一致性,数据成员的值必须遵循以下条件:
- max_samples的值必须高于或等于max_samples_per_instance的值。
- 为HistoryQosPolicy depth设定的值必须低于或等于max_samples_per_instance的值。
Qos配置
xml
<data_writer profile_name="writer_xml_conf_resource_limits_profile">
<topic>
<resourceLimitsQos>
<max_samples>200</max_samples>
<max_instances>20</max_instances>
<max_samples_per_instance>100</max_samples_per_instance>
<allocated_samples>50</allocated_samples>
</resourceLimitsQos>
</topic>
</data_writer>
<data_reader profile_name="reader_xml_conf_resource_limits_profile">
<topic>
<resourceLimitsQos>
<max_samples>200</max_samples>
<max_instances>20</max_instances>
<max_samples_per_instance>100</max_samples_per_instance>
<allocated_samples>50</allocated_samples>
</resourceLimitsQos>
</topic>
</data_reader>
C++实现
DataWriterQos writer_qos;
writer_qos.resource_limits().max_samples = 200;
writer_qos.resource_limits().max_instances = 20;
writer_qos.resource_limits().max_samples_per_instance = 100;
writer_qos.resource_limits().allocated_samples = 50;
writer_ = publisher_->create_datawriter(topic_, writer_qos);
Qos
每个Qos都有一个唯一的ID(定义在枚举QosPolicyId_t中),这个ID值用于一些Status中,以识别状态所引用的特定Qos策略。
Fast DDS中支持的Policies在这里
DeadlineQosPolicy
说明
当新的数据样本的频率低于设定的阈值时,此QoS策略会发出警报。它对于预期定期更新数据的情况非常有用。
在Pub端,它是期望能够提供发送新的数据样本的最长期限;在Sub端,它是接收新样本的最长时间。
对于存在key的topic,这个Qos应用于key ——
适用的entities
- Topic
- DataWriter
- DataReader
可以在enabled的entities中修改
属性
Data Member Name | Type | Default Value |
---|---|---|
period | Duration_t | c_TimeInfinite |
一致性规则
- offerd(发送,配置在
DataWriter
)的deadline
必须小于等于requested(配置在DataReader)的deadline,否则被认为是不能匹配的,这会导致DataWriter和DataReader在服务发现阶段无法匹配 DeadlineQosPolicy
必须与TimeBasedFilterQosPolicy
保持一致,这意味着deadline的period必须等于或高于TimeBasedFilterQosPolicy
的minimum_separation
。
xml配置
<data_writer profile_name="writer_xml_conf_deadline_profile">
<qos>
<deadline>
<period>
<sec>1</sec>
</period>
</deadline>
</qos>
</data_writer>
DurabilityQosPolicy
DurabilityServiceQosPolicy
EntityFactoryQosPolicy
GroupDataQosPolicy
LatencyBudgetQosPolicy
LifespanQosPolicy
说明
每个由DataWriter
写入的数据样本都有一个关联的过期时间,超过这个时间,数据将从DataWriter
和DataReader
的history以及瞬态和持久性的caches中删除
默认情况下,持续时间是无限的,这意味着DataWriter
写入的样本有效期并没有最大限制。
期限时间是从源时间戳开始+持续时间,从writer方法调用后自动计算,或者由应用程序通过write_w_timestamp()函数提供。DataReader
允许使用接收时间戳替代源时间戳。
适用的entities
- Topic
- DataWriter
- DataReader
可以在enabled的entities中修改
属性
Data Member Name | Type | Default Value |
---|---|---|
duration | Duration_t | c_TimeInfinite |
XML配置
<data_writer profile_name="writer_xml_conf_lifespan_profile">
<qos>
<lifespan>
<duration>
<sec>5</sec>
</duration>
</lifespan>
</qos>
</data_writer>
<data_reader profile_name="reader_xml_conf_lifespan_profile">
<qos>
<lifespan>
<duration>
<sec>5</sec>
</duration>
</lifespan>
</qos>
</data_reader>
LivelinessQosPolicy
说明
这个qos策略控制了服务员用来确保网络上特定entities仍然存活的机制。有不同的设置可以区分数据周期性的更新的应用和数据偶尔改变的应用。还允许针对被生存机制检测的故障类型来定制应用。
适用的entities
- Topic
- DataWriter
- DataReader
不能在enabled的entities总改变
属性
Data Member Name | Type | Default Value |
---|---|---|
kind | LivelinessQosPolicyKind | AUTOMATIC_LIVELINESS_QOS |
lease_duration | Duration_t | c_TimeInfinite |
announcement_period | Duration_t | c_TimeInfinite |
属性说明:
- kind:这个数据成员确定了服务是否需要自动确认生存状态,或者是否需要等到发布方确认生存状态。类型为
LivelinessQosPolicyKind
,有以下值:AUTOMATIC_LIVELINESS_QOS
:只要parcitipant所在的本地进程正在运行,且与其关联的远端participant存在,这个qos的服务就会负责按照要求的频率更新lease,远端participant内的entities会被认为是存活的。这个kind值适合于只需要检测远端应用程序是否仍在运行的情况。- 这两种手动模式要求pub端的应用程序在
lease_duration
到期之前确认其liveliness。pub任何新的数据隐式的确认了DataWriter的liveliness,也可以通过调用assert_liveliness()
成员函数来显式确认。MANUAL_BY_PARTICIPANT_LIVELINESS_QOS
:如果pub端的某一个entities确认了它的liveliness,那么服务会推断出在同一个DomainParticipant中的其他entities也是存活的MANUAL_BY_TOPIC_LIVELINESS_QOS
:这种模式更为严格,需要至少一个在DataWriter内的instance被确认是alive的,才能认为DataWriter是alive的。
lease_duration
: 从DataWriter最后一次确认其生存状态之后等待的时间长度,超过这个时间长度就认为它不再存活。announcement_period
:DataWriter连续发送lineliness messages的时间间隔。这个字段只在kind为AUTOMATIC_LIVELINESS_QOS
或MANUAL_BY_PARTICIPANT_LIVELINESS_QOS
,且比lease_duration字段值低的情况下生效。
一致性原则
为了维持在DataReaders 和DataWriters之间LivelinessQosPolicy
的兼容性,DataWriter
的kind
必须高于或等于DataReader kind。不同的kind之间的顺序为:
|AUTOMATIC_LIVELINESS_QOS-api| < |MANUAL_BY_PARTICIPANT_LIVELINESS_QOS-api| < |MANUAL_BY_TOPIC_LIVELINESS_QOS-api|
有以下可能的组合:
DataWriter kind | DataReader kind | |
---|---|---|
AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS | Yes |
AUTOMATIC_LIVELINESS_QOS | MANUAL_BY_PARTICIPANT_LIVELINESS_QOS | No |
AUTOMATIC_LIVELINESS_QOS | MANUAL_BY_TOPIC_LIVELINESS_QOS | No |
MANUAL_BY_PARTICIPANT_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS | Yes |
MANUAL_BY_PARTICIPANT_LIVELINESS_QOS | MANUAL_BY_PARTICIPANT_LIVELINESS_QOS | Yes |
MANUAL_BY_PARTICIPANT_LIVELINESS_QOS | MANUAL_BY_TOPIC_LIVELINESS_QOS | No |
MANUAL_BY_TOPIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS | Yes |
MANUAL_BY_TOPIC_LIVELINESS_QOS | MANUAL_BY_PARTICIPANT_LIVELINESS_QOS | Yes |
MANUAL_BY_TOPIC_LIVELINESS_QOS | MANUAL_BY_TOPIC_LIVELINESS_QOS | Yes |
另外,DataWriter 的lease_duration不一定必要要大于DataReader的lease_duration
xml配置
<data_writer profile_name="writer_xml_conf_liveliness_profile">
<qos>
<liveliness>
<announcement_period>
<nanosec>1000000</nanosec>
</announcement_period>
<lease_duration>
<sec>1</sec>
</lease_duration>
<kind>AUTOMATIC</kind>
</liveliness>
</qos>
</data_writer>
<data_reader profile_name="reader_xml_conf_liveliness_profile">
<qos>
<liveliness>
<lease_duration>
<sec>1</sec>
</lease_duration>
<kind>AUTOMATIC</kind>
</liveliness>
</qos>
</data_reader>
OwnershipQosPolicy
说明
指定了在多个发布者发布形同的topic时,哪个发布者的数据会被接收。这主要涉及到数据的所有权的问题。是否允许多个DataWriters更新data的同一个instance,如果允许,它还决定如何仲裁这些修改。
适用的entities
- Topic
- DataReader
- DataWriter
不能被修改
属性
Data Member Name | Type | Default Value |
---|---|---|
kind | OwnershipQosPolicyKind | SHARED_OWNERSHIP_QOS |
OwnershipQosPolicyKind
取值:
SHARED_OWNERSHIP_QOS
:表明每个实例不会有唯一的所有权,即所有发布的数据都被视为有效的,并且订阅者将接收到所有发布者发布的更新。所以这种情况下允许多个DataWriter更新相同的数据实例,并且这些更新对每个存在的DataReaders都有效。这些更新也将受到TimeBasedFilterQosPolicy
或HistoryQosPolicy
设置的影响,因此可以进行过滤。EXCLUSIVE_OWNERSHIP_QOS
:表明每个instance只能由一个DataWriter更新,意味着在任意时间点只有一个DataWriter拥有每个instance,也只有这个DataWriter的修改对存在的DataReader是可见的。根据highest strength,所有权可以在现有的,没有违反数据实例的deadline的DataWriters之间动态修改。strength可以通过OwnershipStrengthQosPolicy
修改。如果两个DataWriter有相同的强度值,那么具有较低GUID值的DataWriter将会成为topic的所有者。
一致性原则
必须要符合一致性原则,否则DataWriters和DataReaders之间不能进行服务发现的匹配。这个qos的一致性要求,DataWriter和DataReader的kind必须要一样
有以下可能的组合:
DataWriter kind | DataReader kind | Compatibility |
---|---|---|
SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS | Yes |
SHARED_OWNERSHIP_QOS | EXCLUSIVE_OWNERSHIP_QOS | No |
EXCLUSIVE_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS | No |
EXCLUSIVE_OWNERSHIP_QOS | EXCLUSIVE_OWNERSHIP_QOS | Yes |
xml配置
<data_writer profile_name="writer_xml_conf_ownership_profile">
<qos>
<ownership>
<kind>EXCLUSIVE</kind>
</ownership>
</qos>
</data_writer>
<data_reader profile_name="reader_xml_conf_ownership_profile">
<qos>
<ownership>
<kind>EXCLUSIVE</kind>
</ownership>
</qos>
</data_reader>
OwnershipStrengthQosPolicy
PartitionQosPolicy
说明
这个Qos策略允许在由domain引入的物理分区内引入逻辑分区。对于DataReader来看到DataWriter所做的更改,不仅topic必须匹配,而且它们必须至少共享一个逻辑分区。
空字符串也被视为有效的分区,并且它使用与其他任何分区名称相同的字符串匹配和正则表达式匹配规则进行匹配。
PartitionQosPolicy可以用来控制数据的组织和访问。通过正确地使用PartitionQosPolicy,可以确保只有具有适当权限的订阅者才能接收到特定的数据,从而提高系统的安全性和效率。
举例说明:假设你正在开发一个大型的机器人控制系统,这个系统中有许多不同的子系统,比如导航子系统、感应子系统、动作子系统等,每个子系统都有其自己的发布者和订阅者。为了使系统更整洁、更易于管理,你可能希望将每个子系统的通信全部封装在一个分区中,这样每个子系统的发布者和订阅者只会在其自己的分区中进行通信。
在这种情况下,导航子系统的发布者只能将数据发送给同一分区中的订阅者,即使在其他分区中也有订阅者在订阅相同的数据,也无法接收到这些数据。
这就是PartitionQosPolicy的作用。通过设置不同的PartitionQosPolicy,你可以将DDS系统中的通信划分成多个独立的分区,这样一来,就可以确保数据只在正确的地方被发送和接收,从而提高系统的整洁性和效率。
适用的entities
- Publisher
- Subscriber
在enabled entities中可以改变
属性
Data Member Name | Type | Default Value |
---|---|---|
max_size | uint32_t | 0 |
names | SerializedPayload_t | 空 |
- max_size: partition名的列表大小
- names:partition names的列表
注意
Partitions 可以在endpoint级别显式定义用来覆盖配置。
Endpoint Partitions:遵循与可以为publisher和subscriber定义的PartitionQosPolicy相同的匹配逻辑。属性的值是一个以分号分隔的列表,包含用户希望此endpoint所属的分区名称。
如果publisher和其中一个DataWriter有冲突的分区配置,也就是说,DataWriter定义了此属性,而publisher定义了PartitionQosPolicy,那么DataWriter的配置将优先,对于这个endpoint,publisher的PartitionQosPolicy将被忽略。这也适用于Subscriber及其DataReader。
当使用create_with_profile函数创建DataReaders和DataWriters时,此属性将自动设置。实体创建后不能更改。(?)
PropertyPolicyQos name | PropertyPolicyQos value | Default value |
---|---|---|
“partitions” | 分号分隔的分区名称列表 | “” |
Qos配置
xml配置
<data_writer profile_name="pub_partition_example">
<qos>
<partition>
<names>
<name>part1</name>
<name>part2</name>
</names>
</partition>
</qos>
</data_writer>
<data_reader profile_name="sub_partition_example">
<qos>
<partition>
<names>
<name>part1</name>
<name>part2</name>
</names>
</partition>
</qos>
</data_reader>
C++实现
// This example uses a Publisher, but it can also be applied to Subscriber entities
PublisherQos publisher_qos;
// The PartitionsQosPolicy is constructed with max_size = 0 by default
// Max_size is a private member so you need to use getters and setters to access
// Change the max_size to 20
publisher_qos.partition().set_max_size(20); // Setter function
// The PartitionsQosPolicy is constructed with an empty list of partitions by default
// Partitions is a private member so you need to use getters and setters to access
// Add new partitions in initialization
std::vector<std::string> part;
part.push_back("part1");
part.push_back("part2");
publisher_qos.partition().names(part); // Setter function
// Use modified QoS in the creation of the corresponding entity
publisher_ = participant_->create_publisher(publisher_qos);
// Add data to the collection at runtime
part = publisher_qos.partition().names(); // Getter to keep old values
part.push_back("part3");
publisher_qos.partition().names(part); // Setter function
// Update the QoS in the corresponding entity
publisher_->set_qos(publisher_qos);
PresentationQosPolicy
说明
此 QoS 策略指定了表示数据实例更改的样本如何呈现给订阅应用程序。它控制了数据实例更改之间相互依赖的程度,以及可以传播和维护的依赖关系的类型。
适用的entities
属性
Data Member Name | Type | Default Value |
---|---|---|
access_scope | PresentationQosPolicyAccessScopeKind | INSTANCE_PRESENTATION_QOS |
coherent_access | bool | false |
ordered_access | bool | false |
注意
ReaderDataLifecycleQosPolicy
ReliabilityQosPolicy
说明
控制系统发送和请求的可靠性
适用的entities
- Topic
- DataWriter
- DataReader
不能改变
属性
数据成员 | Type | Default Value |
---|---|---|
kind | ReliabilityQosPolicyKind | BEST_EFFORT_RELIABILITY_QOS for DataReaders RELIABLE_RELIABILITY_QOS for DataWriters |
max_blocking_time | Duration_t | 100 ms |
kind
:指定行为,值类型为ReliabilityQosPolicyKind
,包含两个值:BEST_EFFORT_RELIABILITY_QOS
:samles丢失后可以不需要重新传输,所以消息不用等待就可以发送。这可能是样本的新值生成的频率足够高,以至于不必重新发送任何samples。然而,由同一个DataWriter发送的data samples将按照它们发送的顺序存储在DataReader的history中。换句话说,即使DataReader错过了一些数据样本,旧的值也不会覆盖新的值。RELIABLE_RELIABILITY_QOS
:将会尝试发送所有保存在DataWriter的history中的所有的samples,并期望从DataReader得到收到的确认。如果还有之前的samples未被接收,那么由同一个DataWriter发送的samples就无法被DataReader获取。为了在DataReader访问前重建DataWriter的history的正确快照,该服务将会重新发送丢失的samples。这个选项可能会阻塞writer操作,设置的max_blocking_time这个阻塞时间达到后就不会阻塞了,但此时write操作会返回一个error。
max_blocking_time
:指定Writer最大的阻塞时长。max_blocking_time
等待的是DataReader的确认响应时间,如果在max_blocking_time
设置的时间内没有收到确认,DataWriter会将数据视为丢失。这是为了确保数据的可靠传输。
注意
- 将
kind
设置为BEST_EFFORT_RELIABILITY_QOS
会影响DurabilityQosPolicy
,使得endpoints的行为为VOLATILE_DURABILITY_QOS
- 为了DataWriters 和DataReaders 在服务发现阶段匹配,他们的值的组合需要符合一致性规则
一致性规则
为了维持ReliabilityQosPolicy
在DataWriter和DataReaders端的兼容性,DataWriter kind
必须要大于等于DataReader的Kind(|BEST_EFFORT_RELIABILITY_QOS-api| < |RELIABLE_RELIABILITY_QOS-api|
),具体组合如下:
DataWriter kind | DataReader kind | Compatibility |
---|---|---|
BEST_EFFORT_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS | 兼容 |
BEST_EFFORT_RELIABILITY_QOS | RELIABLE_RELIABILITY_QOS | 不兼容 |
RELIABLE_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS | 兼容 |
RELIABLE_RELIABILITY_QOS | RELIABLE_RELIABILITY_QOS | 兼容 |
xml配置
<data_writer profile_name="writer_xml_conf_reliability_profile">
<qos>
<reliability>
<kind>RELIABLE</kind>
<max_blocking_time>
<sec>1</sec>
</max_blocking_time>
</reliability>
</qos>
</data_writer>
<data_reader profile_name="reader_xml_conf_reliability_profile">
<qos>
<reliability>
<kind>BEST_EFFORT</kind>
</reliability>
</qos>
</data_reader>
ResourceLimitsQosPolicy
TimeBasedFilterQosPolicy
官方当前还未实现,参考
TopicDataQosPolicy
TransportPriorityQosPolicy
UserDataQosPolicy
WriterDataLifecycleQosPolicy
Fast DDS中的扩展Qos
WireProtocolConfigQos
说明
用于配置wire protocol
Qos的成员
Data Member Name | Type | Default Value |
---|---|---|
prefix | GuidPrefix_t | 0 |
participant_id | int32_t | -1 |
builtin | BuiltinAttributes | |
port | PortParameters | |
default_unicast_locator_list | LocatorList | 空 |
default_multicast_locator_list | LocatorList | 空 |
default_external_unicast_locators | ExternalLocators | 空 |
ignore_non_matching_locators | bool | false |
DataSharingQosPolicy
说明
用于配置Data-Sharing delivery传输方式,具体原理可以参考FastDDS之DataSharing
适用的entities
DataWriter
DataReader
数据成员
-
Data-Sharing kind
- 类型:DataSharingKind
- 访问接口:
kind()
- 默认值:AUTO
- 说明:指定data-sharing功能是否开启,具体有以下值:
OFF
:不会使用data-sharing进行通信ON
:开启data-sharing,如果当前的topic不能和data-sharing兼容会发生错误;和远端entities通信时如果至少共享了一个domain ID就可以使用data-sharing传输机制了AUTO
:这个是默认值,如果当前的topic和data-sharing兼容就会使用,否则不会。
-
Shared memory directory
- 类型:string
- 访问接口:
shm_directory()
- 默认值:空
- 说明:这个目录用于存放内存映射文件的目录,如果没有配置则会使用系统默认的目录
-
Maximum domain number
- 类型:uint32_t
- 访问接口:
max_domains()
- 默认值:0 (unlimited)
- 说明:确定本地或远端的最大的data-sharing domain ID的数量。DoaminID会在服务发现的端点发现阶段交换,如果这个值低于任何远端端点列表的大小,匹配可能会失败。0表示不限制数量
-
Data-sharing domain IDs
- 类型:
vector<uint64_t>
- 访问接口:
domain_ids()
- 默认值:空
- 说明:当前的DataWriter和DataReader的data-sharing domain ID的列表,如果没有则系统会创建一个当前机器唯一的id
- 类型:
-
Data-sharing listener thread settings
- 类型:ThreadSettings
- 接口访问:
data_sharing_listener_thread()
- 默认值:空
- 说明:data-sharing的线程用于监听
函数接口(使用代码设置时用到)
接口 | 代表的值 | Shared memory directory | Data sharing domain IDs |
---|---|---|---|
automatic() | AUTO | Optional | Optional |
on() | ON | Mandatory | Optional |
off() | off() | N/A | N/A |
代码配置
DataWriterQos writer_qos;
writer_qos.data_sharing().on("/path/to/shared_memory/directory");
writer_qos.data_sharing().off();
// Configure the DataSharing as AUTO with two user-defined IDs (can also be used with ON)
std::vector<uint16_t> ids;
ids.push_back(0x1234);
ids.push_back(0xABCD);
writer_qos.data_sharing().automatic(ids);
// Alternatively, add them individually
writer_qos.data_sharing().add_domain_id(uint16_t(0x1234));
writer_qos.data_sharing().add_domain_id(uint16_t(0xABCD));
// Or you can leave the IDs empty and the system will automatically create a
// unique ID for the current machine
// Set the maximum number of domains to 5. Setting 0 means 'unlimited'
writer_qos.data_sharing().set_max_domains(5);
// [OPTIONAL] ThreadSettings for listening thread
writer_qos.data_sharing().data_sharing_listener_thread(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
XML配置
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
<profiles xmlns="http://www.eprosima.com">
<data_writer profile_name="writer_profile_qos_datasharing">
<qos>
<data_sharing>
<kind>AUTOMATIC</kind>
<domain_ids>
<domainId>123</domainId>
<domainId>098</domainId>
</domain_ids>
</data_sharing>
</qos>
</data_writer>
<data_reader profile_name="reader_profile_qos_datasharing">
<qos>
<data_sharing>
<kind>AUTOMATIC</kind>
<domain_ids>
<domainId>123</domainId>
<domainId>098</domainId>
</domain_ids>
<data_sharing_listener_thread>
<scheduling_policy>-1</scheduling_policy>
<priority>0</priority>
<affinity>0</affinity>
<stack_size>-1</stack_size>
</data_sharing_listener_thread>
</data_sharing>
</qos>
</data_reader>
</profiles>
<dds>