[具身智能-78]:ROS2 DDS的发布者、订阅者、服务服务器、服务客户端、动作服务器、动作客户端,它们是节点的能力,分别运行在各自的节点中。
在 ROS 2 的架构中节点 (Node)是基本的执行单元和拥有者。这里提到的所有通信角色发布者、订阅者、服务服务器/客户端、动作服务器/客户端本质上都是节点内部的功能模块或对象。它们不是独立的进程也不是独立运行的线程虽然它们可能由不同的线程执行回调它们依附于节点而存在。1. 核心关系节点是“容器”其他是“组件”你可以这样形象地理解节点 (Node) 一个运行中的程序实例或者更准确地说是程序中的一个逻辑单元。发布者/订阅者/服务/动作 这个程序实例内部创建的功能接口。生命周期绑定当节点被创建create_node并启动时这些能力才被初始化。当节点被关闭destroy_node或进程结束时这些能力自动销毁它们占用的资源内存、网络连接、DDS实体被释放。你无法在节点之外单独拥有一个“漂浮”的发布者。2. 代码层面的体现在 C (rclcpp) 或 Python (rclpy) 代码中这种包含关系非常清晰C 示例:cppclass MyNode : public rclcpp::Node { public: MyNode() : Node(my_node) { // 1. 发布者是节点的一个成员变量 pub_ this-create_publisherstd_msgs::msg::String(topic_name, 10); // 2. 订阅者是节点的一个成员变量并绑定到节点的执行器 sub_ this-create_subscriptionstd_msgs::msg::String( topic_name, 10, std::bind(MyNode::callback, this, std::placeholders::_1)); // 3. 服务服务器是节点的一个成员变量 srv_ this-create_serviceexample_interfaces::srv::AddTwoInts( service_name, std::bind(MyNode::handle_service, this, std::placeholders::_1, std::placeholders::_2)); // 4. 动作服务器也是节点的一部分 action_server_ rclcpp_action::create_serverexample_interfaces::action::Fibonacci( this, action_name, ...); } private: // 所有这些指针都生活在节点类的内部 rclcpp::Publisherstd_msgs::msg::String::SharedPtr pub_; rclcpp::Subscriptionstd_msgs::msg::String::SharedPtr sub_; rclcpp::Serviceexample_interfaces::srv::AddTwoInts::SharedPtr srv_; rclcpp_action::Serverexample_interfaces::action::Fibonacci::SharedPtr action_server_; void callback(const std_msgs::msg::String::SharedPtr msg) { /* ... */ } void handle_service(...) { /* ... */ } };Python 示例:pythonclass MyNode(rclpy.node.Node): def __init__(self): super().__init__(my_node) # 所有能力都作为 self 的属性存在 self.pub_ self.create_publisher(String, topic_name, 10) self.sub_ self.create_subscription(String, topic_name, self.callback, 10) self.srv_ self.create_service(AddTwoInts, service_name, self.handle_service) # ...3. 它们是如何“运行”的执行器 Executor 的作用虽然它们定义在节点内部但它们需要执行器 (Executor)来驱动其被动行为发布者 (Publisher)通常是主动的。它在发送数据。你在代码中调用pub_-publish(msg)时它立即工作。它不需要执行器轮询但需要节点提供的底层上下文。订阅者 (Subscriber)是被动的。它在等待数据。节点的执行器会不断轮询底层的DDS 接收队列。一旦发现有新数据到达该订阅者对应的通道执行器就会触发你注册的回调函数。服务/动作服务器同样是被动等待请求。执行器检测到请求后调用处理函数。服务/动作客户端发送请求后进入等待响应状态执行器负责监听响应并触发完成回调。结论如果没有节点调用spin()(启动执行器)订阅者、服务器和客户端将无法处理任何传入的数据或请求尽管它们在内存中已经存在。4. 为什么要这样设计这种设计带来了几个关键优势资源管理自动化节点销毁时自动清理所有相关的发布/订阅关系防止资源泄漏。命名空间继承节点通常有一个命名空间如/robot1/sensor。节点内创建的所有主题、服务、动作会自动加上这个前缀无需手动拼接字符串保证了全局命名的模块化。参数共享节点内的所有组件可以方便地访问该节点的参数Parameters实现统一配置。逻辑内聚将相关的功能如“激光雷达驱动”节点包含“发布扫描数据”和“提供重置服务”封装在一个逻辑单元中符合高内聚低耦合的软件工程原则。总结发布者、订阅者、服务、动作→→ 是节点的能力/属性。运行位置→→ 它们运行在节点的上下文中占用节点的内存依赖节点的执行器进行调度。独立性→→ 它们不能脱离节点独立存在。这正是 ROS 2 组件化设计的核心思想。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2434945.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!