Ver código fonte

feat(chapt14): 完成控制OLED-自定义消息接口

鱼香ROS 2 anos atrás
pai
commit
d4bd94d464
21 arquivos alterados com 319 adições e 19 exclusões
  1. 5 6
      docs/_sidebar.md
  2. 1 0
      docs/humble/chapt13/advance/4.使用开源库驱动OLED.md
  3. 280 0
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口.md
  4. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121100425404.png
  5. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121132902249.png
  6. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121143718137.png
  7. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121214938929.png
  8. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121233716879.png
  9. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122004425093.png
  10. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012129199.png
  11. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012216715.png
  12. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012459521.png
  13. BIN
      docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012552293.png
  14. 5 0
      docs/humble/chapt14/advance/2.做个时钟-系统时间同步.md
  15. BIN
      docs/humble/chapt14/advance/2.做个时钟-系统时间同步/imgs/image-20230121132033848.png
  16. 15 0
      docs/humble/chapt14/advance/3.无线通讯-了解传输原理.md
  17. BIN
      docs/humble/chapt14/advance/3.无线通讯-了解传输原理/imgs/image-20230121132147824.png
  18. BIN
      docs/humble/chapt14/advance/3.无线通讯-了解传输原理/imgs/image-20230121224323649.png
  19. 7 7
      docs/humble/chapt14/basic/1.MicroROS介绍与服务安装.md
  20. 4 4
      docs/humble/chapt14/basic/2.你的第一个MicroROS节点.md
  21. 2 2
      docs/humble/chapt14/get_started/3.MicroROS-服务通信服务端实现.md

+ 5 - 6
docs/_sidebar.md

@@ -192,7 +192,6 @@
     - 进阶篇
       -  [1.Gazebo仿真插件之超声波](humble/chapt9/advanced/1.Gazebo仿真插件之超声波.md) 
       <!-- - 2.Gazebo仿真插件之深度相机 -->
-
 - (四)Nav2导航篇
   - 第 10 章 SLAM建图
     - 章节导读
@@ -229,7 +228,6 @@
     - 进阶篇-优化配置
       - 暂定
       <!-- - 使用Carto纯定位替换AMCL -->
-  
 - (五)ROS2控制硬件篇(更新中)
   - 第 13 章 嵌入式开发之从点灯开始
     - [章节导读](humble/chapt13/章节导读.md)
@@ -259,11 +257,12 @@
       - [2.你的第一个MicroROS节点](humble/chapt14/basic/2.你的第一个MicroROS节点.md)
     - 入门篇-在嵌入式平台实现话题与服务通信
       - [1.话题订阅-控制LED](humble/chapt14/get_started/1.话题订阅-控制LED.md)
-      - [2.MicroROS-话题发布实现](humble/chapt14/get_started/2.MicroROS-话题发布实现.md)
-      - [3.MicroROS-服务通信服务端实现](humble/chapt14/get_started/3.MicroROS-服务通信服务端实现.md)
+      - [2.话题发布-上传电量信息](humble/chapt14/get_started/2.MicroROS-话题发布实现.md)
+      - [3.服务实现-两数相加](humble/chapt14/get_started/3.MicroROS-服务通信服务端实现.md)
     - 进阶篇-MicoROS原理与使用进阶
-      - 1.从更换协议了解MicroROS数据传输
-      - 2.MicroROS系统时间同步
+      - [1.控制OLED-自定义消息接口.md](humble/chapt14/get_started/1.话题订阅-控制LED.md)
+      - 2.做个时钟-系统时间同步
+      - 3.无线通讯-了解传输原理
   - 第 15 章 ROS2硬件实战(自制简易雷达)
       - 1.简易雷达原理介绍
       - 2.使用超声波测量距离

+ 1 - 0
docs/humble/chapt13/advance/4.使用开源库驱动OLED.md

