[ROS] [笔记(1)] 一个最简单的例子:Hello Robot(消息、发布者与订阅者)

本例程包含如下内容:
1)创建编译 Package;
2)自定义消息;
3)发布者与订阅者。

0、Hello Robot 的场景:
我们想要完成这样一个场景:

1)有一系列 robot 排成一排(publisher)向管理员(subscriber)报道,每个人都发一个消息(robotID),包含 name 和 id 类似:
name=robot id=0
name=robot id=1
name=robot id=2

2)有一个管理员订阅了这个消息(robotID),然后读取消息内容并且和每个机器人打招呼:
hello robot 0
hello robot 1
hello robot 2

要完成以上的功能,我们需要创建消息(robotID)、发送消息的发送者(publisher)、接收消息的订阅者(subscriber)。他们之间的关系是这样的:
hellorobot_graph

1、创建 ros 目录:
先我们为所有的 ROS 工程创建如下路径:

以后的笔记里面,我们把这一路径称作 ROS_PATH,这一路径就是我们所有 ros 工程的基本路径。

2、创建 workspace 和 package:
一个典型的 ros 工程是在一个 workspace 下包含若干个包,每一个包应该完成一套独立的功能。它的路径通常类似于:
workspace_folder/ -- WORKSPACE
src/ -1- SOURCE SPACE
CMakeLists.txt -- 'Toplevel' CMake file, provided by catkin
package_1/
CMakeLists.txt -- CMakeLists.txt file for package_1
package.xml -- Package manifest for package_1
...
package_n/
CMakeLists.txt -- CMakeLists.txt file for package_n
package.xml -- Package manifest for package_n

我们的 workspace 命名为 hellorobot_ws,我们将所有有关这一工程的包都放在 hellorobot_ws/src 路径下,现在进入 ROS_PATH 创建这个目录:
1) 创建 workspace:

2)创建 package:
我们在该 workspace 的 src 目录下创建一个名为 hellorobot 的 package:

这里面 std_msgs rospy roscpp 是我们通常一个最基本的C++包之中需要的依赖项。后面这些依赖项均可以通过配置 package.xml 进行更改。

3)编译 package:
即使什么都不写我们已经可以编译这个包了。编译包需要在 workspace 路径下

编译成功后在 ROS_PTAH/hellorobot_ws 下就可以看到如下目录结构已经生成了:
build
devel
src

顺便说一下大家在网上下git代码,其实都是其中一个包的src的部分,相当于我们的 ROS_PTAH/hellorobot_ws/src/hellorobot/src,因此只要放入这一目录再按照此步骤运行 catkin_make 即可。

3、创建自定义消息:
1)创建 robotMsg.msg 文件:
在这里我们需要一个消息,包含 name 和 id 两个字段,其中 name 自然都是 robot。我们在 ROS_PTAH/hellorobot_ws/src/hellorobot 路径下创建 msg 文件夹,然后新建 robotMsg.msg 文件:

文件内容如下:

2)在 package.xml 添加 message 依赖:
在 package.xml 中找到如下两行代码并且取消注释:

这两行分别表示在编译和运行时的 message 依赖。

3)在 CMakeList.txt 添加编译依赖:

找到 find_package 添加 message_generation,结果如下:

找到 add_message_files ,去掉注释并添加 robotMsg.msg 消息文件:

找到 generate_messages 函数去掉注释,结果如下:

找到 catkin_package 添加如下行并启用该部分,结果如下:

顺便说下,如果你运行 catkin_make 以后,这个消息的头文件生成在:
devel/include/hellorobot/robotMsg.h
目录下。

4、创建发布者 publisher:
我们在 ROS_PTAH/hellorobot_ws/src/hellorobot/src 目录下创建 publisher.cpp 文件,代码内容如下:

其中最关键的其实只有几行:

这一行声明了我们的 Node 名字叫 “publisher”。

这一行创建了一个 Node 句柄和 Publisher,它发布的消息是 “robotID”,后面的1000是缓存消息队列长度。

后面是一个循环来不断发送消息,其中:

这一部分是我们填写的消息内容,主要的后面两行,这是我们设计的消息部分。前面 header 基本上每个消息都会填写一下。

最后我们只需要:

就把消息发送出去了。

这一行也很关键,这是为了让后面 subscriber 的 callback 能够生效。

其余部分是控制循环时间的机制,这里就不赘述了。

5、创建订阅者 subscriber:
我们在 ROS_PTAH/hellorobot_ws/src/hellorobot/src 目录下创建 subscriber.cpp 文件,代码内容如下:

其中最关键的其实只有几行:

这是我们真正的回调函数,是 subscriber 接收到订阅消息的处理函数。这里我们仅仅是打出 msg 中我们之前定义的内容,id 和 name。

这一行与之前 Publisher 类似,唯一不同的是,这里用 checkRobotCallback 指定了我们之前定义的回调函数。