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
相关产品推荐
相关产品推荐

