记录一次ROS踩坑的经历。本来想用Python实现在一个节点中同时订阅两个话题的消息。在网上查阅了一些资料,其实没有找到特别合适的答案,大多数都是在回答“如何同时订阅和发布话题”这个在Wiki.ros.cn上已经有详细的教程。

我本以为还需要开两个线程,结果还是自己对ROS的话题通讯理解的不够透彻,尝试下来,其实很简单,只需要有两个Subcribe语句就行,分别订阅不同的Topic;ROS的机制是如果没有收到消息,就在spin()里面等待,一旦收到消息,就会去找相应话题名字对应的callback。

我的实现方法是,构造了两个类(class),由于我还实现了同时发布和订阅,因此还有订阅节点,并创建了两个线程,一个线程执行rospy.spin();一个线程执行Publish;如果有更好的方法欢迎给我留言哈!代码结构如下:

#定义线程函数
def thread_job():
    # print("ROSspin has started")
    rospy.spin()
class SubscribeAndPublish:
	def __init__(self):#初始化class时就创建
		#订阅节点
		self.sub = rospy.Subscriber('/rdb_info', info_pos, self.callback)   
		#发布节点
		self.pub = rospy.Publisher('CmdToVtd', Float32MultiArray,queue_size=1)
	def callback(self, data):#你的回调函数
class Subscribe_Objects:
	def __init__(self):#初始化class时就创建
		#订阅节点
		self.sub2 = rospy.Subscriber('/rdb_info_obj',info_pos_aeb_array,self.callback)   
	def callback(self, data):#你的回调函数
if __name__ == '__main__':
    rospy.init_node('self_locate')
    rate = rospy.Rate(10) # 10hz
    ic = SubscribeAndPublish() #第一个订阅函数
    ig = Subscribe_Objects()   #第二个订阅函数
    thread_rosspin = threading.Thread(target=thread_job)  
    thread_rosspin.start()
    while not rospy.is_shutdown():
    ic.recv_CAN() #这个函数里面有发布函数,具体内容就不写在这里了

以上便实现了一个节点同时订阅多个话题,另外,可以使用rqt_graph来检查节点和话题之间的关系。通过rostopic echo /topic来检查是否话题正常发送和接收。
我就又踩了一个坑,发现我这两个话题/rdb_info/rdb_info_aeb每次只能接收到一个,整整卡了我一天!!这个问题太鬼畜了,每次只能收到最好发送的那个话题。结果发现是我的发布节点写错了,我的两个话题的发布节点的名称居然是一样的!!!那肯定只能收到一个话题消息啊!引以为鉴吧!但是不得不承认rqt_graphrostopic echo /topic好用之处。

如果这篇文章有帮到您,请给我一个小小的赞呀~谢谢啦