@@ -87,6 +87,7 @@ void loop()
 该库提供的驱动例程较为复杂,小鱼这里提供一个简易版本。
 
 ```c++
+#include "Wire.h"
 #include <Adafruit_GFX.h>     // 加载Adafruit_GFX库
 #include <Adafruit_SSD1306.h> // 加载Adafruit_SSD1306库
 Adafruit_SSD1306 display;     // 声明对象

+ 280 - 0
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口.md

@@ -0,0 +1,280 @@
+# 1.控制OLED-自定义消息接口
+
+  你好,我是爱吃鱼香ROS的小鱼。前面章节中我们使用ROS2提供的两数相加服务接口实现了服务通信,但是很多场景需要我们自定定义接口,所以本节我们就学习如何自定义MicroROS的接口,以及如何将自己的功能包添加到MicroROS中来。
+
+本节课最终效果是:通过自定义的服务接口控制开发板上的OLED显示器的内容。
+
+```
+ros2 service call /oled_control fishbot_interfaces/srv/OledControl "{px: 0, py: 0 ,data: 'oled control by service~'}"
+```
+
+![image-20230121233716879](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230121233716879.png)
+
+## 一、新建工程添加依赖
+
+新建`example14_custom_interface` 
+
+![](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230121132902249.png)
+
+修改`platformio.ini`
+
+```ini
+[env:featheresp32]
+platform = espressif32
+board = featheresp32
+framework = arduino
+lib_deps = 
+    https://gitee.com/ohhuo/micro_ros_platformio.git
+    adafruit/Adafruit SSD1306@^2.5.7
+```
+
+这里除了添加micro_ros库之外再添加oled驱动库。
+
+## 二、添加自定义接口
+
+**添加自定义接口一共需要三步。**
+
+**1.创建`extra_packages`文件夹并创建接口功能包**
+
+**2.编译功能包(主要为了测试功能包是否正常)**
+
+**3.删除`.pio/libdeps/featheresp32/micro_ros_platformio/libmicroros`文件夹,重新编译**
+
+### 2.1 创建功能包
+
+在工程的主目录下创建`extra_packages`文件夹,接着在文件夹下创建`fishbot_interfaces`功能包
+
+```shell
+cd example14_custom_interface
+mkdir extra_packages
+cd extra_packages 
+ros2 pkg create fishbot_interfaces
+```
+
+接着添加服务接口文件并修改CMakeLists.txt
+
+文件`extra_packages/fishbot_interfaces/srv/OledControl.srv`
+
+```
+int32 px
+int32 py
+string data
+---
+int32 result
+```
+
+文件`extra_packages/fishbot_interfaces/CMakeLists.txt`
+
+```cmake
+cmake_minimum_required(VERSION 3.5)
+project(fishbot_interfaces)
+
+
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+# uncomment the following section in order to fill in
+# further dependencies manually.
+# find_package(<dependency> REQUIRED)
+
+if(BUILD_TESTING)
+  find_package(ament_lint_auto REQUIRED)
+  # the following line skips the linter which checks for copyrights
+  # uncomment the line when a copyright and license is not present in all source files
+  #set(ament_cmake_copyright_FOUND TRUE)
+  # the following line skips cpplint (only works in a git repo)
+  # uncomment the line when this package is not in a git repo
+  #set(ament_cmake_cpplint_FOUND TRUE)
+  ament_lint_auto_find_test_dependencies()
+endif()
+
+find_package(rosidl_default_generators REQUIRED)
+
+rosidl_generate_interfaces(${PROJECT_NAME}
+  "srv/OledControl.srv"
+ )
+
+ament_package()
+
+```
+
+## 2.2 编译功能包
+
+```shell
+cd extra_packages/
+colcon build
+```
+
+
+
+![image-20230122004425093](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230122004425093.png)
+
+### 2.3 重新编译工程
+
+编译前需要删除`.pio/libdeps/featheresp32/micro_ros_platformio/libmicroros`文件夹,使用Ctrl+Alt+B重新重新编译工程。
+
+![](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230121143718137.png)
+
+## 三、编写代码
+
+和两数相加服务相似的代码,只不过更换了接口并添加了OLED的驱动。
+
+```c++
+#include <Arduino.h>
+#include <micro_ros_platformio.h>
+
+#include <rcl/rcl.h>
+#include <rclc/rclc.h>
+#include <rclc/executor.h>
+#include <micro_ros_utilities/string_utilities.h>
+
+#include "Wire.h"
+#include <Adafruit_GFX.h>     // 加载Adafruit_GFX库
+#include <Adafruit_SSD1306.h> // 加载Adafruit_SSD1306库
+
+#include <fishbot_interfaces/srv/oled_control.h> // 添加接口
+
+rclc_executor_t executor;
+rclc_support_t support;
+rcl_allocator_t allocator;
+rcl_node_t node;
+// 定义服务
+rcl_service_t service;
+
+// 服务请求和返回消息定义
+fishbot_interfaces__srv__OledControl_Request req;
+fishbot_interfaces__srv__OledControl_Response res;
+
+Adafruit_SSD1306 display;
+
+// 服务回调函数
+void service_callback(const void *req, void *res)
+{
+  fishbot_interfaces__srv__OledControl_Request *req_in = (fishbot_interfaces__srv__OledControl_Request *)req;
+  fishbot_interfaces__srv__OledControl_Response *res_in = (fishbot_interfaces__srv__OledControl_Response *)res;
+  // 计算sum
+  display.clearDisplay();                    // 清空屏幕
+  display.setCursor(req_in->px, req_in->py); // 设置开始显示文字的坐标
+  display.println(req_in->data.data);        // 输出的字符
+  display.display();
+  res_in->result = 0;
+}
+
+void setup()
+{
+  Serial.begin(115200);
+  // 设置通过串口进行MicroROS通信
+  set_microros_serial_transports(Serial);
+  // 延时时一段时间,等待设置完成
+  delay(2000);
+  // 初始化内存分配器
+  allocator = rcl_get_default_allocator();
+  // 创建初始化选项
+  rclc_support_init(&support, 0, NULL, &allocator);
+  // 创建节点 hello_microros
+  rclc_node_init_default(&node, "example14_interface", "", &support);
+  // 使用默认配置创建服务
+  rclc_service_init_default(&service, &node, ROSIDL_GET_SRV_TYPE_SUPPORT(fishbot_interfaces, srv, OledControl), "/oled_control");
+  // 创建执行器
+  rclc_executor_init(&executor, &support.context, 1, &allocator);
+  // 执行器添加服务
+  rclc_executor_add_service(&executor, &service, &req, &res, service_callback);
+  // 重要,为string类型消息分配空间
+  req.data = micro_ros_string_utilities_init_with_size(100);
+
+  /*========================OLED初始化====================================*/
+  Wire.begin(18, 19);
+  display = Adafruit_SSD1306(128, 64, &Wire);
+  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 设置OLED的I2C地址
+  display.clearDisplay();                    // 清空屏幕
+  display.setTextSize(1);                    // 设置字体大小
+  display.setCursor(0, 0);                   // 设置开始显示文字的坐标
+  display.setTextColor(SSD1306_WHITE);       // 设置字体颜色
+  display.println("hello fishros!");         // 输出的字符
+  display.display();
+}
+
+void loop()
+{
+  delay(100);
+  // 循环处理数据
+  rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
+}
+```
+
+## 四、代码讲解
+
+这里对新增的几行主要代码进行讲解
+
+- `#include <micro_ros_utilities/string_utilities.h> 添加string工具类`
+- ` req.data = micro_ros_string_utilities_init_with_size(100); 使用string类型内存分配工具为data分配100字节e的空间`
+
+**主要就是这两部分,值得注意的是,如果不提前为string类型的数据分配内容空间,最终会导致无法正常接收数据。**
+
+
+
+## 五、下载测试
+
+### 5.1 编译下载
+
+连接开发板,编译下载。
+
+![image-20230121100425404](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230121100425404.png)
+
+### 5.2 启动Agent
+
+接着打开终端启动agent
+
+```shell
+sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO serial --dev /dev/ttyUSB0 -v
+```
+
+点击下RST按钮,重启开发板,正常可以看到下图内容
+
+![image-20230122012216715](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230122012216715.png)
+
+### 5.3 查看是否连通
+
+接着打开终端查看节点和话题
+
+```shell
+ros2 node list
+ros2 service list
+```
+
+![image-20230122012129199](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230122012129199.png)
+
+### 4.4 测试控制
+
+进入`extra_packages`,source环境
+
+```
+source install/setup.bash
+```
+
+显示`nihao`
+
+```shell
+ros2 service call /oled_control fishbot_interfaces/srv/OledControl "{px: 0, py: 0 , data: 'nihao'}"
+```
+
+![image-20230122012459521](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230122012459521.png)
+
+显示`oled control by service~`
+
+```
+ros2 service call /oled_control fishbot_interfaces/srv/OledControl "{px: 0, py: 0 ,data: 'oled control by service~'}"
+```
+
+![image-20230122012552293](1.%E6%8E%A7%E5%88%B6OLED-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3/imgs/image-20230122012552293.png)
+
+## 六、总结
+
+本节通过使用自定义服务接口控制oled显示的例程,学习了如何在工程中添加自己的功能包和接口文件。下一节我们将学习如何让开发板的时间和上位机的时间进行同步。
+
+
+

BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121100425404.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121132902249.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121143718137.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121214938929.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230121233716879.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122004425093.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012129199.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012216715.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012459521.png


BIN
docs/humble/chapt14/advance/1.控制OLED-自定义消息接口/imgs/image-20230122012552293.png


+ 5 - 0
docs/humble/chapt14/advance/2.做个时钟-系统时间同步.md

@@ -0,0 +1,5 @@
+# 2.做个时钟-系统时间同步
+
+
+
+![image-20230121132033848](2.%E5%81%9A%E4%B8%AA%E6%97%B6%E9%92%9F-%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%97%B4%E5%90%8C%E6%AD%A5/imgs/image-20230121132033848.png)

BIN
docs/humble/chapt14/advance/2.做个时钟-系统时间同步/imgs/image-20230121132033848.png


+ 15 - 0
docs/humble/chapt14/advance/3.无线通讯-了解传输原理.md

@@ -0,0 +1,15 @@
+# 3.无线通讯-了解传输原理
+
+
+
+![image-20230121132147824](3.%E6%97%A0%E7%BA%BF%E9%80%9A%E8%AE%AF-%E4%BA%86%E8%A7%A3%E4%BC%A0%E8%BE%93%E5%8E%9F%E7%90%86/imgs/image-20230121132147824.png)
+
+
+
+
+
+```shell
+docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO udp4 --port 8888 -v6
+```
+
+![image-20230121224323649](3.%E6%97%A0%E7%BA%BF%E9%80%9A%E8%AE%AF-%E4%BA%86%E8%A7%A3%E4%BC%A0%E8%BE%93%E5%8E%9F%E7%90%86/imgs/image-20230121224323649.png)

