16#ifndef CARLA_ROS2_MIDDLEWARE_TESTING
17#ifdef CARLA_ROS2_MIDDLEWARE_CYCLONEDDS
20#include <dds/ddsi/ddsi_serdata.h>
21#include <dds/ddsi/ddsi_sertype.h>
35class CycloneDDSSubscriberMiddleware :
public ISubscriberMiddleware {
37 using msg_type =
typename S::msg_type;
39 CycloneDDSSubscriberMiddleware() =
default;
40 CycloneDDSSubscriberMiddleware(
const CycloneDDSSubscriberMiddleware&) =
delete;
41 CycloneDDSSubscriberMiddleware& operator=(
const CycloneDDSSubscriberMiddleware&) =
delete;
43 ~CycloneDDSSubscriberMiddleware()
override {
53 dds_set_listener(_reader,
nullptr);
56 if (_topic > 0) { dds_delete(_topic); }
60 const std::string& topic_name,
62 bool* new_message_flag)
override
64 return InitImpl(topic_name, message_ptr, new_message_flag,
nullptr);
68 const std::string& topic_name,
70 bool* new_message_flag,
71 const QosProfile& qos)
override
73 return InitImpl(topic_name, message_ptr, new_message_flag, &qos);
81 const std::string& topic_name,
83 bool* new_message_flag,
84 const QosProfile* qos_profile)
86 _message_ptr =
static_cast<msg_type*
>(message_ptr);
87 _new_message_ptr = new_message_flag;
89 dds_entity_t participant = carla_cdr_get_participant();
90 if (participant < 0) {
91 log_error(
"CycloneDDSSubscriberMiddleware: Shared participant unavailable "
92 "(topic '", topic_name,
"', code:", participant,
")");
96 const char* type_name = CdrTopicInfo<msg_type>::type_name();
97 _topic = carla_cdr_create_topic(
98 participant, topic_name.c_str(), type_name, &_sertype);
100 log_error(
"CycloneDDSSubscriberMiddleware: Failed to create topic '",
101 topic_name,
"' (code:", _topic,
")");
105 dds_qos_t* qos = dds_create_qos();
106 if (qos_profile !=
nullptr) {
107 dds_qset_reliability(qos,
108 qos_profile->reliability == QosProfile::Reliability::Reliable
109 ? DDS_RELIABILITY_RELIABLE
110 : DDS_RELIABILITY_BEST_EFFORT,
112 dds_qset_durability(qos,
113 qos_profile->durability == QosProfile::Durability::TransientLocal
114 ? DDS_DURABILITY_TRANSIENT_LOCAL
115 : DDS_DURABILITY_VOLATILE);
116 dds_qset_history(qos,
117 qos_profile->history == QosProfile::History::KeepLast
118 ? DDS_HISTORY_KEEP_LAST
119 : DDS_HISTORY_KEEP_ALL,
120 qos_profile->history_depth);
122 dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(1));
123 dds_qset_history(qos, DDS_HISTORY_KEEP_LAST, 1);
127 auto ud = build_user_data_for<msg_type>();
129 dds_qset_userdata(qos, ud.data(), ud.size());
131 dds_listener_t* listener = dds_create_listener(
this);
132 dds_lset_subscription_matched(listener, carla_on_subscription_matched);
133 dds_lset_data_available(listener, carla_on_data_available);
135 _reader = dds_create_reader(participant, _topic, qos, listener);
136 dds_delete_listener(listener);
139 log_error(
"CycloneDDSSubscriberMiddleware: Failed to create reader "
140 "(topic '", topic_name,
"', code:", _reader,
")");
144 _topic_name = topic_name;
149 bool IsAlive()
const override {
150 return _alive.load(std::memory_order_relaxed);
153 std::string GetTopicName()
const override {
158 static void carla_on_subscription_matched(
160 const dds_subscription_matched_status_t status,
163 CycloneDDSSubscriberMiddleware* self =
164 static_cast<CycloneDDSSubscriberMiddleware*
>(arg);
165 self->_alive.store(status.current_count > 0, std::memory_order_relaxed);
168 static void carla_on_data_available(dds_entity_t reader,
void* arg) {
169 CycloneDDSSubscriberMiddleware* self =
170 static_cast<CycloneDDSSubscriberMiddleware*
>(arg);
172 struct ddsi_serdata*
sd =
nullptr;
173 dds_sample_info_t info;
174 dds_return_t rc = dds_takecdr(reader, &
sd, 1u, &info, DDS_ANY_STATE);
175 if (rc <= 0 || !
sd) {
return; }
177 if (info.valid_data) {
178 const uint8_t* data = carla_cdr_data(
sd);
179 const uint32_t size = carla_cdr_size(
sd);
181 *self->_message_ptr)) {
182 log_error(
"CycloneDDSSubscriberMiddleware::on_data_available (",
183 self->_topic_name,
"): deserialization failed");
185 *self->_new_message_ptr =
true;
188 ddsi_serdata_unref(
sd);
191 dds_entity_t _topic { DDS_ENTITY_NIL };
192 dds_entity_t _reader { DDS_ENTITY_NIL };
193 struct ddsi_sertype* _sertype {
nullptr };
195 msg_type* _message_ptr {
nullptr };
196 bool* _new_message_ptr {
nullptr };
198 std::string _topic_name;
199 std::atomic<bool> _alive {
false };
bool deserialize_from_cdr(const uint8_t *data, size_t size, T &msg)
Deserialize a msg::X from a CDR byte buffer that was produced by serialize_to_cdr() or by any ROS2-co...
This file contains definitions of common data structures used in traffic manager.