Переглянути джерело

[feat]:完成3.9-getstarted

鱼香ROS 3 роки тому
батько
коміт
25907edbac
26 змінених файлів з 516 додано та 0 видалено
  1. 99 0
      docs/humble/chapt3/advanced/1.原始数据类型与包装类型.md
  2. BIN
      docs/humble/chapt3/advanced/1.原始数据类型与包装类型/imgs/image-20210824191624340.png
  3. 1 0
      docs/humble/chapt3/advanced/2.通信质量Qos配置指南.md
  4. 49 0
      docs/humble/chapt3/advanced/3.DDS进阶之Fast-DDS环境搭建.md
  5. 45 0
      docs/humble/chapt3/advanced/4.使用DDS进行订阅发布.md
  6. BIN
      docs/humble/chapt3/advanced/4.使用DDS进行订阅发布/imgs/69d6079ecd16442cb3c6824b742ae705.png
  7. 0 0
      docs/humble/chapt3/advanced/6.执行器与回调组.md
  8. 205 0
      docs/humble/chapt4/get_started/1.参数(Param)通信.md
  9. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903125400440.png
  10. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903142558024.png
  11. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903142905553.png
  12. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903145055215.png
  13. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903145702524.png
  14. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903150318055.png
  15. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903150423697.png
  16. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903150815050.png
  17. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903151103098.png
  18. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903151328843.png
  19. BIN
      docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903151639091.png
  20. 91 0
      docs/humble/chapt4/get_started/2.参数之RCLCPP实现.md
  21. 9 0
      docs/humble/chapt4/get_started/3.参数之RCLPY实现.md
  22. 0 0
      docs/humble/chapt4/get_started/4.动作(Action)通信与自定义接口.md
  23. 0 0
      docs/humble/chapt4/get_started/5.动作之RCLCPP实现.md
  24. 0 0
      docs/humble/chapt4/get_started/6.动作之RCLPY实现.md
  25. 0 0
      docs/humble/chapt4/get_started/7.通信机制对比总结.md
  26. 17 0
      docs/humble/chapt4/章节导读.md

+ 99 - 0
docs/humble/chapt3/advanced/1.原始数据类型与包装类型.md

@@ -0,0 +1,99 @@
+在ROS2中定义接口,需要编写一个接口文件,该文件后缀为`msg`、`srv`、`action`。
+
+在接口文件中定义通信过程中所使用的数据类型和数据名称,那可用的数据类型和数据名称有哪些呢?今天小鱼就带你详细了解一下ROS2接口文件中的数据类型和数据名称。
+
+## 1.数据名称
+
+数据名称就是一个字符串,没啥好说的,符合编程语言变量的命名规则就行(比如不能是数字开头)
+
+## 2.数据类型
+
+### 2.1 数据类型有哪些呢?
+
+这里小鱼可以告诉你,原始的数据类型只有九类。其中每一个都可以在后面加上`[]`将其变成数组形式(从一个变成多个)
+
+```
+bool
+byte
+char
+float32, float64
+int8, uint8
+int16, uint16
+int32, uint32
+int64, uint64
+string
+```
+
+> 上面这九类中,官方也在考虑新增一些和删除一些,目前还是支持的,后续小鱼会根据资料再更新一下本文。
+
+### 2.2 类型扩展(套娃)
+
+#### 2.2.1 第一层套娃
+
+ROS2基于上面的九类基础数据类型,为我们定义出了很多拿来就用的数据类型,比如我们在前面章节中用到的图像数据类型`sensor_msgs/Image`,我们可以使用下面的命令来看一下其组成:
+
+```
+ros2 interface show sensor_msgs/msg/Image
+```
+
+![image-20210824191624340](1.原始数据类型与包装类型/imgs/image-20210824191624340.png)
+
+去掉单行的注释后的样子如下:
+
+```
+std_msgs/Header header # Header timestamp should be acquisition time of image
+uint32 height                # image height, that is, number of rows
+uint32 width                 # image width, that is, number of columns
+string encoding       # Encoding of pixels -- channel meaning, ordering, size
+uint8 is_bigendian    # is this data bigendian?
+uint32 step           # Full row length in bytes
+uint8[] data          # actual matrix data, size is (step * rows)
+```
+
+我们可以看到,除了第一行`std_msgs/Header header`之外的其他部分都是由基础类型组成。
+
+#### 2.2.2 第二层套娃
+
+那`std_msgs/Header`由什么组成呢?我们再次使用下面的指令查看一下:
+
+```
+ros2 interface show std_msgs/msg/Header
+```
+
+结果如下:
+
+```
+builtin_interfaces/Time stamp # Two-integer timestamp that is expressed as seconds and nanoseconds.
+string frame_id # Transform frame with which this data is associated.
+```
+
+#### 2.2.3 第三层套娃
+
+看完上面的结果,除了基本类型`string`和我们发现还有一层`builtin_interfaces/Time`,我们再查看一下这个接口类型。
+
+```
+ros2 interface show builtin_interfaces/msg/Time 
+```
+
+结果如下:
+
+```
+# Time indicates a specific point in time, relative to a clock's 0 point.
+
+# The seconds component, valid over all int32 values.
+int32 sec
+
+# The nanoseconds component, valid in the range [0, 10e9).
+uint32 nanosec
+```
+
+我们发现结果全都是基本类型了,终于我们把套娃给解开了。
+
+## 3.接口类型总结
+
+通过基本类型的组合,可以构成一个新的数据类型,而新的数据类型又可以和基本类型或者另外一个数据类型互相组成另一个数据类型。所以我们可以说ROS2中的数据类型有无数种。
+
+## 4.总结
+
+相信看完这篇文章,以后再也不会遇到看不懂的数据类型了。
+

