26 #include "rcl/error_handling.h"
28 #include "rcutils/logging_macros.h"
29 #include "rcutils/macros.h"
32 #include "rmw/error_handling.h"
33 #include "tracetools/tracetools.h"
36 #include "./publisher_impl.h"
42 return null_publisher;
49 const rosidl_message_type_support_t * type_support,
50 const char * topic_name,
69 if (publisher->
impl) {
70 RCL_SET_ERROR_MSG(
"publisher already initialized, or memory was unintialized");
78 RCUTILS_LOG_DEBUG_NAMED(
79 ROS_PACKAGE_NAME,
"Initializing publisher for topic name '%s'", topic_name);
82 char * remapped_topic_name = NULL;
89 &remapped_topic_name);
98 RCUTILS_LOG_DEBUG_NAMED(
99 ROS_PACKAGE_NAME,
"Expanded and remapped topic name '%s'", remapped_topic_name);
104 RCL_CHECK_FOR_NULL_WITH_MSG(
110 publisher->
impl->rmw_handle = rmw_create_publisher(
116 RCL_CHECK_FOR_NULL_WITH_MSG(
117 publisher->
impl->rmw_handle, rmw_get_error_string().str,
goto fail);
119 rmw_ret_t rmw_ret = rmw_publisher_get_actual_qos(
120 publisher->
impl->rmw_handle,
121 &publisher->
impl->actual_qos);
122 if (RMW_RET_OK != rmw_ret) {
123 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
126 publisher->
impl->actual_qos.avoid_ros_namespace_conventions =
127 options->
qos.avoid_ros_namespace_conventions;
129 publisher->
impl->options = *options;
130 RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
"Publisher initialized");
135 (
const void *)publisher,
137 (
const void *)publisher->
impl->rmw_handle,
142 if (publisher->
impl) {
143 if (publisher->
impl->rmw_handle) {
144 rmw_ret_t rmw_fail_ret = rmw_destroy_publisher(
146 if (RMW_RET_OK != rmw_fail_ret) {
147 RCUTILS_SAFE_FWRITE_TO_STDERR(rmw_get_error_string().str);
148 RCUTILS_SAFE_FWRITE_TO_STDERR(
"\n");
152 allocator->deallocate(publisher->
impl, allocator->state);
153 publisher->
impl = NULL;
159 allocator->deallocate(remapped_topic_name, allocator->state);
177 RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
"Finalizing publisher");
178 if (publisher->
impl) {
185 rmw_destroy_publisher(rmw_node, publisher->
impl->rmw_handle);
186 if (ret != RMW_RET_OK) {
187 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
190 allocator.deallocate(publisher->
impl, allocator.state);
191 publisher->
impl = NULL;
193 RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
"Publisher finalized");
203 default_options.
qos = rmw_qos_profile_default;
206 return default_options;
212 const rosidl_message_type_support_t * type_support,
218 return rcl_convert_rmw_ret_to_rcl_ret(
219 rmw_borrow_loaned_message(publisher->
impl->rmw_handle, type_support, ros_message));
225 void * loaned_message)
231 return rcl_convert_rmw_ret_to_rcl_ret(
232 rmw_return_loaned_message_from_publisher(publisher->
impl->rmw_handle, loaned_message));
238 const void * ros_message,
239 rmw_publisher_allocation_t * allocation)
248 TRACEPOINT(
rcl_publish, (
const void *)publisher, (
const void *)ros_message);
249 if (rmw_publish(publisher->
impl->rmw_handle, ros_message, allocation) != RMW_RET_OK) {
250 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
260 rmw_publisher_allocation_t * allocation)
266 rmw_ret_t ret = rmw_publish_serialized_message(
267 publisher->
impl->rmw_handle, serialized_message, allocation);
268 if (ret != RMW_RET_OK) {
269 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
270 if (ret == RMW_RET_BAD_ALLOC) {
282 rmw_publisher_allocation_t * allocation)
288 rmw_ret_t ret = rmw_publish_loaned_message(publisher->
impl->rmw_handle, ros_message, allocation);
289 if (ret != RMW_RET_OK) {
290 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
302 if (rmw_publisher_assert_liveliness(publisher->
impl->rmw_handle) != RMW_RET_OK) {
303 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
316 rmw_time_t rmw_timeout;
319 rmw_timeout.nsec = timeout % 1000000000;
320 }
else if (timeout < 0) {
321 rmw_time_t infinite = RMW_DURATION_INFINITE;
322 rmw_timeout = infinite;
324 rmw_time_t zero = RMW_DURATION_UNSPECIFIED;
328 rmw_ret_t ret = rmw_publisher_wait_for_all_acked(publisher->
impl->rmw_handle, rmw_timeout);
329 if (ret != RMW_RET_OK) {
330 if (ret == RMW_RET_TIMEOUT) {
333 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
334 if (ret == RMW_RET_UNSUPPORTED) {
350 return publisher->
impl->rmw_handle->topic_name;
353 #define _publisher_get_options(pub) & pub->impl->options
361 return _publisher_get_options(publisher);
370 return publisher->
impl->rmw_handle;
379 return publisher->
impl->context;
389 RCL_SET_ERROR_MSG(
"publisher's context is invalid");
392 RCL_CHECK_FOR_NULL_WITH_MSG(
393 publisher->
impl->rmw_handle,
"publisher's rmw handle is invalid",
return false);
400 RCL_CHECK_FOR_NULL_WITH_MSG(publisher,
"publisher pointer is invalid",
return false);
401 RCL_CHECK_FOR_NULL_WITH_MSG(
402 publisher->
impl,
"publisher implementation is invalid",
return false);
403 RCL_CHECK_FOR_NULL_WITH_MSG(
404 publisher->
impl->rmw_handle,
"publisher's rmw handle is invalid",
return false);
411 size_t * subscription_count)
418 rmw_ret_t ret = rmw_publisher_count_matched_subscriptions(
419 publisher->
impl->rmw_handle, subscription_count);
421 if (ret != RMW_RET_OK) {
422 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
423 return rcl_convert_rmw_ret_to_rcl_ret(ret);
428 const rmw_qos_profile_t *
434 return &publisher->
impl->actual_qos;
444 bool disable_loaned_message =
false;
446 if (ret ==
RCL_RET_OK && disable_loaned_message) {
450 return publisher->
impl->rmw_handle->can_loan_messages;
#define rcl_get_default_allocator
Return a properly initialized rcl_allocator_t with default values.
#define RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, msg, fail_statement)
Check that the given allocator is initialized, or fail with a message.
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_context_is_valid(const rcl_context_t *context)
Return true if the given context is currently valid, otherwise false.
RCL_PUBLIC bool rcl_node_is_valid(const rcl_node_t *node)
Return true if the node is valid, else false.
RCL_PUBLIC rcl_ret_t rcl_get_disable_loaned_message(bool *disable_loaned_message)
Check if loaned message is disabled, according to the environment variable.
RCL_PUBLIC RCL_WARN_UNUSED rmw_node_t * rcl_node_get_rmw_handle(const rcl_node_t *node)
Return the rmw node handle.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_node_resolve_name(const rcl_node_t *node, const char *input_name, rcl_allocator_t allocator, bool is_service, bool only_expand, char **output_name)
Expand a given name into a fully-qualified topic name and apply remapping rules.
RCL_PUBLIC bool rcl_node_is_valid_except_context(const rcl_node_t *node)
Return true if node is valid, except for the context being valid.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_init(rcl_publisher_t *publisher, const rcl_node_t *node, const rosidl_message_type_support_t *type_support, const char *topic_name, const rcl_publisher_options_t *options)
Initialize a rcl publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish_loaned_message(const rcl_publisher_t *publisher, void *ros_message, rmw_publisher_allocation_t *allocation)
Publish a loaned message on a topic using a publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_wait_for_all_acked(const rcl_publisher_t *publisher, rcl_duration_value_t timeout)
Wait until all published message data is acknowledged or until the specified timeout elapses.
RCL_PUBLIC bool rcl_publisher_is_valid(const rcl_publisher_t *publisher)
Return true if the publisher is valid, otherwise false.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish_serialized_message(const rcl_publisher_t *publisher, const rcl_serialized_message_t *serialized_message, rmw_publisher_allocation_t *allocation)
Publish a serialized message on a topic using a publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_context_t * rcl_publisher_get_context(const rcl_publisher_t *publisher)
Return the context associated with this publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish(const rcl_publisher_t *publisher, const void *ros_message, rmw_publisher_allocation_t *allocation)
Publish a ROS message on a topic using a publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_borrow_loaned_message(const rcl_publisher_t *publisher, const rosidl_message_type_support_t *type_support, void **ros_message)
Borrow a loaned message.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_get_subscription_count(const rcl_publisher_t *publisher, size_t *subscription_count)
Get the number of subscriptions matched to a publisher.
RCL_PUBLIC RCL_WARN_UNUSED rmw_publisher_t * rcl_publisher_get_rmw_handle(const rcl_publisher_t *publisher)
Return the rmw publisher handle.
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_publisher_get_topic_name(const rcl_publisher_t *publisher)
Get the topic name for the publisher.
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_publisher_get_actual_qos(const rcl_publisher_t *publisher)
Get the actual qos settings of the publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_publisher_options_t rcl_publisher_get_default_options(void)
Return the default publisher options in a rcl_publisher_options_t.
RCL_PUBLIC bool rcl_publisher_is_valid_except_context(const rcl_publisher_t *publisher)
Return true if the publisher is valid except the context, otherwise false.
RCL_PUBLIC RCL_WARN_UNUSED const rcl_publisher_options_t * rcl_publisher_get_options(const rcl_publisher_t *publisher)
Return the rcl publisher options.
RCL_PUBLIC RCL_WARN_UNUSED rcl_publisher_t rcl_get_zero_initialized_publisher(void)
Return a rcl_publisher_t struct with members set to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_fini(rcl_publisher_t *publisher, rcl_node_t *node)
Finalize a rcl_publisher_t.
RCL_PUBLIC bool rcl_publisher_can_loan_messages(const rcl_publisher_t *publisher)
Check if publisher instance can loan messages.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_return_loaned_message_from_publisher(const rcl_publisher_t *publisher, void *loaned_message)
Return a loaned message previously borrowed from a publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_assert_liveliness(const rcl_publisher_t *publisher)
Manually assert that this Publisher is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC)
Encapsulates the non-global state of an init/shutdown cycle.
Structure which encapsulates a ROS Node.
rcl_context_t * context
Context associated with this node.
Options available for a rcl publisher.
rmw_qos_profile_t qos
Middleware quality of service settings for the publisher.
rmw_publisher_options_t rmw_publisher_options
rmw specific publisher options, e.g. the rmw implementation specific payload.
rcl_allocator_t allocator
Custom allocator for the publisher, used for incidental allocations.
Structure which encapsulates a ROS Publisher.
rcl_publisher_impl_t * impl
Pointer to the publisher implementation.
#define RCL_NS_TO_S
Convenience macro to convert nanoseconds to seconds.
rcutils_duration_value_t rcl_duration_value_t
A duration of time, measured in nanoseconds.
#define RCL_RET_UNSUPPORTED
Unsupported return code.
#define RCL_RET_UNKNOWN_SUBSTITUTION
Topic name substitution is unknown.
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
#define RCL_RET_OK
Success return code.
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
#define RCL_RET_ERROR
Unspecified error return code.
rmw_serialized_message_t rcl_serialized_message_t
typedef for rmw_serialized_message_t;
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
#define RCL_RET_TOPIC_NAME_INVALID
Topic name does not pass validation.
#define RCL_RET_TIMEOUT
Timeout occurred return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
#define RCL_RET_PUBLISHER_INVALID
Invalid rcl_publisher_t given return code.