ROS教程中Publisher和Subscriber (Python)的说明

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lqzdreamer/article/details/82813282

Publisher和Subscriber[Python]的说明

1.编写发布节点

$ roscd beginner_tutorials     #切换到package文件夹下
$ mkdir scripts     # 新建存放Python脚本的文件夹
$ cd scripts     #切换
#例程中的文件下载。talker.py publisher脚本
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/talker.py
$ chmod +x talker.py     # 对文件添加可执行指令

talker.py 文件中内容说明:

#!/usr/bin/env python
# license removed for brevity
import rospy     # 编写ROS节点,则需要导入rospy
from std_msgs.msg import String     # std_msgs.msg 导入是为了我们可以 reuse std_msgs / String消息类型(一个简单的字符串容器
#container)进行发布。

def talker():
     #这部分代码定义了讲talker与其余ROS的接口。
     # 声明节点使用消息类型String发布到chatter topic 。 这里的字符串实际上是类std_msgs.msg.String
     #queue_size参数在ROS hydro中是新的参数 ,如果任何订户没有fast enough接收它们,则限制排队消息的数量。 在旧的ROS发行版中,只省略
     #这个参数
    pub = rospy.Publisher('chatter', String, queue_size=10)
     # 声明节点的名字,直到rospy有这个信息,它才能开始与ROS Master通信。
     # 名称必须是base name,即它不能包含任何斜杠“/”。
     # anonymous = True通过在NAME末尾添加随机数来确保节点具有唯一名称。
    rospy.init_node('talker', anonymous=True)
     # 此行创建Rate对象速率。
     # 借助其方法sleep(),它提供了一种以所需速率循环的便捷方式。 它的参数为10,我们期望每秒循环10次(处理时间不超过1/10秒)
    rate = rospy.Rate(10) # 10hz
     # 这个循环是一个相当标准的rospy构造:检查rospy.is_shutdown()标志然后工作。
     #检查is_shutdown()以检查程序是否应该退出(例如,如果有Ctrl-C或其他)。 在这种情况下,“work”是对pub.publish(hello_str)的
     #调用,它将字符串发布到chatter主题。 循环调用rate.sleep(),它sleep时间足够长,可以通过循环保持所需的速率。
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
     # 这个循环还调用rospy.loginfo(str),它执行三重任务:消息被打印到屏幕,它被写入Node的日志文件,并被写入rosout。
     # rosout对于调试非常方便:可以使用rqt_console来提取消息,而不必使用Node的输出找到控制台窗口。
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

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

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

2.编写订阅节点

$ roscd beginner_tutorials/scripts/
$ wget https://raw.github.com/ros/ros_tutorials/kineticdevel/rospy_tutorials/001_talker_listener/listener.py
$ chmod +x listener.py

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)
     # 这声明节点订阅了std_msgs.msgs.String类型的chatter主题。收到新消息时,将调用回调,并将消息作为第一个参数。
     # 我们也稍微改变了对rospy.init_node()的调用。 我们添加了anonymous = True关键字参数。 ROS要求每个节点都有唯一的名称。
     # 如果出现具有相同名称的节点,则会突然显示前一个节点。 这样可以很容易地将故障节点从网络中踢出。 anonymous = True标志告诉
     # rospy为节点生成一个唯一的名称,以便可以轻松运行多个listener.py节点。
    # spin() simply keeps python from exiting until this node is stopped
     # 最后添加,rospy.spin()只是让节点退出,直到节点关闭。 与roscpp不同,rospy.spin()不会影响订阅者回调函数,因为它们
     # 有自己的线程。
    rospy.spin()

if __name__ == '__main__':
    listener()

3.编译现在的节点

使用CMake作为构建系统,即使是Python节点也必须使用它。 这是为了确保创建消息和服务的自动生成的Python代码。
转到catkin工作区并运行catkin_make:

$ cd ~/catkin_ws
$ catkin_make

测试Publisher和Subscriber (Python)

$ roscore

新开一个终端:

# In your catkin workspace
$ cd ~/catkin_ws
$ source ./devel/setup.bash
$ rosrun beginner_tutorials talker.py

再开一个终端:

# In your catkin workspace
$ cd ~/catkin_ws
$ source ./devel/setup.bash
$ rosrun beginner_tutorials listener.py

效果为:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lqzdreamer/article/details/82813282