Search code examples
c++rosros2

Allocator in create publisher ROS2


Based on ROS2 documentation there is a third argument called an allocator that can be used when creatinga publisher. How can this allocator be used ? Does it allocate memory for the publisher ?

std::shared_ptr< PublisherT > rclcpp::node::Node::create_publisher  (   const std::string &     topic_name,
const rmw_qos_profile_t &   qos_profile = rmw_qos_profile_default,
std::shared_ptr< Alloc >    allocator = nullptr 
)   

Solution

  • The custom allocator will be used for all heap allocations within the context of the publisher. This is the same as how you would use a custom allocator with an std::vector as seen here. For ROS2, take the following example of a custom allocator.

    template<typename T>
    struct pointer_traits {
      using reference = T &;
      using const_reference = const T &;
    };
    
    // Avoid declaring a reference to void with an empty specialization
    template<>
    struct pointer_traits<void> {
    };
    
    template<typename T = void>
    struct MyAllocator : public pointer_traits<T> {
    public:
      using value_type = T;
      using size_type = std::size_t;
      using pointer = T *;
      using const_pointer = const T *;
      using difference_type = typename std::pointer_traits<pointer>::difference_type;
    
      MyAllocator() noexcept;
    
      ~MyAllocator() noexcept;
    
      template<typename U>
      MyAllocator(const MyAllocator<U> &) noexcept;
    
      T * allocate(size_t size, const void * = 0);
    
      void deallocate(T * ptr, size_t size);
    
      template<typename U>
      struct rebind {
        typedef MyAllocator<U> other;
      };
    };
    
    template<typename T, typename U>
    constexpr bool operator==(const MyAllocator<T> &,
      const MyAllocator<U> &) noexcept;
    
    template<typename T, typename U>
    constexpr bool operator!=(const MyAllocator<T> &,
      const MyAllocator<U> &) noexcept;
    

    Then, your main setup would look essentially the same as it would without a custom allocator.

    auto alloc = std::make_shared<MyAllocator<void>>();
    auto publisher = node->create_publisher<std_msgs::msg::UInt32>("allocator_example", 10, alloc);
    auto msg_mem_strat =
      std::make_shared<rclcpp::message_memory_strategy::MessageMemoryStrategy<std_msgs::msg::UInt32,
      MyAllocator<>>>(alloc);
    std::shared_ptr<rclcpp::memory_strategy::MemoryStrategy> memory_strategy =
    std::make_shared<AllocatorMemoryStrategy<MyAllocator<>>>(alloc);
    

    For a more complete example I would suggest looking at the TLSF allocator which is designed to be useful for hard real time systems. It can be found here and a full example can be found here