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

ROS订阅者仅在调用input()指令后才收到目标点消息的问题咨询

问题原因

这是ROS1的回调调度机制导致的:

  • ROS1的订阅者回调默认不会自动异步执行,所有待处理的消息回调都需要主线程主动调用rospy.spin()或者rospy.spinOnce()才会被触发执行
  • 你的代码实例化控制器类后直接执行move2goal中的打印逻辑,全程没有触发回调处理的操作,订阅到的目标点消息一直滞留在消息队列中,self.goal_pose始终是初始化的默认值
  • 加入input()后程序进入阻塞等待用户输入的状态,ROS后台拿到CPU时间处理消息队列,触发update_goal回调更新目标点变量,因此输入结束后打印的就是正确的目标值

修复方案

可根据使用场景选择以下任意一种方案:

方案1:手动触发回调处理(改动最小)

在move2goal的循环逻辑中加入rospy.spinOnce()主动处理回调:

def move2goal(self):
    # 等待目标点接收完成
    while not rospy.is_shutdown() and self.goal_pose.x == 0.0 and self.goal_pose.y == 0.0:
        rospy.spinOnce() # 处理一次待执行回调
        self.rate.sleep()
    
    print("self.goal , is:")
    print(self.goal_pose.x, self.goal_pose.y)

    while calc.euclidean_distance(self.odom,self.goal_pose) >= const.DISTANCE_TOLERANCE:
        # 原有移动逻辑不变
        rospy.spinOnce() # 每次循环都处理回调,支持运行中更新目标点
        self.rate.sleep()

    self.stop_the_bot()
    rospy.spin()

注:如果你的合法目标点包含(0,0),可以在__init__中新增标记位self.has_received_goal = False,在update_goal回调中将其设为True,循环判断该标记位即可避免误判。

方案2:回调触发移动逻辑

收到目标点后再启动移动流程,无需主动轮询:

def __init__(self):
    # 原有初始化逻辑不变
    self.has_received_goal = False

def update_goal(self,data): 
    self.goal_pose = data
    self.goal_pose.x = round(self.goal_pose.x, 4)
    self.goal_pose.y = round(self.goal_pose.y, 4)
    if not self.has_received_goal:
        self.has_received_goal = True
        self.move2goal() # 收到第一个目标点后自动启动移动

if __name__ == '__main__':
    try:
        x = oferbot_controller()
        rospy.spin() # 直接进入自旋等待回调,无需主动调用move2goal
    except rospy.ROSInterruptException:
        pass

方案3:启用异步回调线程

开独立线程自动处理所有回调,原有业务逻辑无需修改:

def __init__(self):
    rospy.init_node(const.MOVE_NODE_NAME, anonymous=True)
    # 原有发布订阅初始化逻辑不变
    # 新增以下两行启动异步回调处理
    self.spinner = rospy.AsyncSpinner(1)
    self.spinner.start()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:15:02