BIN
docs/humble/chapt3/advanced/1.原始数据类型与包装类型/imgs/image-20210824191624340.png


+ 1 - 0
docs/humble/chapt3/advanced/2.通信质量Qos配置指南.md

@@ -0,0 +1 @@
+- https://mp.weixin.qq.com/s/J63fO4c_QIseLGQd5W2fAw

+ 49 - 0
docs/humble/chapt3/advanced/3.DDS进阶之Fast-DDS环境搭建.md

@@ -0,0 +1,49 @@
+大家好,我是小鱼,昨天被群友在群里催了DDS相关的文章里,说好的来源码体验一下DDS来着,小鱼不能再咕咕咕了,所以今天就分享一下,FastDDS的安装和体验。
+
+## 1.论FastDDS的三种打开方式
+**FastDDS和普通ROS包一样,有二进制安装、源码编译、Docker三种安装方式。**
+
+因为官方把二进制和Docker放到了官网。。
+而且要填写个人信息才能下载。。
+而且下载速度超级超级慢。。
+而且不方便观摩源码。。
+所以小鱼带你一起从源码进行安装。
+
+本来想做成一键安装的,省的大家敲脚本了!!
+
+爱一个人绝对不能惯着他,鱼粉也是,为了让大家多复制粘贴时多思考一下(其实是为了凑文章字数),小鱼就带大家一起一步步安装编译源码
+
+不过源码安装也很简单,大家不要害怕。。
+
+因为DDS和ROS2相关,我们也可以使用colcon来编译,就不用cmake了(有需要cmake的自行到官网找)
+
+## 2.源码编译安装FastDDS
+
+下载编译DDS分为三步,第一步如果你已经安装了ROS2可以跳过。。
+
+#### 1.安装工具
+```
+sudo apt install python3-colcon-common-extensions python3-vcstool zip openjdk-8-jdk  -y
+```
+#### 2.创建目录,下载仓库
+```
+mkdir -p fastdds_ws/src 
+cd fastdds_ws && wget https://downloads.gradle-dn.com/distributions/gradle-6.4-bin.zip && unzip gradle-6.4-bin.zip 
+wget http://fishros.com/tools/files/fastrtps.repos && vcs import src < fastrtps.repos
+```
+> [安装Fast DDS依赖项的 repos 文件时出现404:Not Found](https://fishros.org.cn/forum/topic/79/%E5%AE%89%E8%A3%85fast-dds%E4%BE%9D%E8%B5%96%E9%A1%B9%E7%9A%84-repos-%E6%96%87%E4%BB%B6%E6%97%B6%E5%87%BA%E7%8E%B0404-not-found/3?_=1650535091374)
+#### 3.编译
+
+```
+colcon build
+cd src/fastddsgen/ &&  gradle assemble
+```
+
+#### 最后一步:配置环境变量
+xxx是你的目录前缀
+```
+echo 'source xxx/fastdds_ws/install/setup.bash' >> ~/.bashrc
+echo 'export PATH=$PATH:xxx/fastdds_ws/gradle-6.4/bin/' >> ~/.bashrc
+echo 'export DDSGEN=xxx/fastdds_ws/src/fastddsgen/scripts' >> ~/.bashrc
+```
+

+ 45 - 0
docs/humble/chapt3/advanced/4.使用DDS进行订阅发布.md

@@ -0,0 +1,45 @@
+## 3.HelloFish例程
+
+DDS使用的RTPS,就是Real-Time Publish Subscribe协议,其实和ROS与ROS2中的发布订阅的感觉时一样的,所以我们就跑一个例程来收发消息,消息内容就叫`HelloFish`
+
+小鱼写的程序已经准备好了,放到了github上,大家可以直接下载下来编译测试哦~
+
+### 下载代码
+
+```
+git clone https://github.com/fishros/dds_tutorial.git
+```
+
+### 编译例程
+
+```
+cd dds_tutorial/examples/01-hellofishros
+mkdir build && cd build
+cmake .. 
+make
+```
+
+### 执行例程
+
+开一个终端
+
+```
+./DDSHelloFishRosPublisher  
+```
+
+再开一个终端
+
+```
+./DDSHelloFishRosSubscribe
+```
+
+### 查看结果
+
+正确结果像下面这样子,已经证明一切OK了~
+![DDS发布订阅测试](4.使用DDS进行订阅发布/imgs/69d6079ecd16442cb3c6824b742ae705.png)
+
+## 4.总结
+
+看到熟悉的发布订阅是不是很神奇,FASTDDS底层采用了多种协议进行数据的传输,包括不靠谱但真的很快的UDP,靠谱但是不怎么快的TCP,还有感觉不传输的内存交换(SHM)。
+
+为了给大家展示一下什么叫做低产(懒),小鱼决定明天再给大家讲解代码~

BIN
docs/humble/chapt3/advanced/4.使用DDS进行订阅发布/imgs/69d6079ecd16442cb3c6824b742ae705.png


+ 0 - 0
docs/humble/chapt3/advanced/6.执行器与回调组.md


+ 205 - 0
docs/humble/chapt4/get_started/1.参数(Param)通信.md

@@ -0,0 +1,205 @@
+# 1.ROS2参数通信介绍
+
+## 1.参数通信是什么?
+
+大家好,我是爱吃瓜皮的小鱼。在前面的机器人控制示例中我们,机器人每移动一步休息500ms,加入我们想让机器人休息时间少一些,就需要手动的修改源码减少其值,这非常的不方便。
+
+在机器人开发中,会有很多参数和设置可以后期需要调整的,如果都放到源码里很难实现动态修改和管理,ROS2为了解决这一问题,提出了参数这一通信机制。
+
+### 1.1 参数定义
+
+ROS2官方对参数的定义是:
+
+**A parameter is a configuration value of a node. You can think of parameters as node settings.**
+
+有请翻译官小鱼
+
+**参数是节点的一个配置值,你可以任务参数是一个节点的设置**
+
+感谢小鱼同学的精彩翻译,ROS2的参数就是节点的设置,和我们上面提出的需求不谋而合,有了参数我们就可以实现动态的改变李四写小说的速度了
+
+### 1.2 参数组成成分
+
+ROS2参数是由键值对组成的,此话怎讲?键值对指的是就是名字和数值,比方说
+
+- 名字:李四写小说周期,值:5s
+- 名字:显示器亮度,值:60%
+
+名字的数据类型小鱼不多说肯定是字符串了,值的数据类型呢?我们这里用到的是5是整形数据,显然只有一个整形是不够用的,ROS2支持的参数值的类型如下:
+
+- bool 和bool[],布尔类型用来表示开关,比如我们可以控制雷达控制节点,开始扫描和停止扫描。
+- int64 和int64[],整形表示一个数字,含义可以自己来定义,这里我们可以用来表示李四节点写小说的周期值
+- float64 和float64[],浮点型,可以表示小数类型的参数值
+- string 和string[],字符串,可以用来表示雷达控制节点中真实雷达的ip地址
+- byte[],字节数组,这个可以用来表示图片,点云数据等信息
+
+## 2.体验参数
+
+我们使用乌龟模拟器来体验一下参数,同时讲解一下常用的参数的命令行工具。
+
+### 2.1 运行小乌龟模拟器节点和小乌龟控制节点
+
+打开终端
+
+```
+ros2 run turtlesim turtlesim_node
+```
+
+再打开一个终端
+
+```
+ros2 run turtlesim turtle_teleop_key
+```
+
+可以看到下面的蓝蓝的模拟器
+
+![image-20210903142558024](1.参数(Param)通信/imgs/image-20210903142558024.png)
+
+### 2.2 查看节点有哪些参数(设置)
+
+我们可以使用下面的指令来查看所有节点的参数列表,打开一个终端,运行下面的指令
+
+```
+ros2 param list
+```
+
+![image-20210903125400440](1.参数(Param)通信/imgs/image-20210903125400440.png)
+
+写代码为什么要做到见名知意?我们看到乌龟模拟器的四个参数,background背景bgr指的是blue、green、red。简而言之就是背景颜色。那这几个参数应该可以控制乌龟模拟器的背景颜色。
+
+> 最后一个use_sim_time是每个节点都带的,后面小鱼写篇文章稍微讲讲。
+
+如果看不懂,还可以有一个方法详细查看一个参数的信息。
+
+```
+ros2 param describe <node_name> <param_name>
+```
+
+比如:
+
+```
+ros2 param describe /turtlesim background_b
+```
+
+![image-20210903150815050](1.参数(Param)通信/imgs/image-20210903150815050.png)
+
+这里就可以详细的看到参数的名字,参数的描述,参数的类型,还有对参数的约束,最大值最小值等。
+
+### 2.3 查看参数值
+
+参数的组成由名字和值(键值组成),名字可以通过`param list`获取,值该使用指令获取呢?
+
+下面这个命令行工具可以帮助我们获取参数的值
+
+```
+ros2 param get /turtlesim background_b
+```
+
+运行一下,你会发现结果是255,蓝色进度条打满,再看看r红色和g绿色。
+
+![image-20210903142905553](1.参数(Param)通信/imgs/image-20210903142905553.png)
+
+分别是255,86,69
+
+### 2.4 设置参数
+
+找到了参数和值,接着我们来改变一下乌龟模拟器的颜色。
+
+打开小鱼精心准备的在线工具:[https://fishros.com/tools/pickr](https://fishros.com/tools/pickr/)
+
+选取一个自己喜欢的颜色,这里小鱼就选绿色,因为乌龟模拟器换成绿色的应该很奇怪。
+
+![image-20210903145055215](1.参数(Param)通信/imgs/image-20210903145055215.png)
+
+可以看到当前的这个颜色,r为44,g为156,b为10,接着我们可以使用下面的指令来设置参数的值。
+
+```
+ros2 param set <node_name> <parameter_name> <value>
+```
+
+我们依次修改参数值:
+
+```
+ros2 param set /turtlesim background_r 44
+ros2 param set /turtlesim background_g 156
+ros2 param set /turtlesim background_b 10
+```
+
+接着你可以看到这样的颜色的乌龟模拟器(绿的令人发慌)
+
+![image-20210903145702524](1.参数(Param)通信/imgs/image-20210903145702524.png)
+
+> 需要留意的是,我们修改的背景数据并没有被存储,只是临时修改。重新启动节点乌龟模拟器依然还是原来的蓝色,不是我们想要的绿色的。
+
+### 2.5 把参数存起来
+
+把参数存起来其实就相当去把当前的参数值拍一张快照,然后保存下来,后面可以用于恢复参数到当前的数值。
+
+可以使用下面的命令进行操作:
+
+```
+ros2 param dump <node_name>
+```
+
+#### 2.5.1 给乌龟模拟器参数拍照
+
+比如我们要保存乌龟模拟器的节点数据,可以采用下面的指令;
+
+```
+ros2 param dump /turtlesim
+```
+
+![image-20210903150318055](1.参数(Param)通信/imgs/image-20210903150318055.png)
+
+文件被保存成了yaml格式,用cat指令看一看
+
+```
+cat ./turtlesim.yaml
+```
+
+![image-20210903150423697](1.参数(Param)通信/imgs/image-20210903150423697.png)
+
+#### 2.5.2 恢复参数值
+
+我们`Ctrl+C`关闭乌龟模拟器,然后再重新运行。
+
+```
+ros2 run turtlesim turtlesim_node
+```
+
+![image-20210903151103098](1.参数(Param)通信/imgs/image-20210903151103098.png)
+
+可以看到模拟器又变成了蓝色了,接着通过param的load的方法把参数值恢复成我们之前存储的。
+
+```
+ros2 param load  /turtlesim ./turtlesim.yaml
+```
+
+![image-20210903151328843](1.参数(Param)通信/imgs/image-20210903151328843.png)
+
+几乎是瞬间,乌龟模拟器又被我们搞绿了
+
+#### 2.5.3 启动节点时加载参数快照
+
+有什么办法一开始就让乌龟模拟器变成绿色?答案有的。
+
+ros2 的run 指令支持下面这种`骚操作`。
+
+```
+ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
+```
+
+关闭我们的乌龟模拟器,使用下面的指令重新运行
+
+```
+ros2 run turtlesim turtlesim_node --ros-args --params-file ./turtlesim.yaml
+```
+
+![image-20210903151639091](1.参数(Param)通信/imgs/image-20210903151639091.png)
+
+可以看到一上来就时绿了的模拟器。
+
+## 3.总结
+
+本节小鱼带大家一起学习了参数的基本概念,同时动手把参数的命令行工具玩了一遍。
+

BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903125400440.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903142558024.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903142905553.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903145055215.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903145702524.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903150318055.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903150423697.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903150815050.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903151103098.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903151328843.png


BIN
docs/humble/chapt4/get_started/1.参数(Param)通信/imgs/image-20210903151639091.png


+ 91 - 0
docs/humble/chapt4/get_started/2.参数之RCLCPP实现.md

@@ -0,0 +1,91 @@
+2.参数之RCLCPP实现
+
+上节我们通过参数控制了小乌龟模拟器的背景色,但是我们并不知道小乌龟模拟器是如何接收到参数并将其应用的,本节我们就学习使用ROS2的RCLCPP中参数相关的API实现对ROS2打印的日志级别控制。
+
+ROS2将日志分为五个级别,在CPP中通过不同的宏可以实现不同日志级别日志的打印,例程如下:
+
+```cpp
+RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
+RCLCPP_INFO(this->get_logger(), "我是INFO级别的日志,我被打印出来了!");
+RCLCPP_WARN(this->get_logger(), "我是WARN级别的日志,我被打印出来了!");
+RCLCPP_ERROR(this->get_logger(), "我是ERROR级别的日志,我被打印出来了!");
+RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出来了!");
+```
+
+有时候日志太多,会让人眼花缭乱找不到重要信息,所以我们需要对日志的级别进行过滤,比如只看INFO以上级别的,ROS2中可以通过已有的API设置日志的级别,RCLCPP中API如下:
+
+```
+this->get_logger().set_level(log_level);
+```
+
+
+
+1.创建功能包和节点
+
+我们创建一个功能包和测试节点,声明参数并实现动态修改打印的日志级别功能。
+
+```
+mkdir -p chapt4/chapt4_ws/
+ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic --maintainer-name "fishros" --maintainer-email "fishros@foxmail.com"
+```
+
+```
+#include <chrono>
+
+#include "rclcpp/rclcpp.hpp"
+/*
+    # 声明
+    # declare_parameter	        声明和初始化一个参数
+    # declare_parameters	    声明和初始化一堆参数
+    # 获取
+    # describe_parameter(name)  通过参数名字获取参数的描述
+    # get_parameter	            通过参数名字获取一个参数
+    # get_parameters	        通过多个参数名字获取多个参数
+    # 设置
+    # set_parameters	        设置一组参数的值
+    #
+    # has_parameter             参数是否被声明
+*/
+class ParametersBasicNode : public rclcpp::Node {
+ public:
+  // 构造函数,有一个参数为节点名称
+  explicit ParametersBasicNode(std::string name) : Node(name) {
+    // 打印一句
+    RCLCPP_INFO(this->get_logger(), "节点已启动:%s.", name.c_str());
+    this->declare_parameter("rcl_log_level", 0);
+    this->get_parameter("rcl_log_level", log_level);
+
+    RCLCPP_INFO(this->get_logger(), "设置%s节点日志级别 %d .", name.c_str(),
+                log_level);
+    this->get_logger().set_level((rclcpp::Logger::Level)log_level);
+    RCLCPP_INFO(this->get_logger(), "设置%s节点日志级别完成 %d .", name.c_str(),
+                log_level);
+
+    using namespace std::literals::chrono_literals;
+    timer_ = this->create_wall_timer(
+        500ms, std::bind(&ParametersBasicNode::timer_callback, this));
+  }
+
+ private:
+};
+
+int main(int argc, char** argv) {
+  rclcpp::init(argc, argv);
+  /*产生一个的节点*/
+  auto node = std::make_shared<ParametersBasicNode>("parameters_basic");
+  /* 运行节点,并检测退出信号*/
+  rclcpp::spin(node);
+  rclcpp::shutdown();
+  return 0;
+}
+```
+
+2.RCLCPP参数API
+
+
+
+3.使用参数控制节点日志级别
+
+
+
+4.总结

+ 9 - 0
docs/humble/chapt4/get_started/3.参数之RCLPY实现.md

@@ -0,0 +1,9 @@
+3.参数之RCLPY实现
+
+1.创建功能包和节点
+
+2.RCLPY参数API
+
+3.使用参数控制节点日志级别
+
+4.总结

+ 0 - 0
docs/humble/chapt4/get_started/4.动作(Action)通信与自定义接口.md


+ 0 - 0
docs/humble/chapt4/get_started/5.动作之RCLCPP实现.md


+ 0 - 0
docs/humble/chapt4/get_started/6.动作之RCLPY实现.md


+ 0 - 0
docs/humble/chapt4/get_started/7.通信机制对比总结.md


+ 17 - 0
docs/humble/chapt4/章节导读.md

@@ -0,0 +1,17 @@
+- 第 4 章 ROS2通信之参数与动作
+- 章节导读
+- 基础篇-控制概述
+    - 机器人控制概述
+- 入门篇-参数与动作
+    1.参数(Param)通信
+    2.参数之RCLCPP实现
+    3.参数之RCLPY实现
+    4.动作(Action)通信与自定义接口
+    5.动作之RCLCPP实现
+    6.动作之RCLPY实现
+    7.通信机制对比总结
+- 进阶篇-原理进阶
+    - 参数与动作通信机制原理
+    - 3.生命周期节点介绍
+    - 高效的ROS2进程内通信
+    - 使用ZeroMQ进行订阅发布