1. ROS2节点创建与生命周期管理

任务目标

创建一个ROS2 Python节点,该节点在启动时执行初始化操作,在运行期间周期性发布消息,在关闭时执行清理操作。通过该节点演示ROS2节点的标准生命周期:构造→初始化→执行→销毁,并观察节点状态转换。

环境依赖

  • Ubuntu 22.04 + ROS2 Humble(或更高版本)
  • 已安装 rclpy 和 std_msgs 包
  • 已source ROS2环境:source /opt/ros/humble/setup.bash

完整实现

创建文件 lifecycle_node.py,内容如下:

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

class LifecycleDemoNode(Node):
    def __init__(self):
        # 节点初始化:创建节点、声明参数、创建发布器
        super().__init__('lifecycle_demo_node')
        self.publisher = self.create_publisher(String, 'lifecycle_topic', 10)
        self.timer = self.create_timer(1.0, self.timer_callback)
        self.counter = 0
        self.get_logger().info('节点已创建,进入初始化状态')

    def timer_callback(self):
        # 运行期间周期性执行
        msg = String()
        msg.data = f'第 {self.counter} 条消息'
        self.publisher.publish(msg)
        self.counter += 1
        self.get_logger().info(f'发布: {msg.data}')

    def destroy_node(self):
        # 销毁前清理:停止定时器、记录日志
        self.get_logger().info('节点销毁中,执行清理操作...')
        self.timer.cancel()
        super().destroy_node()

def main(args=None):
    rclpy.init(args=args)          # 1. 初始化ROS2客户端库
    node = LifecycleDemoNode()     # 2. 创建节点实例(构造+初始化)
    
    try:
        rclpy.spin(node)           # 3. 进入执行循环,等待回调
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()        # 4. 销毁节点(清理)
        if rclpy.ok():
            rclpy.shutdown()       # 5. 关闭ROS2客户端库
        print('节点已完全销毁,进程退出')

if __name__ == '__main__':
    main()

运行方式

  1. 打开终端,source ROS2环境
  2. 运行节点:python3 lifecycle_node.py
  3. 另开终端,查看节点列表:ros2 node list,应看到 /lifecycle_demo_node
  4. 查看话题消息:ros2 topic echo /lifecycle_topic

验证方法与判定标准

  • 初始化验证:运行节点后,终端输出 节点已创建,进入初始化状态,且 ros2 node list 能查到该节点
  • 执行验证:每1秒输出一条 发布: 第 N 条消息,ros2 topic echo 能收到对应消息
  • 销毁验证:按 Ctrl+C 终止进程,终端输出 节点销毁中,执行清理操作...,随后进程正常退出,ros2 node list 中节点消失
  • 状态转换观察:运行 ros2 lifecycle get /lifecycle_demo_node 可查看节点生命周期状态(当前为 active),说明节点处于正常运行状态

生命周期状态说明

ROS2节点生命周期遵循标准状态机:未配置(unconfigured)→未激活(inactive)→激活(active)→最终化(finalized)。本案例中,节点创建后直接进入 active 状态(默认配置),通过 rclpy.spin() 保持执行,销毁时通过 destroy_node() 完成清理并退出。如需显式管理状态转换,可使用 rclpy.lifecycle 模块,但本案例聚焦于基础节点的创建与销毁流程。

常见问题

  • 找不到 rclpy:确认已source ROS2环境,且Python版本匹配(ROS2 Humble需Python3.10)
  • 节点无法销毁:确保在 finally 块中调用 destroy_node(),避免异常导致资源泄漏
  • 话题收不到消息:检查发布器队列长度(本案例设为10),并确认订阅方已启动