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

ROS2 Foxy(Windows)使用launch启动节点阻塞问题求助

ROS2 Foxy Windows下launch启动节点阻塞无输出问题解决

问题描述

Windows系统使用ROS2 Foxy版本,创建了topic_helloworld_pub发布节点、topic_helloworld_sub订阅节点及simple.launch.py启动文件。使用ros2 launch启动时,终端无报错但进程阻塞无输出,按下ctrl+c终止后,两节点才各输出一条消息并结束;但用ros2 run分别启动节点时一切正常。

相关代码

发布节点(topic_helloworld_pub)

import rclpy                                     
from rclpy.node import Node                      
from std_msgs.msg import String                  


class PublisherNode(Node):
    
    def __init__(self, name):
        super().__init__(name)                                    
        self.pub = self.create_publisher(String, "chatter", 10)   
        self.timer = self.create_timer(0.5, self.timer_callback)  
        
    def timer_callback(self):                                     
        msg = String()                                            
        msg.data = 'Hello World'                                 
        self.pub.publish(msg)                                     
        self.get_logger().info('Publishing: "%s"' % msg.data)     
        
def main(args=None):                                 
    rclpy.init(args=args)                           
    node = PublisherNode("topic_helloworld_pub")     
    rclpy.spin(node)                                
    node.destroy_node()                              
    rclpy.shutdown()                                 

订阅节点(topic_helloworld_sub)

import rclpy                                     
from rclpy.node   import Node                    
from std_msgs.msg import String                  


class SubscriberNode(Node):
    
    def __init__(self, name):
        super().__init__(name)                                   
        self.sub = self.create_subscription(\
            String, "chatter", self.listener_callback, 10)        

    def listener_callback(self, msg):                             
        self.get_logger().info('I heard: "%s"' % msg.data)        
        
def main(args=None):                                
    rclpy.init(args=args)                            
    node = SubscriberNode("topic_helloworld_sub")    
    rclpy.spin(node)                                
    node.destroy_node()                             
    rclpy.shutdown()                                 

启动文件(simple.launch.py)

from launch import LaunchDescription           
from launch_ros.actions import Node            

def generate_launch_description():             
    return LaunchDescription([                 
        Node(                                  
            package='launch_test',          
            executable='topic_helloworld_pub', 
        ),
        Node(                                  
            package='launch_test',          
            executable='topic_helloworld_sub', 
        ),
    ])

终端输出

G:\python-work\ROS2\Lab1>ros2 launch launch_test simple.launch.py  
[INFO] [launch]: All log files can be found below C:\Users\Administrator\.ros\log\2024-07-04-16-51-07-430723-MS-UISXVFQQVNRF-11664
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [topic_helloworld_pub.EXE-1]: process started with pid [4524]
[INFO] [topic_helloworld_sub.EXE-2]: process started with pid [15504]
[WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
[ERROR] [topic_helloworld_pub.EXE-1]: process has died [pid 4524, exit code 3221225786, cmd 'G:\python-work\ROS2\Lab1\install\launch_test\lib\launch_test\topic_helloworld_pub.EXE --ros-args'].
[topic_helloworld_pub.EXE-1] [INFO] [1720083068.578953900] [topic_helloworld_pub]: Publishing: "Hello World"

[ERROR] [topic_helloworld_sub.EXE-2]: process has died [pid 15504, exit code 3221225786, cmd 'G:\python-work\ROS2\Lab1\install\launch_test\lib\launch_test\topic_helloworld_sub.EXE --ros-args'].
[topic_helloworld_sub.EXE-2] [INFO] [1720083068.579490800] [topic_helloworld_sub]: I heard: "Hello World"

问题原因

这是Windows系统下ROS2 Foxy的进程输出缓冲机制问题:

  • 用ros2 launch启动时,Python进程默认采用全缓冲模式,日志消息不会实时输出到终端,直到进程退出时才一次性刷新缓冲。
  • 用ros2 run启动时,系统自动配置了行缓冲模式,所以消息能实时显示。

修复方法

方法1:修改节点代码强制刷新输出

在日志打印语句中添加flush=True参数,确保每次日志输出后立即刷新缓冲:

修改发布节点的日志行:

self.get_logger().info('Publishing: "%s"' % msg.data, flush=True)

修改订阅节点的日志行:

self.get_logger().info('I heard: "%s"' % msg.data, flush=True)

方法2:修改launch文件配置输出模式

给每个Node添加output='screen'参数,并传递Python无缓冲启动参数-u:

from launch import LaunchDescription           
from launch_ros.actions import Node            

def generate_launch_description():             
    return LaunchDescription([                 
        Node(                                  
            package='launch_test',          
            executable='topic_helloworld_pub',
            output='screen',
            arguments=['-u']
        ),
        Node(                                  
            package='launch_test',          
            executable='topic_helloworld_sub',
            output='screen',
            arguments=['-u']
        ),
    ])
  • output='screen':让launch直接捕获进程输出并打印到终端
  • -u:强制Python使用无缓冲的标准输出/错误流,确保消息实时显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:38:13