话题topic订阅 存储订阅者的数据结构源码流程
-
调用create_subscription,
从
node_impl.hpp Node::create_subscription
调用到
create_subscription.hpp rclcpp::create_subscriptionusing SequenceOfWeakSubscriptions = std::vector<WeakSubscriptionEntry>;
SequenceOfWeakSubscriptions subscriptions_;using SequenceOfWeakWaitables = std::vector<WeakWaitableEntry>;
SequenceOfWeakWaitables waitables_; -
在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)的交互。
以上为生成回答,仅供参考~
-