15 #ifndef RCLCPP__EXPERIMENTAL__SUBSCRIPTION_INTRA_PROCESS_BUFFER_HPP_
16 #define RCLCPP__EXPERIMENTAL__SUBSCRIPTION_INTRA_PROCESS_BUFFER_HPP_
23 #include "rcl/error_handling.h"
27 #include "rclcpp/experimental/buffers/intra_process_buffer.hpp"
28 #include "rclcpp/experimental/create_intra_process_buffer.hpp"
29 #include "rclcpp/experimental/subscription_intra_process_base.hpp"
30 #include "rclcpp/experimental/ros_message_intra_process_buffer.hpp"
31 #include "rclcpp/qos.hpp"
32 #include "rclcpp/detail/add_guard_condition_to_rcl_wait_set.hpp"
34 #include "tracetools/tracetools.h"
38 namespace experimental
42 typename SubscribedType,
43 typename Alloc = std::allocator<SubscribedType>,
44 typename Deleter = std::default_delete<SubscribedType>,
47 typename ROSMessageType = SubscribedType
50 typename allocator::AllocRebind<ROSMessageType, Alloc>::allocator_type,
51 allocator::Deleter<typename allocator::AllocRebind<ROSMessageType, Alloc>::allocator_type,
57 using SubscribedTypeAllocatorTraits = allocator::AllocRebind<SubscribedType, Alloc>;
58 using SubscribedTypeAllocator =
typename SubscribedTypeAllocatorTraits::allocator_type;
59 using SubscribedTypeDeleter = allocator::Deleter<SubscribedTypeAllocator, SubscribedType>;
61 using ROSMessageTypeAllocatorTraits = allocator::AllocRebind<ROSMessageType, Alloc>;
62 using ROSMessageTypeAllocator =
typename ROSMessageTypeAllocatorTraits::allocator_type;
63 using ROSMessageTypeDeleter = allocator::Deleter<ROSMessageTypeAllocator, ROSMessageType>;
65 using ConstMessageSharedPtr = std::shared_ptr<const ROSMessageType>;
66 using MessageUniquePtr = std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>;
68 using ConstDataSharedPtr = std::shared_ptr<const SubscribedType>;
69 using SubscribedTypeUniquePtr = std::unique_ptr<SubscribedType, SubscribedTypeDeleter>;
78 std::shared_ptr<Alloc> allocator,
79 rclcpp::Context::SharedPtr context,
80 const std::string & topic_name,
84 ROSMessageTypeDeleter>(
85 context, topic_name, qos_profile),
86 subscribed_type_allocator_(*allocator)
88 allocator::set_allocator_for_deleter(&subscribed_type_deleter_, &subscribed_type_allocator_);
91 buffer_ = rclcpp::experimental::create_intra_process_buffer<SubscribedType, Alloc,
92 SubscribedTypeDeleter>(
95 std::make_shared<Alloc>(subscribed_type_allocator_));
96 TRACETOOLS_TRACEPOINT(
97 rclcpp_ipb_to_subscription,
98 static_cast<const void *
>(buffer_.get()),
99 static_cast<const void *
>(
this));
105 if (this->buffer_->has_data()) {
106 this->trigger_guard_condition();
108 detail::add_guard_condition_to_rcl_wait_set(wait_set, this->gc_);
112 is_ready([[maybe_unused]]
const rcl_wait_set_t & wait_set)
override
114 return buffer_->has_data();
117 SubscribedTypeUniquePtr
118 convert_ros_message_to_subscribed_type_unique_ptr(
const ROSMessageType & msg)
120 if constexpr (!std::is_same<SubscribedType, ROSMessageType>::value) {
121 auto ptr = SubscribedTypeAllocatorTraits::allocate(subscribed_type_allocator_, 1);
122 SubscribedTypeAllocatorTraits::construct(subscribed_type_allocator_, ptr);
124 return SubscribedTypeUniquePtr(ptr, subscribed_type_deleter_);
126 throw std::runtime_error(
127 "convert_ros_message_to_subscribed_type_unique_ptr "
128 "unexpectedly called without TypeAdapter");
133 provide_intra_process_message(ConstMessageSharedPtr message)
override
135 if constexpr (std::is_same<SubscribedType, ROSMessageType>::value) {
136 buffer_->add_shared(std::move(message));
137 trigger_guard_condition();
139 buffer_->add_shared(convert_ros_message_to_subscribed_type_unique_ptr(*message));
140 trigger_guard_condition();
142 this->invoke_on_new_message();
146 provide_intra_process_message(MessageUniquePtr message)
override
148 if constexpr (std::is_same<SubscribedType, ROSMessageType>::value) {
149 buffer_->add_unique(std::move(message));
150 trigger_guard_condition();
152 buffer_->add_unique(convert_ros_message_to_subscribed_type_unique_ptr(*message));
153 trigger_guard_condition();
155 this->invoke_on_new_message();
159 provide_intra_process_data(ConstDataSharedPtr message)
161 buffer_->add_shared(std::move(message));
162 trigger_guard_condition();
163 this->invoke_on_new_message();
167 provide_intra_process_data(SubscribedTypeUniquePtr message)
169 buffer_->add_unique(std::move(message));
170 trigger_guard_condition();
171 this->invoke_on_new_message();
175 use_take_shared_method()
const override
177 return buffer_->use_take_shared_method();
180 size_t available_capacity()
const override
182 return buffer_->available_capacity();
187 trigger_guard_condition()
override
192 BufferUniquePtr buffer_;
193 SubscribedTypeAllocator subscribed_type_allocator_;
194 SubscribedTypeDeleter subscribed_type_deleter_;
RCLCPP_PUBLIC void trigger()
Signal that the condition has been met, notifying both the wait set and listeners,...
Encapsulation of Quality of Service settings.
void add_to_wait_set(rcl_wait_set_t &wait_set) override
Add the Waitable to a wait set.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
Container for subscription's, guard condition's, etc to be waited on.
Template structure used to adapt custom, user-defined types to ROS types.