ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

C++ 第 31B 课:只看一份最小 Publisher 程序

C++ 第 31B 课:只看一份最小 Publisher 程序 先给上一课 4 个问题的标准答案。std_msgs::msg::Int32 msg;意思是创建一个 ROS2 的整数消息对象名字叫msg。可以把它理解成一个“整数消息盒子”。msg.data 100;意思是把数字100放进msg这个消息盒子的data成员里。this-create_publisher...()大概意思是让当前这个 ROS2 节点创建一个 Publisher。其中this 当前这个节点对象 - 通过指针访问对象成员 create_publisher 创建发布器publisher_-publish(msg);意思是通过publisher_这个发布器把msg消息发送出去。可以直接脑补成消息盒子 msg ↓ publisher_ ↓ 发送出去第 31B 课只看一份最小 Publisher 程序今天不碰 Subscriber。我们的目标只有一个让一个 ROS2 节点不断发布整数。先看完整代码不要求你立刻全部懂#include rclcpp/rclcpp.hpp #include std_msgs/msg/int32.hpp class NumberPublisher : public rclcpp::Node { public: NumberPublisher() : Node(number_publisher) { publisher_ this-create_publisherstd_msgs::msg::Int32( number, 10 ); } void publishNumber() { std_msgs::msg::Int32 msg; msg.data 100; publisher_-publish(msg); } private: rclcpp::Publisherstd_msgs::msg::Int32::SharedPtr publisher_; };今天只拆这份代码。1. 第一行#include rclcpp/rclcpp.hpp你以前学过#include iostream意思是引入某个库提供的功能。这里#include rclcpp/rclcpp.hpp就是引入 ROS2 C 客户端库rclcpp。以后很多 ROS2 C 节点都离不开它。2. 第二行#include std_msgs/msg/int32.hpp意思是引入 ROS2 的Int32消息类型。也就是后面这个std_msgs::msg::Int32如果不包含对应头文件编译器就不知道Int32是什么。3. 定义自己的节点类class NumberPublisher : public rclcpp::Node你已经学过。翻译定义一个叫NumberPublisher的类它继承 ROS2 的rclcpp::Node。也就是说NumberPublisher ROS2普通Node 我们自己加的发布数字功能4. 构造函数NumberPublisher() : Node(number_publisher)这里NumberPublisher()是构造函数。而: Node(number_publisher)表示初始化父类Node并给这个 ROS2 节点取名number_publisher。所以创建NumberPublisher node;时它在 ROS2 世界里的名字大概就是/number_publisher5. 构造函数里面创建 Publisherpublisher_ this-create_publisherstd_msgs::msg::Int32( number, 10 );这一句你现在应该能拆一点了。先看this-create_publisher意思当前这个 Node 创建一个 Publisher。然后std_msgs::msg::Int32表示这个 Publisher 专门发Int32消息。再看number表示 Topic 名字。也就是/number这个频道。最后10先理解为ROS2 通信队列参数暂时默认写 10。现在不需要深入。6. 为什么要保存到publisher_因为this-create_publisher(...)创建出来的是一个 Publisher。我们以后还要反复用它发消息。所以要保存起来publisher_可以理解成“我这个节点自己的发布器”。7.publishNumber()是我们自己写的函数void publishNumber()这个不是 ROS2 强制规定的名字。是我们自己写的普通成员函数。它的任务发布一个数字。8. 第一步创建消息std_msgs::msg::Int32 msg;就是创建一个整数消息盒子。此时可以想象msg ┌────────────┐ │ data ? │ └────────────┘9. 第二步往消息里放数据msg.data 100;现在msg ┌────────────┐ │ data 100 │ └────────────┘10. 第三步发出去publisher_-publish(msg);先看左边publisher_它是一个智能指针。所以用-找到 Publisher 对象。然后publish(msg)表示发布msg。所以整句用这个节点的 Publisher把msg发到/numberTopic。11. 整个publishNumber()其实只有三步void publishNumber() { std_msgs::msg::Int32 msg; msg.data 100; publisher_-publish(msg); }你可以翻译成1. 创建一个消息盒子 2. 往里面放100 3. 把盒子发出去这就是 ROS2 Publisher 最核心的本质。12. private 里的这一句rclcpp::Publisherstd_msgs::msg::Int32::SharedPtr publisher_;这句先不要追求完全看懂。现在只读成publisher_是一个“发布 Int32 消息的 ROS2 Publisher 智能指针”。拆开rclcpp::Publisher → ROS2 Publisher 类型 std_msgs::msg::Int32 → 专门发布 Int32 ::SharedPtr → 智能指针版本 publisher_ → 变量名够了。13. 为什么不是普通对象你可能会问为什么不直接Publisher publisher_;因为 ROS2 内部常常会通过智能指针管理这些对象的生命周期。所以你会看到SharedPtr这和我们前面学的std::shared_ptrRobot本质思想是一致的。14. 这份程序现在还差什么很重要这段类代码虽然已经能“定义一个会发布消息的节点”但现在publishNumber()并不会自动执行。也就是说目前只是节点会发布但没有规定什么时候发布例如每1秒发布一次 按按钮时发布 收到VLA结果时发布我们现在还没写。15. 这正好对应 VLA以后你的 VLA 场景可能不是每秒发布100而是VLA推理完成 ↓ 得到动作 ↓ 调用 publishAction() ↓ 发布动作消息所以 Publisher 的角色就是把你程序内部算出来的数据送进 ROS2 通信系统。16. 现在把整份代码压缩成人话class NumberPublisher : public rclcpp::Node我定义一个 ROS2 节点。: Node(number_publisher)它叫number_publisher。create_publisherInt32(number, 10)创建一个往/number发整数的 Publisher。std_msgs::msg::Int32 msg;创建整数消息。msg.data 100;填入 100。publisher_-publish(msg);发出去。这就是整节课。本课小练习1class NumberPublisher : public rclcpp::Node这句话是什么意思2: Node(number_publisher)是给什么东西设置名字3create_publisherstd_msgs::msg::Int32( number, 10 );这里Int32 number分别代表什么4下面三句按顺序分别干什么std_msgs::msg::Int32 msg; msg.data 100; publisher_-publish(msg);5为什么publisher_后面调用publish()时使用-而不是.
返回列表