BIN
docs/humble/chapt14/advance/3.无线通讯-了解传输原理/imgs/image-20230121132147824.png


BIN
docs/humble/chapt14/advance/3.无线通讯-了解传输原理/imgs/image-20230121224323649.png


+ 7 - 7
docs/humble/chapt14/basic/1.MicroROS介绍与服务安装.md

@@ -4,7 +4,7 @@
 
 
 
-![micro-ROS architecture](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/micro-ROS_architecture.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/micro-ROS_architecture.png)
 
 
 
@@ -14,21 +14,21 @@
 
 首先从名称看,Micro-ROS,Micro指的就是`microcontrollers`即微控制器。
 
-![image-20230121000431421](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121000431421.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121000431421.png)
 
 核心作用就是上面这句话`micro-ROS puts ROS 2 onto microcontrollers`。既然是在微控制器上,因硬件资源受限,其功能肯定会有所裁剪,但核心的ROS2通信功能依然保有。
 
-![image-20230121002536573](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121002536573.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121002536573.png)
 
 ## 二、特点2:MicroROS支持多种通信协议并依赖Agent
 
-![image-20230121002714689](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121002714689.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121002714689.png)
 
 所谓Agen其实就是一个代理,**微控制器可以通过串口,蓝牙、以太网、Wifi等多种协议将数据传递给Agent**,Agent再将其转换成ROS2的话题等数据,以此完成通信。
 
 ## 三、特点3:通过RCLC-API调用MicroROS
 
-![image-20230121003129698](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121003129698.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121003129698.png)
 
 因为MicroROS遵循RCLCAPI,所以和在上位机中使用Python或者C++调用MicroROS有所不同,最终代码风格如下面这段所示
 
@@ -90,7 +90,7 @@ wget http://fishros.com/install -O fishros && . fishros
 
 接着输入密码,在下面的界面输入8,一键安装Docker,完成后等待即可。
 
-![528a2dc4-de20-4b24-89eb-d9fe7b5b107d-image.png](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/1663861023833-528a2dc4-de20-4b24-89eb-d9fe7b5b107d-image-16742326632143.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/1663861023833-528a2dc4-de20-4b24-89eb-d9fe7b5b107d-image-16742326632143.png)
 
 
 ### 4.2 运行Agent
@@ -101,7 +101,7 @@ sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=ho
 ```
 稍微等待下载完成,看到如下界面表示成功启动。
 
-![image-20230121004045577](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121004045577.png)
+![](1.MicroROS%E4%BB%8B%E7%BB%8D%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85/imgs/image-20230121004045577.png)
 
 上面的指令是使用串口通讯协议运行microros-agent,还可以通过UDP、TCP、CAN等协议运行,具体指令如下
 

+ 4 - 4
docs/humble/chapt14/basic/2.你的第一个MicroROS节点.md

@@ -113,15 +113,15 @@ rclc_support_init(
 
 连接开发板,编译下载,如果遇到端口被占用,多半是你的microros_agent没有关闭,Ctrl+C打断运行再次尝试。
 
-![image-20230121011234354](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011234354.png)
+![](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011234354.png)
 
 接着打开Agent
 
-![image-20230121011320762](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011320762.png)
+![](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011320762.png)
 
 然而并没有什么反应,重新点击一次RST即可看到有数据发送和接收过来了。
 
-![image-20230121011410538](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011410538.png)
+![](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011410538.png)
 
 接着打开新的终端,输入指令
 
@@ -132,7 +132,7 @@ ros2 node info /hello_microros
 
 
 
-![image-20230121011552866](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011552866.png)
+![](2.%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAMicroROS%E8%8A%82%E7%82%B9/imgs/image-20230121011552866.png)
 
 可以看到,我们的第一个节点成功运行起来了。
 

+ 2 - 2
docs/humble/chapt14/get_started/3.MicroROS-服务通信服务端实现.md

@@ -51,8 +51,8 @@ rcl_node_t node;
 rcl_service_t service;
 
 // 服务请求和返回消息定义
-example_interfaces__srv__AddTwoInts_Request res;
-example_interfaces__srv__AddTwoInts_Response req;
+example_interfaces__srv__AddTwoInts_Request req;
+example_interfaces__srv__AddTwoInts_Response res;
 
 // 服务回调函数
 void service_callback(const void *req, void *res)