ROS中如何在另一Python文件中使用话题接收的变量?
问题分析与解决方案
你的问题核心有两点:
- 另一个文件中创建的
listenerPy实例从未启动ROS订阅逻辑,也没处理回调,导致received_integer始终是初始的None - ROS节点默认是独立进程,不同进程间无法直接共享内存变量,必须用ROS原生通信机制实现数据传递
下面分两种场景给出解决方法:
场景1:两个逻辑在同一个进程内运行
修改listener.py,将ROS的spin()放在后台线程运行,避免阻塞主线程:
#!/usr/bin/env python import rospy from std_msgs.msg import Int32 import threading class listenerPy: def __init__(self): self.received_integer = None self._spin_thread = None def callback(self, data): self.received_integer = data.data print(self.received_integer) def start_listener(self): # 避免重复初始化节点 if not rospy.is_initialized(): rospy.init_node('listener', anonymous=True) rospy.Subscriber('chatter', Int32, self.callback) # 用守护线程运行spin,不阻塞主线程 self._spin_thread = threading.Thread(target=rospy.spin) self._spin_thread.daemon = True self._spin_thread.start() def stop_listener(self): if self._spin_thread and self._spin_thread.is_alive(): rospy.signal_shutdown("Stopping listener") self._spin_thread.join() if __name__ == '__main__': try: listener = listenerPy() listener.start_listener() rospy.spin() except rospy.ROSInterruptException: pass
另一个文件修改为:
#!/usr/bin/env python from listener import listenerPy from time import sleep import rospy def main(): # 初始化ROS节点 if not rospy.is_initialized(): rospy.init_node('data_consumer', anonymous=True) local_var = listenerPy() local_var.start_listener() # 启动订阅逻辑 try: while not rospy.is_shutdown(): value = local_var.received_integer print(value) sleep(1) except KeyboardInterrupt: local_var.stop_listener() if __name__ == '__main__': main()
场景2:两个独立ROS节点(分开运行两个脚本)
这种场景下必须用ROS的通信机制传递数据,这里用参数服务器实现:
修改listener.py,将收到的数据写入参数服务器:
#!/usr/bin/env python import rospy from std_msgs.msg import Int32 class listenerPy: def __init__(self): self.received_integer = None def callback(self, data): self.received_integer = data.data rospy.set_param('/received_integer', self.received_integer) # 写入参数服务器 print(self.received_integer) def listener(self): rospy.init_node('listener', anonymous=True) rospy.Subscriber('chatter', Int32, self.callback) rospy.spin() if __name__ == '__main__': try: listener = listenerPy() listener.listener() except rospy.ROSInterruptException: pass
另一个文件从参数服务器读取数据:
#!/usr/bin/env python import rospy from time import sleep def main(): rospy.init_node('data_reader', anonymous=True) while not rospy.is_shutdown(): try: value = rospy.get_param('/received_integer') print(value) except KeyError: print("暂无可用数据") sleep(1) if __name__ == '__main__': try: main() except KeyboardInterrupt: pass
内容的提问来源于stack exchange,提问作者Bo Mengels
相关产品推荐
相关产品推荐

