ROS Publisher无法持续发布,如何同时实现订阅、发布与服务通告?
ROS节点同时实现订阅、发布与服务的问题修复
你的代码存在两个核心问题导致无法持续发布消息:
- 仅在节点初始化阶段调用了一次
self.accPlan_pub.publish(),之后rospy.spin()进入阻塞状态,没有后续发布逻辑 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
相关产品推荐
相关产品推荐

