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

ROS Publisher无法持续发布,如何同时实现订阅、发布与服务通告?

ROS节点同时实现订阅、发布与服务的问题修复

你的代码存在两个核心问题导致无法持续发布消息:

  1. 仅在节点初始化阶段调用了一次self.accPlan_pub.publish(),之后rospy.spin()进入阻塞状态,没有后续发布逻辑
  2. modelRec回调中使用了未初始化的self.old_model,会触发运行时错误

以下是修复后的完整代码,同时实现持续发布消息、订阅话题和提供服务三个功能:

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import rospy
from std_msgs.msg import String, Bool
from state_controller.srv import ActorChange, ActorChangeResponse

class StateController:
    def __init__(self):
        self.accum_plan = {}
        self.old_model = None  # 初始化变量,避免回调报错
        rospy.init_node("state_controller", anonymous=True, log_level=rospy.INFO)
        
        # 初始化发布者、订阅者和服务
        self.accPlan_pub = rospy.Publisher("accumulated_plan", String, queue_size=10)
        rospy.Subscriber("model", String, self.modelRec)
        rospy.Service("change_actor", ActorChange, self.changeActor)
        
        # 设置定时器,每隔1秒发布一次消息(可根据需求调整周期)
        self.publish_timer = rospy.Timer(rospy.Duration(1.0), self.publish_accum_plan)
        
        rospy.spin()

    def publish_accum_plan(self, event):
        """定时器触发的持续发布逻辑"""
        self.accPlan_pub.publish(json.dumps(self.accum_plan))

    ## Subscriber CallBacks
    def modelRec(self, data):
        """处理model话题订阅消息"""
        model = json.loads(data.data)
        if model != self.old_model:
            self.old_model = model
            # 可选:当model更新时立即发布一次accum_plan
            # self.accPlan_pub.publish(json.dumps(self.accum_plan))

    def changeActor(self, req):
        """处理change_actor服务请求"""
        lego = req.data
        # 这里可以添加实际的actor变更逻辑
        return ActorChangeResponse(True)

if __name__ == "__main__":
    try:
        controller_ = StateController()
    except rospy.ROSInterruptException:
        rospy.logerr("State Controller interrupted")

关键修复说明:

  • 持续发布:使用rospy.Timer创建周期性任务,替代单次发布,确保消息持续推送
  • 变量初始化:添加self.old_model = None,避免回调中的未定义变量错误
  • 结构优化:将订阅者、服务的初始化移至__init__,逻辑更清晰;移除不必要的rospy.sleep(3),避免延迟回调处理
  • 日志修复:用ROS原生的rospy.logerr替代未导入的logging.error

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:31:36