ROS(三) 编写简单的消息发布器和订阅器

一.前言

通过Python编写一个发布器节点和订阅器节点,该文章的目录如下:
编写发布节点
代码
解释
编写订阅节点
代码
解释
构建节点

编写发布节点

”节点“是ROS术语,它连接到ROS网络的可执行文件。在这里,我们将创建发布器(“talker”)节点不断广播消息。
进入之前创建的beginner_tutorials包

$ roscd beginner_tutorials

代码
首先创建scripts目录存放Python代码

$ mkdir scripts
$ cd scripts

下载例子脚本talker.py到scrips目录,并修改权限为可执行:

$ wget https://raw.github.com/ros/ros_tutorials/kinetic‐devel/rospy_tutorials/001_talker_
listener/talker.py
$ chmod +x talker.py

浏览和编辑:

$ rosed beginner_tutorials talker.py

内容如下:

#!/usr/bin/env python
#每个python的ROS节点会在顶部描述,,第一行确保你的脚本是使用python执行的脚本
# license removed for brevity
import rospy
from std_msgs.msg import String
#需要导入rospy客户端库,导入std_msgs.msg重用std_msgs/String消息类型
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
#定义talker 接口,pub = rospy.Publisher("chatter", String, #queue_size=10)表示节点发布chatter 话题,使用String 字符类型,实际上就是类#std_msgs.msg.String。queue_size 表示队列的大小(适合hydro以后版本),如果#队列消息处理不够快,就会丢弃旧的消息。
rate = rospy.Rate(10) # 10hz
#创建Rate 对象,与sleep()函数结合使用,控制话题消息的发布频率。
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
#rospy.is_shutdown()返回false 就会退出(例如按下Ctrl-C)
#程序执行pub.publish(String(str)),在chatter 话题发布String 消息
#r.sleep()通过睡眠来,保持消息发送频率
#rospy.loginfo(str)函数在屏幕输出调试信息,同时写入到节点日志文件和rosout 节#点
#
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
#标准的Python main 检查,这个会捕获rospy.ROSInterruptException 异常,当按#下Ctrl-C 或节点关闭的话,即使在rospy.sleep()和rospy.Rate.sleep()函数里都#会抛出异常。

编写订阅节点

代码
下载listener.py 到scripts 目录

$ roscd beginner_tutorials/scripts/
$ wget https://raw.github.com/ros/ros_tutorials/kinetic‐devel/rospy_tutorials/001_talker_
listener/listener.py

文件内容如下:

#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
def listener():
# In ROS, nodes are uniquely named. If two nodes with the same
# node are launched, the previous one is kicked off. The
# anonymous=True flag means that rospy will choose a unique
# name for our 'listener' node so that multiple listeners can
# run simultaneously.
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("chatter", String, callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
listener()

不要忘记增加可执行权限:

$ chmod +x listener.py

这表示节点订阅话题chatter,消息类型是std_msgs.msgs.String
当接受到新消息,回调函数就触发处理这些信息,并把消息作为第一个参数传递到函数里
还改变了调用rospy.init_node() ,增加anonymous=True 关键词参数。
ROS 要求每个节点要有唯一名称,如果相同的名称,就会中止之前同名的节点。
anonymous=True 标识就会告诉rospy,要生成一个唯一的节点名称,因此你可以有多个listener.py 同
时运行。
最后rospy.spin()简单保持你的节点一直运行,直到程序关闭。
不像roscpp,rospy.spin()不影响到订阅的回调函数,因为他们有自己的独立线程。

构建节点

我们使用CMake 作为构建系统,即使是Python 节点也需要使用。
这确保针对消息和服务能自动生成Python 代码
进入catkin 工作空间,运行catkin_make:

$ cd ~/catkin_ws
$ catkin_make

测试消息发布器和订阅器

启动发布器
启动订阅器
确保roscore 可用,并运行:

$ roscore

catkin specific 如果使用catkin,确保你在调用catkin_make 后,在运行你自己的程序前,已经source
了catkin 工作空间下的setup.sh 文件:

# In your catkin workspace
$ cd ~/catkin_ws
$ source ./devel/setup.bash
$ rosrun beginner_tutorials talker (C++)
$ rosrun beginner_tutorials talker.py (Python)

你将看到如下的输出信息:

[INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
[INFO] [WallTime: 1314931832.775497] hello world 1314931832.77
[INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
[INFO] [WallTime: 1314931834.782059] hello world 1314931834.78
[INFO] [WallTime: 1314931835.784853] hello world 1314931835.78
[INFO] [WallTime: 1314931836.788106] hello world 1314931836.79

发布器节点已经启动运行。现在需要一个订阅器节点来接受发布的消息。
我们编写了一个名为”listener”的订阅器节点。现在运行它:

$ rosrun beginner_tutorials listener (C++)
$ rosrun beginner_tutorials listener.py (Python)

你将会看到如下的输出信息:

[INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I heard hello world
1314931970.26
[INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I heard hello world
1314931971.26
[INFO] [WallTime: 1314931972.270429] /listener_17657_1314931968795I heard hello world
1314931972.27
[INFO] [WallTime: 1314931973.274382] /listener_17657_1314931968795I heard hello world
1314931973.27
[INFO] [WallTime: 1314931974.277694] /listener_17657_1314931968795I heard hello world
1314931974.28
[INFO] [WallTime: 1314931975.283708] /listener_17657_1314931968795I heard hello world
1314931975.28

猜你喜欢

转载自blog.csdn.net/weixin_40522162/article/details/80344450