sangxin 3 år sedan
förälder
incheckning
d9fbfa161d

+ 64 - 67
docs/chapt4/4.10服务实现(C++).md

@@ -2,34 +2,24 @@
 
 看到张三买书就突然想起`华强买瓜`,但张三是真心买书不是存心找茬。开始编写代码之前,我们先梳理一下买书任务流程。
 
-**一句话:张三拿多少钱钱给王二,王二凑够多少个章节的艳娘传奇给他**
-
-## 1.如何编写C++服务
-
-### 1.1编写C++服务端
+## 1.任务流程
 
-- 创建服务节点
-- 添加服务接口与依赖
-- 创建服务与回调函数
-- 实例化服务端并编写回调函数处理请求
-- 修改`CMakeLists.txt`并编译
-
-### 1.2编写C++客户端
+**一句话:张三拿多少钱钱给王二,王二凑够多少个章节的艳娘传奇给他**
 
-- 创建客户端节点
-- 添加服务接口与依赖
-- 创建客户端、请求函数和请求结果回调函数
-- 实例化客户端、编写请求函数和回调函数
-- 修改`CMakeLists.txt`并编译
 
 ## 2.服务端(王二)实现
 
 首先是作为二手书提供者的服务端王二节点代码的编写,我们按照上面所说的步骤开始编写程序。
 
-### 2.1 创建服务节点
+### 2.1 创建C++服务通信服务端的步骤
 
-服务肯定是由节点提供,所以肯定要有节点,在3.6章节中,王二已经在前面的章节中被创建了出来,这里无需再次创建节点。
+1. 导入服务接口
 
+2. 创建服务端回调函数
+
+3. 声明并创建服务端
+
+4. 编写回调函数逻辑处理请求
 
 ### 2.2 添加服务接口与依赖
 
