You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在roslibpy中将订阅的话题数据存储到变量中?

解决roslibpy订阅字符串话题数据保存到变量的问题

在roslibpy中,订阅回调函数是异步触发的,直接返回msg['data']不会有效果——因为回调的执行时机由roslibpy的事件循环控制,返回值无法被主逻辑捕获。以下是几种可行的实现方式:

方法一:使用全局变量

最简单的方式是定义一个全局变量,在回调函数中更新它,主逻辑可直接访问该变量:

from __future__ import print_function
import roslibpy
import time

# 定义全局变量存储订阅到的数据
received_data = ""

def callback(msg):
    global received_data
    received_data = msg['data']
    print(f"更新数据:{received_data}")


client = roslibpy.Ros(host='localhost', port=9090)
client.run()
listener = roslibpy.Topic(client, '/chatter2', 'std_msgs/String')
listener.subscribe(callback)

try:
    while True:
        # 主逻辑中可随时使用received_data
        time.sleep(1)
        print(f"当前存储的数据:{received_data}")
except KeyboardInterrupt:
    client.terminate()

方法二:使用类封装(更规范)

如果项目规模较大,用类封装订阅逻辑和数据存储,能避免全局变量的混乱:

from __future__ import print_function
import roslibpy
import time

class ROSDataSubscriber:
    def __init__(self, host, port, topic_name, topic_type):
        self.received_data = ""
        self.client = roslibpy.Ros(host=host, port=port)
        self.topic = roslibpy.Topic(self.client, topic_name, topic_type)
        self.topic.subscribe(self.callback)
        self.client.run()

    def callback(self, msg):
        self.received_data = msg['data']
        print(f"更新数据:{self.received_data}")

# 初始化订阅器
subscriber = ROSDataSubscriber('localhost', 9090, '/chatter2', 'std_msgs/String')

try:
    while True:
        time.sleep(1)
        print(f"当前存储的数据:{subscriber.received_data}")
except KeyboardInterrupt:
    subscriber.client.terminate()

方法三:使用队列(适合多线程/异步场景)

如果需要在其他线程或异步任务中处理订阅数据,用queue.Queue可实现线程安全的数据传递:

from __future__ import print_function
import roslibpy
import time
import queue
import threading

def callback(msg, data_queue):
    data_queue.put(msg['data'])
    print(f"推送数据到队列:{msg['data']}")

def process_data(data_queue):
    # 单独线程处理数据
    while True:
        data = data_queue.get()
        print(f"处理数据:{data}")
        data_queue.task_done()

client = roslibpy.Ros(host='localhost', port=9090)
client.run()
data_queue = queue.Queue()

# 启动数据处理线程
processing_thread = threading.Thread(target=process_data, args=(data_queue,), daemon=True)
processing_thread.start()

listener = roslibpy.Topic(client, '/chatter2', 'std_msgs/String')
# 回调中传递队列引用
listener.subscribe(lambda msg: callback(msg, data_queue))

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    client.terminate()

关键说明

roslibpy的订阅回调基于事件循环异步执行,必须通过外部可访问的存储介质(全局变量、类属性、队列等)保存数据,而非依赖回调的返回值。主逻辑使用数据时,注意处理数据未初始化的情况(比如订阅还未收到数据时变量为空)。

内容的提问来源于stack exchange,提问作者upix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 23:25:56