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 CycloneDDSPublisherMiddleware :
public IPublisherMiddleware {
37 using msg_type =
typename T::msg_type;
39 CycloneDDSPublisherMiddleware() =
default;
40 CycloneDDSPublisherMiddleware(
const CycloneDDSPublisherMiddleware&) =
delete;
41 CycloneDDSPublisherMiddleware& operator=(
const CycloneDDSPublisherMiddleware&) =
delete;
43 ~CycloneDDSPublisherMiddleware()
override {
52 dds_set_listener(_writer,
nullptr);
55 if (_topic > 0) { dds_delete(_topic); }
58 bool Init(
const std::string& topic_name)
override {
59 return InitImpl(topic_name,
nullptr);
62 bool Init(
const std::string& topic_name,
const QosProfile& qos)
override {
63 return InitImpl(topic_name, &qos);
70 bool InitImpl(
const std::string& topic_name,
const QosProfile* qos_profile) {
71 dds_entity_t participant = carla_cdr_get_participant();
72 if (participant < 0) {
73 log_error(
"CycloneDDSPublisherMiddleware: Shared participant unavailable "
74 "(topic '", topic_name,
"', code:", participant,
")");
78 const char* type_name = CdrTopicInfo<msg_type>::type_name();
79 _topic = carla_cdr_create_topic(
80 participant, topic_name.c_str(), type_name, &_sertype);
82 log_error(
"CycloneDDSPublisherMiddleware: Failed to create topic '",
83 topic_name,
"' (code:", _topic,
")");
87 dds_qos_t* qos = dds_create_qos();
91 if (qos_profile !=
nullptr) {
92 dds_qset_reliability(qos,
93 qos_profile->reliability == QosProfile::Reliability::Reliable
94 ? DDS_RELIABILITY_RELIABLE
95 : DDS_RELIABILITY_BEST_EFFORT,
97 dds_qset_durability(qos,
98 qos_profile->durability == QosProfile::Durability::TransientLocal
99 ? DDS_DURABILITY_TRANSIENT_LOCAL
100 : DDS_DURABILITY_VOLATILE);
101 dds_qset_history(qos,
102 qos_profile->history == QosProfile::History::KeepLast
103 ? DDS_HISTORY_KEEP_LAST
104 : DDS_HISTORY_KEEP_ALL,
105 qos_profile->history_depth);
107 dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(1));
108 dds_qset_history(qos, DDS_HISTORY_KEEP_LAST, 1);
112 auto ud = build_user_data_for<msg_type>();
114 dds_qset_userdata(qos, ud.data(), ud.size());
116 dds_listener_t* listener = dds_create_listener(
this);
117 dds_lset_publication_matched(listener, carla_on_publication_matched);
119 _writer = dds_create_writer(participant, _topic, qos, listener);
120 dds_delete_listener(listener);
123 log_error(
"CycloneDDSPublisherMiddleware: Failed to create writer "
124 "(topic '", topic_name,
"', code:", _writer,
")");
128 _topic_name = topic_name;
144 bool Publish(
void* message_data)
override {
145 const msg_type* msg =
static_cast<const msg_type*
>(message_data);
148 struct ddsi_serdata*
sd = carla_cdr_wrap(
151 static_cast<uint32_t
>(cdr.size()));
153 log_error(
"CycloneDDSPublisherMiddleware::Publish (", _topic_name,
154 "): allocation failed");
161 dds_return_t rc = dds_writecdr(_writer,
sd);
162 if (rc != DDS_RETCODE_OK) {
163 ddsi_serdata_unref(
sd);
164 log_error(
"CycloneDDSPublisherMiddleware::Publish (", _topic_name,
165 "): dds_writecdr failed (code:", rc,
")");
171 bool IsAlive()
const override {
172 return _alive.load(std::memory_order_relaxed);
175 std::string GetTopicName()
const override {
180 static void carla_on_publication_matched(
182 const dds_publication_matched_status_t status,
185 CycloneDDSPublisherMiddleware* self =
186 static_cast<CycloneDDSPublisherMiddleware*
>(arg);
187 self->_alive.store(status.current_count > 0, std::memory_order_relaxed);
190 dds_entity_t _topic { DDS_ENTITY_NIL };
191 dds_entity_t _writer { DDS_ENTITY_NIL };
192 struct ddsi_sertype* _sertype {
nullptr };
194 std::string _topic_name;
195 std::atomic<bool> _alive {
false };
std::vector< uint8_t > serialize_to_cdr(const T &msg)
Serialize a msg::X to a CDR byte buffer including the DDS encapsulation header (Classic CDR,...
This file contains definitions of common data structures used in traffic manager.