ROS 消息的发送与接收(基于 python)

1、编写发布器节点 
1.1 源代码 

查看 talker.py 文件:

$ roscd dashgo_tutorials/scripts 
$ cat 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 Node 都会在顶部有这个声明。 第一行确保脚本作为 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)

这部分代码定义了说话者与 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 的末尾添加随机数确保您的节点具有唯一的名称。

rate = rospy.Rate(10) # 10h

此行创建一个 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 或其他)。 在这种情况下,“工作”是对 pub.publish(hello_str)的调用,它向我们的聊天话题发布字符 串。循环调用 rate.sleep(),睡眠时间足够长,以便通过循环保持期望的速率。 

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

std_msgs.msg.String 是一种非常简单的消息类型,因此您可能想知道发布更复杂的类型是 什么样子。一般的经验法则是构造函数的参数与.msg 文件中的顺序相同。您也可以不传入 参数并直接初始化字段,例如 

msg = String()
msg.data = str
try:
 	talker()
 except rospy.ROSInterruptException:
 	pass

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

2、编写订阅器节点 
2.1 源代码 

在 dashgo_tutorials/scripts 目录下查看 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()
2.2 代码说明 

下面我们将逐条解释代码,当然,之前解释过的代码就不再赘述了。

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、给 talker.py 和 listener.py 文件添加执行权限
$ roscd dashgo_tutorials/scripts 
$ chmod +x *
4、测试发布器和接收器
4.1 确保 roscore 可用,并运行:
$ roscore
4.2 启动发布器
$ rosrun dashgo_tutorials talker.py

将看到如下的输出信息: 

[INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
 [INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
 [INFO] [WallTime: 1314931836.788106] hello world 1314931836.79
4.3 启动订阅器
$ rosrun dashgo_tutorials listener.py

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

[INFO] [WallTime: 1314931969.258941] /listener_17657_1314931968795I 
heard hello world 1314931969.26
 [INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I 
heard hello world 1314931970.26
 [INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I 
heard hello world 1314931971.26

至此,已经测试完了发布器和订阅器(python)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序老猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值