@@ -80,17 +70,13 @@ ament_target_dependencies(wang2_node
 
 
 
-### 2.3 声明服务与回调函数
+### 2.3 声明回调函数
 
-#### 2.3.1 声明服务与回调函数
+#### 2.3.1 声明回调函数
 
-添加完服务接口接着就可以声明服务和回调函数。
-
-在Wang2Node中声明一个服务和一个**卖书请求回调函数**。
+添加完服务接口接着就可以声明一个**卖书请求回调函数**。
 
 ```c++
-// 声明一个服务端
-rclcpp::Service<village_interfaces::srv::SellNovel>::SharedPtr server_;
 // 声明一个回调函数,当收到买书请求时调用该函数,用于处理数据
 void sell_book_callback(const village_interfaces::srv::SellNovel::Request::SharedPtr request,
         const village_interfaces::srv::SellNovel::Response::SharedPtr response)
@@ -127,24 +113,24 @@ std::queue<std::string>  novels_queue;
 
 #### 2.3.5 回调函数组
 
-ROS2中要使用多线程执行器和回调组来实现多线程,我们先在`Wang2Node`中声明一个回调组成员变量。
+ROS2中要使用多线程执行器和回调组来实现多线程,我们先在`SingleDogNode`中声明一个回调组成员变量。
 
 ```c++
 // 声明一个服务回调组
 rclcpp::CallbackGroup::SharedPtr callback_group_service_;
 ```
 
-完成 声明之后,我们的`Wang2Node`新增内容如下:
+完成 声明之后,我们的`SingleDogNode`新增内容如下:
 
 #### 2.3.6 最终结果
 
 ```c++
-class Wang2Node : public rclcpp::Node 
+class SingleDogNode : public rclcpp::Node 
 {
 
 public:
     // 构造函数
-    Wang2Node() : Node("wang2")
+    SingleDogNode(std::string name) : Node(name)
     {
     }
     
@@ -164,21 +150,19 @@ private:
 };
 ```
 
-
-
 ### 2.4 实例化服务端并编写回调函数处理请求
 
 #### 2.4.1 实例化回调组
 
 在`ROS2`中,回调函数组也是一个对象,通过实例化`create_callback_group`类即可创建一个callback_group_service的对象。
 
-在Wang2Node的构造函数中添加下面这行代码,即可完成实例化
+在SingleDogNode的构造函数中添加下面这行代码,即可完成实例化
 
 ```
 callback_group_service_ = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
 ```
 
-#### 2.4.2 实例化服务端
+#### 2.4.2 声明并实例化服务端
 
 我们使用成员函数作为回调函数,这里要根据回调函数中参数个数,设置占位符,即告诉编译器,这个函数需要传入的参数个数。
 
@@ -189,12 +173,19 @@ using std::placeholders::_1;
 using std::placeholders::_2;
 ```
 
-**实例化服务端**
+在`private:`下**声明服务端**
+
+```
+// 声明一个服务端
+rclcpp::Service<village_interfaces::srv::SellNovel>::SharedPtr server_;
+```
+
+在构造函数中**实例化服务端**
 
 ```C++
 // 实例化卖二手书的服务
 server_ = this->create_service<village_interfaces::srv::SellNovel>("sell_novel",
-                            std::bind(&Wang2Node::sell_book_callback,this,_1,_2),
+                            std::bind(&SingleDogNode::sell_book_callback,this,_1,_2),
                             rmw_qos_profile_services_default,
                             callback_group_service_);
 ```
@@ -202,7 +193,7 @@ server_ = this->create_service<village_interfaces::srv::SellNovel>("sell_novel",
 实例化服务端可以直接使用`create_service`函数,该函数是一个模版函数,需要输入要创建的服务类型,这里我们使用的是`<village_interfaces::srv::SellNovel>`,这个函数有四个参数需要输入,小鱼接下来进行一一介绍
 
 - `"sell_novel"`服务名称,没啥好说的,要唯一哦,因为服务只能有一个
-- `std::bind(&Wang2Node::sell_book_callback,this,_1,_2)`回调函数,这里指向了我们2.3.1中我们声明的`sell_book_callback`
+- `std::bind(&SingleDogNode::sell_book_callback,this,_1,_2)`回调函数,这里指向了我们2.3.1中我们声明的`sell_book_callback`
 - `rmw_qos_profile_services_default` 通信质量,这里使用服务默认的通信质量
 - `callback_group_service_`,回调组,我们前面创建回调组就是在这里使用的,告诉ROS2,当你要调用回调函数处理请求时,请把它放到单独线程的回调组中
 
@@ -260,18 +251,18 @@ server_ = this->create_service<village_interfaces::srv::SellNovel>("sell_novel",
 
 ```
  // 收到话题数据的回调函数
-    void topic_callback(const std_msgs::msg::String::SharedPtr msg){
-        // 新建一张人民币
-        std_msgs::msg::UInt32 money;
-        money.data = 10;
+ 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_->publish(money);
+    RCLCPP_INFO(this->get_logger(), "王二:我收到了:'%s' ,并给了李四:%d 元的稿费", msg->data.c_str(),money.data);
 
-        //将小说放入novels_queue中
-        novels_queue.push(msg->data);
-    };
+    //将小说放入novels_queue中
+    novels_queue.push(msg->data);
+};
 ```
 
 ### 2.5 修改`main`函数
@@ -285,7 +276,7 @@ int main(int argc, char **argv)
 {
     rclcpp::init(argc, argv);
     /*产生一个Wang2的节点*/
-    auto node = std::make_shared<Wang2Node>();
+    auto node = std::make_shared<SingleDogNode>("wang2");
     /* 运行节点,并检测退出信号*/
     rclcpp::executors::MultiThreadedExecutor exector;
     exector.add_node(node);
@@ -297,11 +288,7 @@ int main(int argc, char **argv)
 
 王二节点完整代码见:https://fishros.com/code/ros2/ros2_town/village_wang/src/wang2.cpp
 
-### 2.6 修改CmkeLists.txt并编译
-
-很开心的告诉你,因为之前我们已经添加了王二节点,使其生成可执行文件并安装到指定目录,这里就不需要做任何修改。
-
-#### 2.6.1 直接编译
+### 2.6 编译
 
 在工作空间下:输入下面的指令
 
@@ -372,12 +359,22 @@ ros2 run village_li li4_node
 
 
 
+
+
 ## 3.客户端(张三)实现
 
 编写完服务端的程序,接下来我们就可以编写客户端张三了。
 
-### 3.1 创建客户端节点
+### 3.1 编写ROS2服务通信客户端步骤
+
+
 
+
+
+### 3.2 添加服务接口与依赖
+
+
+#### 3.2.1 创建客户端节点
 因为张家村和张三之前不存在,这里我们需要新创建出来,命令如下:
 
 打开终端到src文件夹下:
@@ -393,8 +390,7 @@ ros2 pkg create village_zhang --build-type ament_cmake --dependencies rclcpp
 ![image-20210831125824511](4.10服务实现(C++)/imgs/image-20210831125824511.png)
 
 
-
-### 3.2 添加服务接口与依赖
+#### 3.2.2 创建客户端节点
 
 因为张三要找王二请求小说,所以一定依赖通信接口`village_interfaces`
 
@@ -441,7 +437,7 @@ ament_target_dependencies(zhang3_node
 
 #### 3.3.1 创建客户端
 
-接着我们就可以编写客户端了,张三也是C++,我们可以参考王二的代码,建立一个C++节点的基本的框架。
+接着我们就可以编写客户端了,穷光蛋张三也是C++,我们可以参考王二的代码,建立一个C++节点的基本的框架。
 
 ```
 #include "rclcpp/rclcpp.hpp"
@@ -451,14 +447,14 @@ ament_target_dependencies(zhang3_node
 using std::placeholders::_1;
 
 /*
-    创建一个类节点,名字叫做Zhang3Node,继承自Node.
+    创建一个类节点,名字叫做PoorManNode,继承自Node.
 */
-class Zhang3Node : public rclcpp::Node
+class PoorManNode : public rclcpp::Node
 {
 
 public:
 	/* 构造函数 */
-    Zhang3Node() : Node("wang2")
+    PoorManNode(std::string name) : Node(name)
     {
         // 打印一句自我介绍
         RCLCPP_INFO(this->get_logger(), "大家好,我是得了穷病的张三.");
@@ -471,7 +467,8 @@ int main(int argc, char **argv)
 {
     rclcpp::init(argc, argv);
     /*产生一个Zhang3的节点*/
-    auto node = std::make_shared<Zhang3Node>();
+    auto node = std::make_shared<PoorManNode>("zhang3");
+    /* 运行节点,并检测rclcpp状态*/
     rclcpp::spin(node);
     rclcpp::shutdown();
     return 0;
@@ -516,14 +513,14 @@ int main(int argc, char **argv)
 using std::placeholders::_1;
 
 /*
-    创建一个类节点,名字叫做Zhang3Node,继承自Node.
+    创建一个类节点,名字叫做PoorManNode,继承自Node.
 */
-class Zhang3Node : public rclcpp::Node
+class PoorManNode : public rclcpp::Node
 {
 
 public:
 	/* 构造函数 */
-    Zhang3Node() : Node("zhang3")
+    PoorManNode() : Node("zhang3")
     {
         // 打印一句自我介绍
         RCLCPP_INFO(this->get_logger(), "大家好,我是得了穷病的张三.");
@@ -551,7 +548,7 @@ int main(int argc, char **argv)
 {
     rclcpp::init(argc, argv);
     /*产生一个Zhang3的节点*/
-    auto node = std::make_shared<Zhang3Node>();
+    auto node = std::make_shared<PoorManNode>();
     rclcpp::spin(node);
     rclcpp::shutdown();
     return 0;
@@ -606,7 +603,7 @@ client_ = this->create_client<village_interfaces::srv::SellNovel>("sell_novel");
         request->money = 5; 
         
         //3.发送异步请求,然后等待返回,返回时调用回调函数
-        client_->async_send_request(request,std::bind(&Zhang3Node::novels_callback, this, _1));
+        client_->async_send_request(request,std::bind(&PoorManNode::novels_callback, this, _1));
     };
 ```
 
@@ -664,7 +661,7 @@ int main(int argc, char **argv)
 {
     rclcpp::init(argc, argv);
     /*产生一个Zhang3的节点*/
-    auto node = std::make_shared<Zhang3Node>();
+    auto node = std::make_shared<PoorManNode>();
     node->buy_novel();
     /* 运行节点,并检测rclcpp状态*/
     rclcpp::spin(node);

+ 1 - 1
docs/chapt4/4.9服务实现(Python).md

@@ -52,7 +52,7 @@ from village_interfaces.srv import BorrowMoney
 
 #### 2.2.1创建服务端
 
-接着创建一个服务,继承于`Node`之后,`BaiPiaoNode`也具备了创建一个服务的能力。在`BaiPiaoNode`的`__init__`函数中创建成员变量`borrow_server`。
+接着创建一个服务,继承于`Node`之后,`WriterNode`也具备了创建一个服务的能力。在`WriterNode`的`__init__`函数中创建成员变量`borrow_server`。
 
 ```
 # 新建借钱服务

+ 2 - 1
docs/chapt7/7.1.1数学基础.md

@@ -1,7 +1,8 @@
 # 数学基础
 
 线性代数基础
-                                          
+
+- 矩阵介绍                                
 - 单位矩阵
 - 矩阵的逆
 - 增广矩阵