机器人操作系统(ROS)实验课程
第三节 ROS的通信机制
一,理解ROS节点
预备工作
如果你之前安装的并非是ros的完整桌面版(Desktop-Full),请先
# 将<distro>替换成你安装的ROS发行版简称(比如kinetic或noetic等)。
sudo apt-get install ros-<distro>-ros-tutorials
图概念速览
计算图(Computation Graph)是一个由ROS进程组成的点对点网络,它们能够共同处理数据。ROS的基本计算图概念有节点(Nodes)、主节点(Master)、参数服务器(Parameter Server)、消息(Messages)、服务(Services)、话题(Topics)和袋(Bags),它们都以不同的方式向图(Graph)提供数据。
- 节点(Nodes):节点是一个可执行文件,它可以通过ROS来与其他节点进行通信。
- 消息(Messages):订阅或发布话题时所使用的ROS数据类型。
- 话题(Topics):节点可以将消息发布到话题,或通过订阅话题来接收消息。
- 主节点(Master):ROS的命名服务,例如帮助节点发现彼此。
- rosout:在ROS中相当于
stdout/stderr(标准输出/标准错误)
。 - roscore:主节点 + rosout + [参数服务器](https://wiki.ros.org/Parameter Server)(会在以后介绍)。
节点
节点实际上只不过是ROS软件包中的一个可执行文件。ROS节点使用ROS[客户端库](https://wiki.ros.org/cn/Client Libraries)与其他节点通信。节点可以发布或订阅话题,也可以提供或使用服务。
**注:**节点是ROS中非常重要的一个概念,为了帮助初学者理解这个概念,这里举一个通俗的例子:
例如,咱们有一个机器人,和一个遥控器,那么这个机器人和遥控器开始工作后,就是两个节点。遥控器起到了下达指 令的作用;机器人负责监听遥控器下达的指令,完成相应动作。从这里我们可以看出,节点是一个能执行特定工作任 务的工作单元,并且能够相互通信,从而实现一个机器人系统整体的功能。在这里我们把遥控器和机器人简单定义为两个节点,实际上在机器人中根据控制器、传感器、执行机构等不同组成模块,还可以将其进一步细分为更多的节点,这个是根据用户编写的程序来定义的。)
客户端库
ROS客户端库可以让用不同编程语言编写的节点进行相互通信:
- rospy = Python客户端库
- roscpp = C++客户端库
roscore
roscore
是你在运行所有ROS程序前首先要运行的命令。当然,在你运行一个launch时,如果没有roscore,ROS会自动的运行一个roscore
请打开终端运行
roscore
然后你应当看到以下的输出信息
... logging to ~/.ros/log/9cf88ce4-b14d-11df-8a75-00251148e8cf/roslaunch-machine_name-13039.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://machine_name:33919/
ros_comm version 1.4.7
SUMMARY
========
PARAMETERS
* /rosversion
* /rosdistro
NODES
auto-starting new master
process[master]: started with pid [13054]
ROS_MASTER_URI=http://machine_name:11311/
setting /run_id to 9cf88ce4-b14d-11df-8a75-00251148e8cf
process[rosout-1]: started with pid [13067]
started core service [/rosout]
如果roscore
运行后没有初始化,很有可能是网络配置的问题。参见网络配置 - 单机器配置。
如果roscore
不能初始化并提示缺少权限,可能是因为~/.ros
目录属于root
用户(只有root
用户才能访问),可以用以下命令递归地更改该目录的所有权:
sudo chown -R <your_username> ~/.ros
使用rosnode
打开一个新终端,可以使用rosnode
看看roscore
运行时干了些什么…… 记得要保持以前的终端开着,比如打开一个新的标签页,或者最小化之前的窗口。
注意: 当打开一个新的终端时,环境将会重置,
~/.bashrc
文件将会生效。如果你在运行rosnode
等命令时出现一些问题,那么可能需要将一些环境设置文件添加到~/.bashrc
或手动source
一下。
rosnode
显示当前正在运行的ROS节点信息。rosnode list
命令会列出这些活动的节点:
rosnode list
你会看到
/rosout
这表示当前只有一个节点在运行: rosout。因为这个节点用于收集和记录节点的调试输出,所以它总是在运行的。
而rosnode info
命令返回的是某个指定节点的信息。
rosnode info /rosout
这给了我们更多关于rosout
的信息, 比如说实际上它是发布了一个/rosout_agg
话题。
------------------------------------------------------------------------
Node [/rosout]
Publications:
* /rosout_agg [rosgraph_msgs/Log]
Subscriptions:
* /rosout [unknown type]
Services:
* /rosout/get_loggers
* /rosout/set_logger_level
contacting node http://machine_name:54614/ ...
Pid: 5092
现在,让我们看看其他节点。为此,我们将使用rosrun
调出另一个节点。
使用noderun
rosrun
可以让你用包名直接运行软件包内的节点(而不需要知道包的路径)。
rosrun [package_name] [node_name]
所以现在我们试着运行turtlesim
包中的turtlesim_node
。
在一个新终端中:
rosrun turtlesim turtlesim_node
应当出现
**注意:**此处的乌龟可能和你turtlesim窗口上的不同。别担心,实际上有许多版本的turtle ,而你的是个惊喜!(一个可爱的小彩蛋~)
在一个新终端中:
rosnode list
你会看到类似下面的输出信息:
/rosout
/turtlesim
ROS有一个强大的功能,就是你可以通过命令行重新分配名称。
关闭turtlesim窗口以停止节点(或回到rosrun turtlesim
的终端并按Ctrl+C
)。现在让我们重新运行它,但是这一次使用[重映射参数](https://wiki.ros.org/Remapping Arguments)来改变节点名称:
rosrun turtlesim turtlesim_node __name:=my_turtle
现在,如果我们回去使用rosnode list
:
rosnode list
你会看到类似下面的输出信息
/rosout
/my_turtle
**注意:**如果你仍看到
/turtlesim
在列表中,这可能因为你是在终端中使用Ctrl+C
停止的节点而不是关闭窗口,或者你没有按网络配置 - 单机器配置中的描述定义$ROS_HOSTNAME
环境变量。可以尝试清除下rosnode列表: $ rosnode cleanup
我们可以看到新的/my_turtle
节点。使用另外一个rosnode
指令,ping
,来测试它是否正常:
rosnode ping my_turtle
rosnode: node is [/my_turtle]
pinging /my_turtle with a timeout of 3.0s
xmlrpc reply from http://aqy:42235/ time=1.152992ms
xmlrpc reply from http://aqy:42235/ time=1.120090ms
xmlrpc reply from http://aqy:42235/ time=1.700878ms
xmlrpc reply from http://aqy:42235/ time=1.127958ms
未完待续…………