源代码
#!/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
逐行解析
#!/usr/bin/env python
每个Python ROS 节点都会在顶部显示此声明。第一行确保您的脚本作为Python脚本执行。
import rospy from std_msgs.msg import String
def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) 这部分代码定义了讲话者与其余ROS的接口。pub = rospy.Publisher(“chatter”,String,queue_size = 10)声明您的节点使用消息类型String发布到chatter主题。这里的字符串实际上是类std_msgs.msg.String。queue_size是若消息订阅的较慢,限制消息发布的数量,,下一行rospy.init_node(NAME,...)非常重要,因为它告诉rospy节点的名称 - 直到rospy有这个信息,它才能开始与ROS Master通信。在这种情况下,您的节点将采用名称说话者。注意:名称必须是基本名称,即它不能包含任何斜杠“/”。anonymous = True通过在NAME末尾添加随机数来确保您的节点具有唯一名称。有关节点初始化选项的更多信息,请参阅rospy文档中的初始化和关闭 - 初始化ROS节点。 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()标志然后做工作。你必须检查is_shutdown()以检查你的程序是否应该退出(例如,如果有Ctrl-C或其他)。在这种情况下,“work”是对pub.publish(hello_str)的调用,它将字符串发布到我们的聊天主题。循环调用rate.sleep(),它睡眠的时间足够长,可以通过循环保持所需的速率。这个循环还调用rospy.loginfo(str),它执行三重任务:消息被打印到屏幕,它被写入Node的日志文件,并被写入rosout。rosout对于调试非常方便:您可以使用rqt_console来提取消息,而不必使用Node的输出找到控制台窗口。
std_msgs.msg.String是一种非常简单的消息类型,因此您可能想知道发布更复杂类型的样子。一般的经验法则是构造函数args的顺序与.msg文件中的顺序相同。您也可以不传递参数并直接初始化字段,例如
if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass 除了标准的Python __main__检查之外,这还会捕获一个rospy.ROSInterruptException异常,当按下Ctrl-C或者你的节点关闭时,rospy.sleep()和rospy.Rate.sleep()方法可以抛出该异常。引发此异常的原因是,您不会在sleep()之后意外地继续执行代码。
下面创建订阅者的节点源代码
#!/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()