鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    话题topic订阅 存储订阅者的数据结构源码流程

    已定时 已固定 已锁定 已移动
    综合问题
    源码分析 订阅话题
    2
    2
    165
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • robot-zzzR
      白日梦想家
      最后由 编辑

      ab4dbdb4-bdc0-402a-af6c-62bc643d677f-image.png

      调用create_subscription,
      从
      node_impl.hpp Node::create_subscription
      调用到
      create_subscription.hpp rclcpp::create_subscription

      ad978c59-a517-4c60-a279-5389807d0c04-image.png

      6cbd3d01-0ec9-4eb1-bb71-b596b5766c65-111.jpg

      80729543-672b-4178-810f-0d6a052be9b8-222.jpg

      86c81103-244f-48b3-9116-7f36d72a83cf-333.jpg

      using SequenceOfWeakSubscriptions = std::vector<WeakSubscriptionEntry>;
      SequenceOfWeakSubscriptions subscriptions_;

      fd0c8fe0-4570-4b41-8215-85dafb102796-555.jpg

      using SequenceOfWeakWaitables = std::vector<WeakWaitableEntry>;
      SequenceOfWeakWaitables waitables_;

      1 条回复 最后回复 回复 引用 0
      • 小伊小
        机器人小伊
        最后由 编辑

        在ROS 2(Robot Operating System 2)中,rclcpp库提供了创建和管理订阅者(subscriptions)的功能。为了理解如何存储订阅者的数据结构及其源码流程,我们需要从Node::create_subscription方法开始,逐步跟踪到实际的订阅创建逻辑。以下是一个简化的流程和源码解析示例,以帮助理解这一过程。

        1. Node::create_subscription (在node_impl.hpp中)

        首先,Node类中的create_subscription方法被调用。这个方法是一个用户接口,用于创建一个新的订阅者。它通常接受一些参数,包括主题名称、消息类型以及一个回调函数。

        // node_impl.hpp
        template<typename MessageT, typename CallbackT>
        std::shared_ptr<typename rclcpp::Subscription<MessageT, CallbackT>::SharedPtr>
        Node::create_subscription(
            const std::string &topic_name,
            std::shared_ptr<rclcpp::QoS> qos,
            CallbackT callback,
            const rclcpp::SubscriptionOptions &subscription_options = rclcpp::SubscriptionOptions())
        {
            // 内部调用 rclcpp::create_subscription
            auto subscription = rclcpp::create_subscription<MessageT, CallbackT>(
                this->get_shared_from_this(), topic_name, qos, callback, subscription_options);
            // 存储订阅者(可能是通过某种内部机制,比如添加到某个成员变量中)
            // 此处省略具体存储逻辑,因为具体实现依赖于Node的内部结构
            return subscription;
        }
        

        2. rclcpp::create_subscription (在create_subscription.hpp中)

        rclcpp::create_subscription是一个模板函数,用于实际创建订阅者对象。这个函数通常处理一些通用逻辑,比如创建订阅者的核心对象,并设置回调。

        // create_subscription.hpp
        template<typename MessageT, typename CallbackT>
        std::shared_ptr<typename rclcpp::Subscription<MessageT, CallbackT>::SharedPtr>
        rclcpp::create_subscription(
            std::shared_ptr<rclcpp::node::NodeBaseInterface> node_base,
            const std::string &topic_name,
            std::shared_ptr<rclcpp::QoS> qos,
            CallbackT callback,
            const rclcpp::SubscriptionOptions &subscription_options)
        {
            // 创建Subscription对象
            auto subscription = std::make_shared<rclcpp::Subscription<MessageT, CallbackT>>(
                node_base, topic_name, std::move(callback), qos, subscription_options);
        
            // 初始化订阅者(例如,注册到RMW层等)
            subscription->initialize();
        
            // 返回订阅者对象
            return subscription;
        }
        

        3. 存储订阅者的数据结构

        在Node类中,通常会使用某种数据结构来存储所有创建的订阅者。这些数据结构可能是std::vector、std::unordered_map或其他容器,具体取决于实现需求。

        在你的示例中,提到了SequenceOfWeakSubscriptions和SequenceOfWeakWaitables,这两个类型分别用于存储弱引用到订阅者和等待对象的指针。弱引用(std::weak_ptr)的使用可以避免循环引用导致的内存泄漏问题。

        // 假设的Node内部数据结构
        class NodeImpl
        {
        public:
            using SequenceOfWeakSubscriptions = std::vector<std::weak_ptr<rclcpp::SubscriptionBase>>;
            using SequenceOfWeakWaitables = std::vector<std::weak_ptr<rclcpp::Waitable>>;
        
            SequenceOfWeakSubscriptions subscriptions_;
            SequenceOfWeakWaitables waitables_;
        
            // 添加订阅者的方法
            void add_subscription(std::shared_ptr<rclcpp::SubscriptionBase> subscription)
            {
                subscriptions_.emplace_back(subscription);
                // 可能还需要将订阅者转换为Waitable并添加到waitables_中
            }
        };
        

        4. 总结

        • Node::create_subscription是用户接口,用于创建订阅者。
        • rclcpp::create_subscription是实际创建订阅者对象的函数。
        • 订阅者对象被存储在Node的内部数据结构中,如SequenceOfWeakSubscriptions。
        • 使用弱引用(std::weak_ptr)来避免循环引用问题。

        这个流程提供了一个高层次的概述,实际的ROS 2实现可能会更加复杂,包括更多的错误处理、线程安全考虑以及与底层RMW(Robot Middleware)的交互。


        以上为生成回答,仅供参考~

        我是小伊,已接入ChatGpt,所有回复,仅供参考~

        1 条回复 最后回复 回复 引用 0
        • 小鱼小 小鱼 将这个主题转为普通主题,在
        • 第一个帖子
          最后一个帖子
        皖ICP备16016415号-7
        Powered by NodeBB | 鱼香ROS