Explorar o código

修改完善-在公园

sangxin %!s(int64=3) %!d(string=hai) anos
pai
achega
83a25a2eee

+ 108 - 4
docs/chapt5/5.4ROS2_Action介绍.md

@@ -94,27 +94,131 @@ Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rot
 
 ## 4. Action的CLI工具
 
-Action的命令行工具一共有三个。
-
+Action的命令行工具一共有三个,下面我们一一介绍。
 
 
 ### 4.1 action list
+该命令用于获取目前系统中的action列表。
+
+```
+ros2 action list
+```
+你将看到
+
+```
+/turtle1/rotate_absolute
+```
 
+如果在list后加入-t参数,即可看到action的类型
+
+```
+/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]
+```
+
+知道了接口类型之后,可以使用接口相关CLI指令获取接口的信息
+
+```
+ros2 interface show turtlesim/action/RotateAbsolute 
+```
 
+结果
+
+```
+# The desired heading in radians
+float32 theta
+---
+# The angular displacement in radians to the starting position
+float32 delta
+---
+# The remaining rotation in radians
+float32 remaining
+```
 
 ### 4.2 action info
 
+查看action信息,在终端中输入下面的指令。
+
 ```
 ros2 action info /turtle1/rotate_absolute 
+```
+
+你将看到,action客户端和服务段的数量以及名字。
+
+```
 Action: /turtle1/rotate_absolute
-Action clients: 0
+Action clients: 1
+    /teleop_turtle
 Action servers: 1
     /turtlesim
 ```
 
+### 4.3 action send_goal
 
+该指令用于发送actin请求到服务端,我们可以模拟下,让小乌龟转到我们定义的角度。
 
-### 4.3 action send_goal
+我们只需要把goal发给服务端即可,根据goal的定义,我们可以看到goal是由一个浮点类型的theta组成的,我们把theta发给服务端。
 
 
+发送弧度制1.6给小乌龟
+
+```
+ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.6}"
+```
+
+结果
+```
+Waiting for an action server to become available...
+Sending goal:
+     theta: 1.6
+
+Goal accepted with ID: b215ad060899444793229171e76481c7
+
+Result:
+    delta: -1.5840003490447998
+
+Goal finished with status: SUCCEEDED
+```
+
+我们可以看到goal和result,但是没有看到feedback,这里我们需要加一个参数 --feedback
+
+加上这个参数我们再发送一次。
+
+
+```
+ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.5}" --feedback
+```
+
+可以看到了,这次的日志中多出了很多实时的反馈,反馈的数值是小乌龟当前的角度与我们给定的目标角度之间的差值,可以看到一直在变小。
+
+```
+
+Waiting for an action server to become available...
+Sending goal:
+     theta: 1.5
+
+Feedback:
+    remaining: -0.0840003490447998
+
+Goal accepted with ID: b368de0ed1a54e00890f1b078f4671c8
+
+Feedback:
+    remaining: -0.06800031661987305
+
+Feedback:
+    remaining: -0.05200028419494629
+
+Feedback:
+    remaining: -0.03600025177001953
+
+Feedback:
+    remaining: -0.020000219345092773
+
+Feedback:
+    remaining: -0.004000186920166016
+
+Result:
+    delta: 0.08000016212463379
+
+Goal finished with status: SUCCEEDED
+```
 

+ 17 - 12
docs/chapt5/5.9ROS2通信机制大总结.md

@@ -1,26 +1,31 @@
-5.9 ROS2通信机制大总结
+5.6 ROS2通信机制大总结
 
 恭喜恭喜恭喜你!完成了ROS2所有通信机制的学习,基于ROS2的通信机制,编写程序将机器人各个组件互相连接,完成一个属于自己的机器人指日可待!
 
 
 
+## 1.话题
 
+话题是单向的,而且不需要等待服务端上线,直接发就行,数据的实时性比较高。
 
-<!-- 本节小鱼主要想和大家扯扯闲话,说一说通信机制这件事
+频率高,实时性强的传感器数据的传递一般使用话题实现
 
-通信即信息传递,每每说起信息传递总让小鱼想起来中学课本上的烽火戏诸侯,烽火这种信息传递方式对应到ROS2中应该是话题通信,因为他们都具备单项传递数据这一特点。
+## 2.服务
 
-信息传递的方式多种多样,但都是源于实践生活
+服务是双向的,客户端发送请求后,服务端有响应,可以得知服务端的处理结果
 
