|
@@ -1,14 +1,14 @@
|
|
|
# 4.2.2 ROS2话题通信(C++实现)
|
|
|
|
|
|
-本节小鱼将带你一起实现C++版本话题通信功能,帮助王二拿到他最想看的艳娘传奇,并通过话题支付稿费给李四。最终实现像下图这样的计算图。
|
|
|
+本节小鱼将带你一起实现C++版本话题通信功能,帮助单身汉王二拿到他最想看的艳娘传奇,并通过话题支付稿费给李四。最终实现像下图这样的计算图。
|
|
|
|
|
|
-/imgs/image-20210804061637113.png)
|
|
|
+/imgs/image-20210804061637113.png)
|
|
|
|
|
|
## 1.订阅话题
|
|
|
|
|
|
### 1.1 如何编写
|
|
|
|
|
|
-在C++中如何实现话题的订阅呢?其实做法和Python中差不多。还记得第三章中我们新建的王二节点类的定义吗?
|
|
|
+在C++中如何实现话题的订阅呢?其实做法和Python中差不多。还记得第三章中我们新建的SingleDogNode类的定义吗?
|
|
|
|
|
|
```
|
|
|
class SingleDogNode : public rclcpp::Node
|
|
@@ -16,28 +16,28 @@ class SingleDogNode : public rclcpp::Node
|
|
|
|
|
|
SingleDogNode继承了Node节点,其实Node可以理解为一个类,SingleDogNode继承了Node后就会拥有Node类所具备的能力和知识。
|
|
|
|
|
|
-和python中李四继承的Node类一样,本节中会使用SingleDogNode继承而来的三种能力:
|
|
|
+和python中WriterNode继承的Node类一样,本节中会使用SingleDogNode继承而来的三种能力:
|
|
|
|
|
|
-- 创建一个话题订阅者的能力,用于拿到艳娘传奇的数据
|
|
|
+1. 创建一个话题订阅者的能力,用于拿到艳娘传奇的数据
|
|
|
|
|
|
- ```
|
|
|
- rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
|
|
|
- sub_ = this->create_subscription<std_msgs::msg::String>("sexy_girl", 10, std::bind(&SingleDogNode::topic_callback, this, _1));
|
|
|
- ```
|
|
|
+ ```
|
|
|
+ rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
|
|
|
+ sub_ = this->create_subscription<std_msgs::msg::String>("sexy_girl", 10, std::bind(&SingleDogNode::topic_callback, this, _1));
|
|
|
+ ```
|
|
|
|
|
|
-- 创建一个话题发布者的能力,用于给李四送稿费
|
|
|
+2. 创建一个话题发布者的能力,用于给李四送稿费
|
|
|
|
|
|
- ```
|
|
|
- rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr pub_;
|
|
|
- pub_ = this->create_publisher<std_msgs::msg::UInt32>("sexy_girl_money",10);
|
|
|
- ```
|
|
|
+ ```
|
|
|
+ rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr pub_;
|
|
|
+ pub_ = this->create_publisher<std_msgs::msg::UInt32>("sexy_girl_money",10);
|
|
|
+ ```
|
|
|
|
|
|
-- 获取日志打印器的能力
|
|
|
+3. 获取日志打印器的能力
|
|
|
|
|
|
- ```
|
|
|
- // 打印一句自我介绍
|
|
|
- RCLCPP_INFO(this->get_logger(), "大家好,我是单身汉王二.");
|
|
|
- ```
|
|
|
+ ```
|
|
|
+ // 打印一句自我介绍
|
|
|
+ RCLCPP_INFO(this->get_logger(), "大家好,我是单身汉王二.");
|
|
|
+ ```
|
|
|
|
|
|
更多的能力可以参考rclcpp的API:https://docs.ros2.org/foxy/api/rclcpp/index.html
|
|
|
|
|
@@ -52,7 +52,6 @@ SingleDogNode继承了Node节点,其实Node可以理解为一个类,SingleDo
|
|
|
|
|
|
用VsCode打开上一章中town_ws工作空间,并打开wang2.cpp。我们在其中添加代码即可。
|
|
|
|
|
|
-
|
|
|
添加完成后SingleDogNode类中代码如下:
|
|
|
|
|
|
```
|
|
@@ -60,7 +59,10 @@ SingleDogNode继承了Node节点,其实Node可以理解为一个类,SingleDo
|
|
|
#include "std_msgs/msg/string.hpp"
|
|
|
#include "std_msgs/msg/u_int32.hpp"
|
|
|
|
|
|
+
|
|
|
using std::placeholders::_1;
|
|
|
+using std::placeholders::_2;
|
|
|
+
|
|
|
/*
|
|
|
创建一个类节点,名字叫做SingleDogNode,继承自Node.
|
|
|
*/
|
|
@@ -68,22 +70,25 @@ class SingleDogNode : public rclcpp::Node
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
- SingleDogNode() : Node("wang2")
|
|
|
+ // 构造函数,有一个参数为节点名称
|
|
|
+ SingleDogNode(std::string name) : Node(name)
|
|
|
{
|
|
|
// 打印一句自我介绍
|
|
|
- RCLCPP_INFO(this->get_logger(), "大家好,我是单身汉王二.");
|
|
|
- // 创建一个订阅者来订阅李四写的小说,通过名字sexy_girl
|
|
|
- sub_ = this->create_subscription<std_msgs::msg::String>("sexy_girl", 10, std::bind(&SingleDogNode::topic_callback, this, _1));
|
|
|
+ RCLCPP_INFO(this->get_logger(), "大家好,我是单身狗%s.", name.c_str());
|
|
|
+ // 创建一个订阅者来订阅李四写的小说,通过名字sexy_girl
|
|
|
+ sub_novel = this->create_subscription<std_msgs::msg::String>("sexy_girl", 10, std::bind(&SingleDogNode::topic_callback, this, _1));
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
// 声明一个订阅者(成员变量),用于订阅小说
|
|
|
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_novel;
|
|
|
-
|
|
|
- void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
|
|
|
+
|
|
|
+ // 收到话题数据的回调函数
|
|
|
+ void topic_callback(const std_msgs::msg::String::SharedPtr msg)
|
|
|
{
|
|
|
- RCLCPP_INFO(this->get_logger(), "王二::'%s'", msg->data.c_str());
|
|
|
- }
|
|
|
+ RCLCPP_INFO(this->get_logger(), "朕已阅:'%s'", msg->data.c_str());
|
|
|
+ };
|
|
|
+
|
|
|
};
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
@@ -175,39 +180,55 @@ pub_ = this->create_publisher<std_msgs::msg::UInt32>("sexy_girl_money",10);
|
|
|
我们来看一下增加发布者之后的完整代码
|
|
|
|
|
|
```
|
|
|
+#include "rclcpp/rclcpp.hpp"
|
|
|
+#include "std_msgs/msg/string.hpp"
|
|
|
+#include "std_msgs/msg/u_int32.hpp"
|
|
|
+
|
|
|
+
|
|
|
+using std::placeholders::_1;
|
|
|
+using std::placeholders::_2;
|
|
|
+
|
|
|
+/*
|
|
|
+ 创建一个类节点,名字叫做SingleDogNode,继承自Node.
|
|
|
+*/
|
|
|
class SingleDogNode : public rclcpp::Node
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
- SingleDogNode() : Node("wang2")
|
|
|
+ // 构造函数,有一个参数为节点名称
|
|
|
+ SingleDogNode(std::string name) : Node(name)
|
|
|
{
|
|
|
// 打印一句自我介绍
|
|
|
- RCLCPP_INFO(this->get_logger(), "大家好,我是单身汉王二.");
|
|
|
- // 创建一个订阅者来订阅李四写的小说,通过名字sexy_girl
|
|
|
- sub_ = this->create_subscription<std_msgs::msg::String>("sexy_girl", 10, std::bind(&SingleDogNode::topic_callback, this, _1));
|
|
|
- pub_ = this->create_publisher<std_msgs::msg::UInt32>("sexy_girl_money",10);
|
|
|
+ RCLCPP_INFO(this->get_logger(), "大家好,我是单身狗%s.", name.c_str());
|
|
|
+ // 创建一个订阅者来订阅李四写的小说,通过名字sexy_girl
|
|
|
+ sub_novel = this->create_subscription<std_msgs::msg::String>("sexy_girl", 10, std::bind(&SingleDogNode::topic_callback, this, _1));
|
|
|
+ // 创建发布者
|
|
|
+ pub_money = this->create_publisher<std_msgs::msg::UInt32>("sexy_girl_money", 10);
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
- // 声明一个订阅者(成员变量)
|
|
|
- rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_;
|
|
|
+ // 声明一个订阅者(成员变量),用于订阅小说
|
|
|
+ rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_novel;
|
|
|
|
|
|
- rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr pub_;
|
|
|
+ // 声明一个发布者(成员变量),用于给李四钱
|
|
|
+ rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr pub_money;
|
|
|
|
|
|
- void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
|
|
|
+ // 收到话题数据的回调函数
|
|
|
+ void topic_callback(const std_msgs::msg::String::SharedPtr msg)
|
|
|
{
|
|
|
// 新建一张人民币
|
|
|
std_msgs::msg::UInt32 money;
|
|
|
money.data = 10;
|
|
|
// 发送人民币给李四
|
|
|
- pub_->publish(money);
|
|
|
- RCLCPP_INFO(this->get_logger(), "王二:我收到了:'%s' ,并给了李四:%d 元的稿费", msg->data.c_str(),money.data);
|
|
|
- }
|
|
|
+ pub_money->publish(money);
|
|
|
+
|
|
|
+ RCLCPP_INFO(this->get_logger(), "朕已阅:'%s',打赏李四:%d 元的稿费", msg->data.c_str(), money.data);
|
|
|
+ };
|
|
|
|
|
|
};
|
|
|
```
|
|
|
|
|
|
-主要将回调函数修改了一下,每次收到了小说之后,王二就会发10块钱到`sexy_girl_money`话题上。
|
|
|
+程序主要将回调函数修改了一下,每次收到了小说之后,王二就会发10块钱到`sexy_girl_money`话题上。
|
|
|
|
|
|
## 4.发布测试
|
|
|
|