19#ifndef CARLA_ROS2_MIDDLEWARE_TESTING
20#ifdef CARLA_ROS2_MIDDLEWARE_ZENOH
37class ZenohPublisherMiddleware :
public IPublisherMiddleware {
39 using msg_type =
typename T::msg_type;
41 ZenohPublisherMiddleware() {
43 z_internal_null(&_publisher);
44 z_internal_null(&_liveliness_token);
45 z_internal_null(&_matching_listener);
47 ZenohPublisherMiddleware(
const ZenohPublisherMiddleware&) =
delete;
48 ZenohPublisherMiddleware& operator=(
const ZenohPublisherMiddleware&) =
delete;
50 ~ZenohPublisherMiddleware()
override {
55 std::lock_guard<std::mutex> lock(_publish_mutex);
56 z_drop(z_move(_matching_listener));
57 z_drop(z_move(_liveliness_token));
58 z_drop(z_move(_publisher));
61 bool Init(
const std::string& topic_name)
override {
62 return InitImpl(topic_name, kZenohDefaultQos);
65 bool Init(
const std::string& topic_name,
const QosProfile& qos)
override {
69 return InitImpl(topic_name, zenoh_qos_keyexpr(qos));
73 bool InitImpl(
const std::string& topic_name,
const std::string& qos_str) {
74 const z_loaned_session_t* session = zenoh_get_shared_session();
76 const std::string topic_no_rt = zenoh_strip_rt_prefix(topic_name);
77 const char* type_name = CdrTopicInfo<msg_type>::type_name();
78 const char* type_hash = CdrTopicInfo<msg_type>::type_hash();
79 if (type_hash ==
nullptr) {
80 log_error(
"ZenohPublisherMiddleware: no type_hash for topic '",
85 const std::string ke_str = zenoh_make_topic_keyexpr(
86 zenoh_ros_domain_id(), topic_no_rt, type_name, type_hash);
88 if (z_view_keyexpr_from_str(&ke, ke_str.c_str()) != Z_OK) {
89 log_error(
"ZenohPublisherMiddleware (", topic_name,
90 "): invalid keyexpr '", ke_str,
"'");
94 z_publisher_options_t pub_opts;
95 z_publisher_options_default(&pub_opts);
96 if (z_declare_publisher(session, &_publisher, z_loan(ke), &pub_opts)
98 log_error(
"ZenohPublisherMiddleware (", topic_name,
99 "): z_declare_publisher failed");
103 const std::string lv_ke_str = zenoh_make_topic_liveliness_keyexpr(
104 zenoh_ros_domain_id(), zenoh_session_zid(), zenoh_next_entity_id(),
105 kZenohEntityKindPub, topic_no_rt, type_name, type_hash,
107 z_view_keyexpr_t lv_ke;
108 if (z_view_keyexpr_from_str(&lv_ke, lv_ke_str.c_str()) != Z_OK) {
109 log_error(
"ZenohPublisherMiddleware (", topic_name,
110 "): invalid liveliness keyexpr");
113 if (z_liveliness_declare_token(session, &_liveliness_token,
114 z_loan(lv_ke),
nullptr) != Z_OK) {
115 log_error(
"ZenohPublisherMiddleware (", topic_name,
116 "): z_liveliness_declare_token failed");
120 z_owned_closure_matching_status_t closure;
121 z_closure_matching_status(&closure, &on_matching_status,
nullptr,
this);
122 if (z_publisher_declare_matching_listener(
123 z_loan(_publisher), &_matching_listener, z_move(closure))
125 log_error(
"ZenohPublisherMiddleware (", topic_name,
126 "): z_publisher_declare_matching_listener failed");
130 _topic_name = topic_name;
135 bool Publish(
void* message_data)
override {
136 std::lock_guard<std::mutex> lock(_publish_mutex);
137 if (!z_internal_check(_publisher)) {
141 const msg_type* msg =
static_cast<const msg_type*
>(message_data);
144 z_owned_bytes_t payload;
145 z_bytes_copy_from_buf(&payload, cdr.data(), cdr.size());
147 const std::vector<uint8_t> attach = zenoh_attachment();
148 z_owned_bytes_t attachment;
149 z_bytes_copy_from_buf(&attachment, attach.data(), attach.size());
151 z_publisher_put_options_t opts;
152 z_publisher_put_options_default(&opts);
153 opts.attachment = z_move(attachment);
155 if (z_publisher_put(z_loan(_publisher), z_move(payload), &opts) != Z_OK) {
156 log_error(
"ZenohPublisherMiddleware::Publish (", _topic_name,
157 "): z_publisher_put failed");
163 bool IsAlive()
const override {
164 return _alive.load(std::memory_order_relaxed);
167 std::string GetTopicName()
const override {
172 static void on_matching_status(
const z_matching_status_t* status,
174 auto* self =
static_cast<ZenohPublisherMiddleware*
>(context);
175 self->_alive.store(status->matching, std::memory_order_relaxed);
178 z_owned_publisher_t _publisher;
179 z_owned_liveliness_token_t _liveliness_token;
180 z_owned_matching_listener_t _matching_listener;
182 mutable std::mutex _publish_mutex;
183 std::atomic<bool> _alive {
false };
184 std::string _topic_name;
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.