ROS教程四——编写Publisher和Subscriber节点(Python篇)

本教程介绍如何在python中编写发布者和订阅者节点

1、编写Publisher节点 

“节点”是连接到ROS网络的可执行文件的ROS术语。在这里,我们将创建广播消息的 publisher(“talker”)节点。

将目录更改为之前教程中创建的beginner_tutorials包:

$ roscd beginner_tutorials

  1.1 代码

首先,创建一个'scripts'文件夹来存储你的Python脚本:

$ mkdir scripts
$ cd scripts

talker.py源代码如下:

#!/usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

  1.2 代码解释

#!/usr/bin/env python

每个Python ROS节点都会在顶部显示此声明。第一行确保您的脚本作为Python脚本执行。

import rospy
from std_msgs.msg import String

编写ROS节点,则需要导入rospy。std_msgs.msg导入是为了可以重用std_msgs / String消息类型(一个简单的字符串容器)进行发布。

  pub = rospy.Publisher('chatter', String, queue_size=10)
  rospy.init_node('talker', anonymous=True)

这部分代码定义了talker与其它ROS的接口。pub = rospy.Publisher("chatter", String, queue_size=10) 声明节点使用String消息类型,发布到chatter主题。这里的字符串实际上是类std_msgs.msg.String。queue_size参数在ROS hydro中是新的类型,如果任何订户没有足够快地接收它们,则限制排队消息的数量。在旧的ROS发行版中,只省略了这个论点。

下一行rospy.init_node(NAME,...)非常重要,因为它发布rospy节点的名称 - 直到rospy有这个信息,它才能开始与ROS 主机通信。在这种情况下,节点将采用名称talker。注意:名称必须是基本名称,即它不能包含任何斜杠“/”。

anonymous = True通过在NAME末尾添加随机数来确保您的节点具有唯一名称。有关节点初始化选项的更多信息,请参阅Initialization and Shutdown - Initializing your ROS Node

 rate = rospy.Rate(10) # 10hz

此行创建Rate对象速率。借助其方法sleep(),它提供了一种以所需速率循环的便捷方式。它的参数为10,我们应该期望每秒循环10次(只要我们的处理时间不超过1/10秒!)

    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

这个循环是一个相当标准的rospy构造:检查rospy.is_shutdown()标志然后做工作。检查程序是否应该退出(例如,如果有Ctrl-C或其他)。在这种情况下,“work”是对pub.publish(hello_str)的调用,它将字符串发布到我们的talker主题。循环调用rate.sleep(),保持循环所需的速率。

也可以运行rospy.sleep(),它类似于time.sleep(),但它也适用于模拟时间(请参阅Clock)。

这个循环还调用rospy.loginfo(str),它执行三重任务:消息被打印到屏幕,它被写入Node的日志文件,并被写入rosout。rosout对于调试非常方便:您可以使用rqt_console来提取消息,而不必使用Node的输出找到控制台窗口。

std_msgs.msg.String是一种非常简单的消息类型。一般的经验法则是构造函数args的顺序与.msg文件中的顺序相同。也可以不传入参数并直接初始化字段,例如

msg = String()
msg.data = str

或者可以初始化某些字段,并将其余字段保留为默认值:

String(data=str)

最后一点:

  try:
        talker()
    except rospy.ROSInterruptException:
        pass

除了标准的Python __main__检查之外,这还会捕获一个rospy.ROSInterruptException异常,当按下Ctrl-C或者你的节点关闭时,rospy.sleep()和rospy.Rate.sleep()方法可以抛出该异常。引发此异常的原因是不会在sleep()之后意外地继续执行代码。

2、编写Subscriber节点

2.1 代码

    

#!/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()

2.2 代码解释

    listener.py的代码类似于talker.py,除了引入了一个新的基于回调的机制来订阅消息。

    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

这声明的节点订阅了std_msgs.msgs.String类型的chatter主题。收到新消息时,将调用回调函数,并将消息作为第一个参数。

也稍微改变了对rospy.init_node()的调用。添加了anonymous = True关键字参数。ROS要求每个节点都有唯一的名称。如果出现具有相同名称的节点,则会突然显示前一个节点。这样可以很容易地将故障节点从网络中踢出。anonymous = True标志告诉rospy为节点生成一个唯一的名称,以便可以轻松运行多个listener.py节点。

最后添加,rospy.spin()只是让节点退出,直到节点关闭。与roscpp不同,rospy.spin()不会影响订阅者回调函数,因为它们有自己的线程。

3、编译 nodes 

使用CMake作为构建系统,即使是Python节点也必须使用它。这是为了确保创建消息和服务的自动生成的Python代码。

转到catkin工作区并运行catkin_make

$ cd ~/catkin_ws
$ catkin_make

既然已经编写了一个简单的发布者和订阅者,让我们来查看ROS教程五-运行简单的发布者和订阅者。

展开阅读全文

没有更多推荐了,返回首页