-比如你以前是一个大户人家,有天想吃烧鸡,你给伙计一两银子去买只烧鸡,然后你就在家等着,过了一会伙计就带着烧鸡回来了。这种通信方式是不是和ROS2中的服务类似,只不过银子变成了请求值,烧鸡变成了返回值,伙计变成了ROS2的Service.
+频率较低,强调服务特性和反馈的场景一般使用服务实现。
 
-话题再回到机器人身上,比方说我们要做一个酒店配送机器人(手机下单,机器人把物品配送到门口)
-我们现在来梳理一下任务流程
+## 3.参数
 
-- 手机向机器人发送来瓶王老吉服务
-- 机器人收到服务并告诉手机确认任务并开始执行
-- 机器人开始前往补给点,拿王老吉
-- 机器人到达补给点,拿完王老吉前往目标点
-- 到达目标点,通知你已经前来取货 -->
+参数是节点的设置,用于配置节点,原理基于服务。
 
+## 4.动作
 
+动作适用于需要实时反馈的场景,原理基于话题和服务。
+
+## 5.总结
+
+截至目前,相信你已经掌握了ROS2中的话题和服务通信机制,这两种通信机制是ROS2中通信机制的精华部分,下一章节的参数和动作两种通信方式其实就是基于话题和服务实现的。
+
+保持好奇心,让我们继续往下学习吧。

+ 79 - 3
docs/chapt6/6.1ROS2接点管理之launch文件.md

@@ -2,7 +2,7 @@
 
 大家好,我是小鱼。今天我们来讲一讲launch文件。
 
