Closed yanzhang920817 closed 3 months ago
Your writer is created with the default QoS (both topic and writer have NULL
for the QoS parameter, so the topic doesn't override anything and the writer just gets the default):
topic = dds_create_topic (participant, &DDS_MSG_STRUCT_Msg_desc, "HelloWorldData_Msg", NULL, NULL);
writer = dds_create_writer (participant, topic, NULL, NULL);
On the Python side:
qos = Qos(
Policy.Reliability.BestEffort,
Policy.Deadline(duration(microseconds=10)),
Policy.Durability.Transient,
Policy.History.KeepLast(10)
)
participant = DomainParticipant(0)
tp = Topic(particip_STRUCT, qos=qos)
subscriber = Subscriber(participant)
reader = DataReader(subscriber, tp, listener=listener)
The topic gets reliability = "best effort", deadline = 1µs, durability = "transient" and history = "keep last 10". The idea is that there is a all definition of topic T are the same in a domain, but it doesn't actually matter most of the time, because the reader and writer can overrule it anyway.
But then, the reader inherits the settings from the QoS (you can easily see them using cyclonedds ls --qos
[^1]):
Deadline(deadline='10 microseconds')
Durability.Transient
History.KeepLast(depth=10)
Reliability.BestEffort
DDS has a QoS "matching" rule in place where some QoS's must be set to compatible values for the reader and writer to communicate. Among those are: "deadline", "durability" and "reliability". Having a "best-effort" reader is also fine, but a deadline of 10µs on the reader with a (default) deadline of ∞ on the writer won't talk. Similarly, transient
vs volatile
is also not going to work.
A 10µs deadline is going to be a problem in practice, it would require you to update the data at 100kHz minimum and that's tricky on standard operating systems. Cyclone doesn't support "transient" yet (it should reject it when try to use it, I guess, but it doesn't at the moment).
So the two are expected not to communicatie.
[^1]: You could also use the new insight tool, it even flags QoS incompatibilities.
Your writer is created with the default QoS (both topic and writer have
NULL
for the QoS parameter, so the topic doesn't override anything and the writer just gets the default):topic = dds_create_topic (participant, &DDS_MSG_STRUCT_Msg_desc, "HelloWorldData_Msg", NULL, NULL); writer = dds_create_writer (participant, topic, NULL, NULL);
On the Python side:
qos = Qos( Policy.Reliability.BestEffort, Policy.Deadline(duration(microseconds=10)), Policy.Durability.Transient, Policy.History.KeepLast(10) ) participant = DomainParticipant(0) tp = Topic(particip_STRUCT, qos=qos) subscriber = Subscriber(participant) reader = DataReader(subscriber, tp, listener=listener)
The topic gets reliability = "best effort", deadline = 1µs, durability = "transient" and history = "keep last 10". The idea is that there is a all definition of topic T are the same in a domain, but it doesn't actually matter most of the time, because the reader and writer can overrule it anyway.
But then, the reader inherits the settings from the QoS (you can easily see them using
cyclonedds ls --qos
1):Deadline(deadline='10 microseconds') Durability.Transient History.KeepLast(depth=10) Reliability.BestEffort
DDS has a QoS "matching" rule in place where some QoS's must be set to compatible values for the reader and writer to communicate. Among those are: "deadline", "durability" and "reliability". Having a "best-effort" reader is also fine, but a deadline of 10µs on the reader with a (default) deadline of ∞ on the writer won't talk. Similarly,
transient
vsvolatile
is also not going to work.A 10µs deadline is going to be a problem in practice, it would require you to update the data at 100kHz minimum and that's tricky on standard operating systems. Cyclone doesn't support "transient" yet (it should reject it when try to use it, I guess, but it doesn't at the moment).
So the two are expected not to communicatie.
Footnotes
I have also observed that the c demo uses the default qos, but I have tried not setting qos or qos=Qos()
, but it has no effect.
cat subsciber3.py
from dataclasses import dataclass
from cyclonedds.domain import DomainParticipant, Domain
from cyclonedds.sub import DataReader, Subscriber
from cyclonedds.topic import Topic
from cyclonedds.core import Listener, Qos, Policy
from cyclonedds.util import duration
from cyclonedds.idl import IdlStruct
import cyclonedds.idl.types as types
import cyclonedds.idl.annotations as annotate
import time
@dataclass
@annotate.final
@annotate.autoid("sequential")
class DDS_MSG_STRUCT(IdlStruct, typename="DDS_MSG_STRUCT::Msg"):
userID: types.int32
message: types.array[types.int8, 64]
class MyListener(Listener):
def on_liveliness_changed(self, reader, status):
print(">> Liveliness event")
listener = MyListener()
participant = DomainParticipant(0)
qos=Qos()
tp = Topic(participant, "HelloWorldData_Msg", DDS_MSG_STRUCT, qos)
subscriber = Subscriber(participant)
reader = DataReader(subscriber, tp, listener=listener)
print("\n=== [Subscriber] Waiting for a sample ...")
for sample in reader.take_iter(timeout=duration(seconds=2)):
print(sample)
del reader
del tp
del participant
Thanks to eboasson's patient help, my problem was solved. It was because the message formats of Python and C were inconsistent, and the cyclonedds.xml was not used when the Python code was running.
I have implemented subscribers and publishers in C and Python. If the subscriber and publisher are in the same language, they can communicate normally, but if not, it doesn't work. As shown below, I am the publisher in C and the subscriber in Python.
publisher.c:
cat dds_msg_struct.idl
subscriber.py:
cat cyclonedds.xml
a part of log: