在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)的交互。
以上为生成回答,仅供参考~