-## 一、为什么需要launch文件
+## 1.为什么需要launch文件
 ### 1.1 需要启动的节点太多
 看过小鱼[动手学ROS2](https://d2lros2.fishros.com/)教程的同学都知道,我们每启动一个节点的时候,都是先打开一个新的终端,然后使用下面这种方式来启动节点:
 ```shell
@@ -26,7 +26,7 @@ ros2 run package-name  execute-name
 > 在ROS1中launch文件只有一种格式以.launch结尾的xml文档,不熟悉的同学写起来被xml语法折磨的死去活来。不过在ROS2中不要担心,因为在ROS2你可以使用Python代码来编写launch文件
 
 
-## 二、编写第一个ROS2的launch文件
+## 2.编写第一个ROS2的launch文件
 ### 2.1 三种编写launch文件的方法
 ROS2的launch文件有三种格式,python、xml、yaml。其中ROS2官方推荐的时python方式编写launch文件。
 原因在于,相较于XML和YAML,**Python是一个编程语言,更加的灵活,我们可以利用Python的很多库来做一些其他工作**(比如创建一些初始化的目录等)。
@@ -145,13 +145,89 @@ ros2 launch village_wang village.launch.py
 ![c++功能包测试](6.1ROS2接点管理之launch文件/imgs/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6bG86aaZUk9T,size_20,color_FFFFFF,t_70,g_se,x_16.png)
 
 
-## 三、将参数加入launch文件
+## 3.将参数加入launch文件
 
 当我们启动节点时,可以对该节点的参数进行赋值,比如我们可以尝试在启动节点时修改李四写书的速度,改变王二卖书的价格。
 
+在node中给param赋值即可。
 
 
+```python
+# 导入库
+from launch import LaunchDescription
+from launch_ros.actions import Node
+
+# 定义函数名称为:generate_launch_description
+def generate_launch_description():
+    # 创建Actions.Node对象li_node,标明李四所在位置
+    li4_node = Node(
+        package="village_li",
+        executable="li4_node",
+        output='screen',  #四个可选项 
+        parameters=[{'write_timer_period': 1}]
+        )
+    # 创建Actions.Node对象wang2_node,标明王二所在位置
+    wang2_node = Node(
+        package="village_wang",
+        executable="wang2_node",
+        output='screen',  #四个可选项 
+        parameters=[{'novel_price': 2}]
+        )
+    # 创建LaunchDescription对象launch_description,用于描述launch文件
+    launch_description = LaunchDescription([li4_node,wang2_node])
+    # 返回让ROS2根据launch描述执行节点
+    return launch_description
+```
+
+大家自行运行尝试。
+
+## 4.命名空间修改
+
+我们可以修改命名空间,这样就可以区分两个同名节点。
+
+```python
+# 导入库
+from launch import LaunchDescription
+from launch_ros.actions import Node
+
+# 定义函数名称为:generate_launch_description
+def generate_launch_description():
+
+
+    # 创建Actions.Node对象li_node,标明李四所在位置
+    li4_node = Node(
+        package="village_li",
+        executable="li4_node",
+        output='screen',  #四个可选项 
+        parameters=[{'write_timer_period': 1}]
+        )
+    # 创建Actions.Node对象wang2_node,标明王二所在位置
+    wang2_node = Node(
+        package="village_wang",
+        executable="wang2_node",
+        parameters=[{'novel_price': 2}]
+        )
+
+    # 创建另外一个命名空间下的,创建Actions.Node对象li_node,标明李四所在位置
+    li4_node2 = Node(
+        package="village_li",
+        namespace="mirror_town",
+        executable="li4_node",
+        parameters=[{'write_timer_period': 2}]
+    )
+    # 创建另外一个命名空间下的,Actions.Node对象wang2_node,标明王二所在位置
+    wang2_node2 = Node(
+        package="village_wang",
+        namespace="mirror_town",
+        executable="wang2_node",
+        parameters=[{'novel_price': 1}]
+    )
 
+    # 创建LaunchDescription对象launch_description,用于描述launch文件
+    launch_description = LaunchDescription([li4_node,wang2_node,wang2_node2,li4_node2])
+    # 返回让ROS2根据launch描述执行节点
+    return launch_description
+```
 
 ## 四、小总结
 今天只是简单讲了下,使用launch文件来同时启动多个接待年,但对节点的一些参数也可以在launch中配置

+ 1 - 0
docs/chapt6/6.2时光记录仪之rosbag2.md

@@ -101,6 +101,7 @@ ros2 bag play xxx.db3
 ros2 topic echo /sexy_girl
 ```
 ![播放话题信息](6.2时光记录仪之rosbag2/imgs/a78e638365ac4868bed8ff16cef1eb7e.png)
+
 ### 4.2 播放选项
 ### 4.2.1 倍速播放 -r 
 -r选项可以修改播放速率,比如 -r 值,比如 -r 10,就是10倍速,十倍速播放话题

+ 1 - 1
docs/chapt6/6.4RVIZ2.md

@@ -1,6 +1,6 @@
 # 6.4 RVIZ2
 
-作为机器人开发中常用的可视化工具RVIZ2。
+本节我们来说一说,机器人开发中常用的数据可视化工具RVIZ2。
 
 ## 1.RVIZ2是什么
 RVIZ2是ROS2中的一个非常重要且常用的数据可视化工具。

+ 1 - 1
docs/chapt6/6.5Gazebo介绍.md

@@ -1,6 +1,6 @@
 # 6.5 Gazebo介绍
 
-今天说说Gazebo,小鱼公司有一些同事傻傻的分不清Gazebo和Rviz之间的区别,只道是Gazebo和RVIZ都能显示机器人模型。
+今天说说Gazebo,有些同学没有学习RVIZ和Gazebo之前,分不清Gazebo和Rviz之间的区别,只道是Gazebo和RVIZ都能显示机器人模型。
 
 ## 1.Gazebo VS Rviz2
 昨天小鱼有说RVIZ2是什么:

+ 11 - 4
docs/chapt6/6.6ROS2命令行工具.md

@@ -1,7 +1,10 @@
-6.5 ROS2命令行工具
+6.6 ROS2命令行工具
 
-本节我们来对ROS2的命令行工具进行一个小结。打开终端,输入ros2,你将看到下面的内容:
+本节我们来对ROS2的命令行工具进行一个小结。
 
+## 1.命令小结
+
+打开终端,输入ros2,你将看到下面的内容:
 
 ```
 usage: ros2 [-h] Call `ros2 <command> -h` for more detailed usage. ...
@@ -33,9 +36,13 @@ Commands:
   Call `ros2 <command> -h` for more detailed usage.
 ```
 
-每一个Command都是对应着ROS2目前所拥有的工具
+
+每一个Command都是对应着ROS2目前所拥有的工具,其实每一个我们在前面的章节中几乎都使用过,而那些没有使用的到的,几乎都是不常用的,所以大家只需要将前面章节中的CLI掌握即可
+
+这里小鱼只是提示下,当我们忘记了某个命令行工具的时候该怎么办,可以使用对应的指令加上-h,即可获取其使用方法。
 
 
+## 2.总结
 
-待更新,欢迎关注微信公众号《鱼香ROS》,第一时间获取更新
+截至到本节,我们的动手学ROS2之旅的第一期已经圆满结束了,下一章节(第二期)我们会从机器人学基础知识讲起,带你一起完成机器人的建模和运动学仿真