在这里插入图片描述

ROS1 系列教程(总目录)
ROS2 系列教程(总目录)
ROS2 系列教程源码、学习群

一、生命周期节点

ROS2除了常用的 rclcpp::Node 节点,还有一种 rclcpp_lifecycle::LifecycleNode 节点,生命周期节点(LifecycleNode / ManagedNode)是 ROS2 引入的有状态节点,它将节点的生命周期划分为明确的状态,每个状态之间有严格的转换规则。

它基于 rclcpp::Node 实现,有 rclcpp::Node 的所有标准API。

特性 rclcpp::Node(普通节点) rclcpp_lifecycle::LifecycleNode(生命周期节点)
运行模式 启动即运行,无状态控制 必须按状态流转:未配置→配置→激活→运行
状态管理 4 个稳态 + 5 个过渡态(上一轮你问的那些)
回调函数 构造函数直接初始化 必须重写:onConfigure/onActivate/onDeactivate
使用场景 工具节点、简单功能、调试 传感器、驱动、算法、机器人核心节点
受控能力 无法安全启停 可远程安全激活 / 关闭,不崩溃
发布 / 订阅 普通 rclcpp 接口 生命周期管理的接口(自动启停)
启动依赖 依赖 lifecycle_msgs 服务

为什么需要生命周期节点?如下是一些特殊场景中普通节点与生命周期节点的对比:

场景 普通节点 生命周期节点
传感器驱动 启动即开始发布,无法暂停 configure 连接硬件,activate 开始发布
导航系统 启动顺序不可控 按依赖顺序启动
安全关键系统 崩溃后无法安全恢复 deactivate → 修复 → activate
多机器人系统 无法统一管理启停 生命周期管理器统一控制
调试 只能 kill + restart deactivate 暂停,activate 恢复
硬件资源 占用后无法释放 cleanup 释放资源

二、状态机

2.1 状态转换

生命周期节点使用状态机管理节点的状态,一共有10个状态,包括4个主状态和6个过渡状态,如下:

主状态 ID 含义
Unconfigured 1 刚创建,未分配任何资源
Inactive 2 已配置(资源已分配),但未激活
Active 3 正常工作
Finalized 4 已关闭,不可恢复
过渡状态 ID 含义
Configuring 10 正在执行 on_configure
CleaningUp 11 正在执行 on_cleanup
ShuttingDown 12 正在执行 on_shutdown
Activating 13 正在执行 on_activate
Deactivating 14 正在执行 on_deactivate
ErrorProcessing 15 正在执行 on_error

状态机转换图如下:

在这里插入图片描述

关键规则

  • 不能跳状态(如 Unconfigured → Active)
  • 不能反向转换(如 Active → Unconfigured,必须先 deactivate)
  • 从任何主状态都可以 shutdown

2.2 状态切换回调

提供6个状态切换回调函数,当进行状态转换时,调用对应回调。

回调 状态转换 典型操作
on_configure Unconfigured→Inactive 分配资源、初始化硬件、读取配置
on_activate Inactive→Active 启动数据流、激活发布器、使能硬件
on_deactivate Active→Inactive 暂停数据流、停用发布器、禁用输出
on_cleanup Inactive→Unconfigured 释放资源、断开硬件、重置状态
on_shutdown 任何→Finalized 安全关闭、释放所有资源
on_error 错误恢复 复位硬件、尝试恢复

回调函数有3种返回值

返回值 含义 后续行为
SUCCESS 转换成功 进入目标状态
FAILURE 转换失败 回到之前的状态
ERROR 严重错误 进入 ErrorProcessing → 调用 on_error

2.3 错误恢复

当发生严重错误时,会进入 ErrorProcessing 状态,调用 on_error 进行错误恢复,恢复成功切为 Unconfigured 状态,恢复失败则切为 Finalized 状态,节点死亡。

错误恢复流程如下:
在这里插入图片描述

三、话题与服务

对于 LifecycleNode 的话题与服务,分为两类,用户自定义和系统定义。

3.1 自定义话题与服务

对于和节点外部交互的话题与服务,ROS2设计为当处于 Inactive 状态时不进行响应。

ROS2提供了 LifecyclePublisher 类,对应普通的 Publisher,他们的区别是当处于 Inactive 状态时,LifecyclePublisher 自动不发布消息,而 Publisher 仍然会发布消息。

但对于话题的订阅,ROS2没有提供 LifecycleSubscriber,所以要实现 Inactive 状态时不进行响应,需要手动过滤。

例如:

void callback(const Msg::SharedPtr msg) {
  if (get_current_state().id() != State::PRIMARY_STATE_ACTIVE) {
    return; // Inactive/Unconfigured 直接丢弃消息
  }
  // 正常处理
}

对于服务,LifecycleNode没有提供特殊的类,但当处于 Inactive 状态,并且节点作为服务端时,自动不响应功能服务请求,客户端会超时,所以当调用一个属于LifecycleNode的服务时,应该先查询该节点的状态,再根据结果处理。

当LifecycleNode作为客户端时,情况和订阅者类似,ROS2既没有提供特殊类也不会在框架层拦截,需要开发人员手动限制。

例如:

void send_service_request()
{
    if (get_current_state().id() == State::PRIMARY_STATE_INACTIVE) {
        RCLCPP_WARN(get_logger(), "节点休眠中,不发送服务请求");
        return;
    }

	// 正常处理
    auto req = std::make_shared<Request>();
    client_->async_send_request(req);
}

3.2 系统话题与服务

系统话题与服务不受节点状态限制,用于获取、发布节点状态相关信息,所有状态(包括 Inactive/Unconfigured)永远可用。

Lifecycle 管理服务(系统自动创建):

  • /{node_name}/__get_state
  • /{node_name}/__change_state
  • /{node_name}/__get_available_states
  • /{node_name}/__get_available_transitions

状态切换事件:

  • /<node_name>/__transition_event

下面详细介绍它们:

  • /{node_name}/__get_state

查询节点当前状态(主状态 + 正在进行的过渡状态)。

服务类型:lifecycle_msgs/srv/GetState

接口:

# Request
---
# Response
# The current state-machine state of the node.
State current_state
	uint8 id
	string label

其中,current_state 是当前状态, id是状态枚举,label是状态对应的字符串描述(如:unconfigured、inactive等)

状态枚举如下:

// 生命周期主状态(稳定常驻状态)
uint8 PRIMARY_STATE_UNKNOWN            = 0;  // 未知状态
uint8 PRIMARY_STATE_UNCONFIGURED       = 1;  // 未配置状态,资源未初始化
uint8 PRIMARY_STATE_INACTIVE           = 2;  // 休眠/就绪状态,已配置未运行
uint8 PRIMARY_STATE_ACTIVE             = 3;  // 激活运行状态,正常执行业务
uint8 PRIMARY_STATE_FINALIZED          = 4;  // 终止结束状态,节点即将退出

// 生命周期过渡状态(临时跳转中状态)
uint8 TRANSITION_STATE_CONFIGURING     = 10; // 正在执行配置中
uint8 TRANSITION_STATE_CLEANINGUP      = 11; // 正在执行资源清理中
uint8 TRANSITION_STATE_SHUTTINGDOWN    = 12; // 正在执行关闭流程中
uint8 TRANSITION_STATE_ACTIVATING      = 13; // 正在执行激活流程中
uint8 TRANSITION_STATE_DEACTIVATING    = 14; // 正在执行失活流程中
uint8 TRANSITION_STATE_ERRORPROCESSING = 15; // 正在执行错误恢复处理中
  • /{node_name}/__change_state

触发状态机跳转,外部控制节点生命周期

服务类型:lifecycle_msgs/srv/ChangeState

接口:

# Request
# This change state service will fail if the transition is not possible.
Transition transition
	uint8 id
	string label
---
# Response
# Indicates whether the service was able to initiate the state transition
bool success

其中,transition 是触发状态转换的动作,id是动作枚举,label是动作对应的字符串描述(如:configure、cleanup等)。

动作枚举如下:

// 生命周期状态跳转动作枚举值
uint8 TRANSITION_CREATE                  = 0;   // 创建节点,初始化资源
uint8 TRANSITION_CONFIGURE               = 1;   // 配置跳转:未配置态 → 休眠态
uint8 TRANSITION_CLEANUP                 = 2;   // 清理跳转:休眠态 → 未配置态
uint8 TRANSITION_ACTIVATE                = 3;   // 激活跳转:休眠态 → 工作态
uint8 TRANSITION_DEACTIVATE              = 4;   // 失活跳转:工作态 → 休眠态
uint8 TRANSITION_UNCONFIGURED_SHUTDOWN   = 5;   // 未配置状态下执行关闭
uint8 TRANSITION_INACTIVE_SHUTDOWN       = 6;   // 休眠状态下执行关闭
uint8 TRANSITION_ACTIVE_SHUTDOWN         = 7;   // 工作状态下执行关闭
uint8 TRANSITION_DESTROY                 = 8;   // 销毁节点,释放全部资源

// 配置流程回调结果事件
uint8 TRANSITION_ON_CONFIGURE_SUCCESS    = 10;  // 配置回调执行成功
uint8 TRANSITION_ON_CONFIGURE_FAILURE    = 11;  // 配置回调执行失败
uint8 TRANSITION_ON_CONFIGURE_ERROR      = 12;  // 配置回调执行异常报错

// 清理流程回调结果事件
uint8 TRANSITION_ON_CLEANUP_SUCCESS      = 20;  // 清理回调执行成功
uint8 TRANSITION_ON_CLEANUP_FAILURE      = 21;  // 清理回调执行失败
uint8 TRANSITION_ON_CLEANUP_ERROR        = 22;  // 清理回调执行异常报错

// 激活流程回调结果事件
uint8 TRANSITION_ON_ACTIVATE_SUCCESS     = 30;  // 激活回调执行成功
uint8 TRANSITION_ON_ACTIVATE_FAILURE     = 31;  // 激活回调执行失败
uint8 TRANSITION_ON_ACTIVATE_ERROR       = 32;  // 激活回调执行异常报错

// 失活流程回调结果事件
uint8 TRANSITION_ON_DEACTIVATE_SUCCESS   = 40;  // 失活回调执行成功
uint8 TRANSITION_ON_DEACTIVATE_FAILURE   = 41;  // 失活回调执行失败
uint8 TRANSITION_ON_DEACTIVATE_ERROR     = 42;  // 失活回调执行异常报错

// 关闭流程回调结果事件
uint8 TRANSITION_ON_SHUTDOWN_SUCCESS     = 50;  // 关闭回调执行成功
uint8 TRANSITION_ON_SHUTDOWN_FAILURE     = 51;  // 关闭回调执行失败
uint8 TRANSITION_ON_SHUTDOWN_ERROR       = 52;  // 关闭回调执行异常报错

// 通用错误恢复流程回调结果
uint8 TRANSITION_ON_ERROR_SUCCESS        = 60;  // 错误恢复流程执行成功
uint8 TRANSITION_ON_ERROR_FAILURE        = 61;  // 错误恢复流程执行失败
uint8 TRANSITION_ON_ERROR_ERROR          = 62;  // 错误恢复流程执行异常

// 生命周期通用回调统一返回状态
uint8 TRANSITION_CALLBACK_SUCCESS        = 97;  // 任意生命周期回调执行成功
uint8 TRANSITION_CALLBACK_FAILURE        = 98;  // 任意生命周期回调执行失败
uint8 TRANSITION_CALLBACK_ERROR          = 99;  // 任意生命周期回调执行异常
  • /{node_name}/__get_available_states

获取该节点所有可能存在的状态列表,永远不变,节点启动后固定。

服务类型:lifecycle_msgs/srv/GetAvailableStates

接口:

# Request
---
# Response
# Array of possible states that can be transitioned to.
State[] available_states
	uint8 id
	string label

其中,available_states是可能存在的状态列表。

  • /{node}/__get_available_transitions

获取从当前状态出发,所有合法的 transition列表(可执行动作、前状态、后状态)。

服务类型:lifecycle_msgs/srv/GetAvailableTransitions

接口:

# Request
---
# Response
# An array of the possible start_state-goal_state transitions
TransitionDescription[] available_transitions
	Transition transition
		uint8 id
		string label
	State start_state
		uint8 id
		string label
	State goal_state
		uint8 id
		string label

其中,transition 是触发状态转换的动作,start_stategoal_state 前状态和后状态。

  • /<node_name>/__transition_event

节点每次状态切换都会发一条,包含前状态、后状态、触发动作。

消息类型:lifecycle_msgs/msg/TransitionEvent

接口:

# The time point at which this event occurred.
uint64 timestamp

# The id and label of this transition event.
Transition transition
	uint8 id
	string label

# The starting state from which this event transitioned.
State start_state
	uint8 id
	string label

# The end state of this transition event.
State goal_state
	uint8 id
	string label

其中,start_stategoal_state 前状态和后状态。transition 是触发状态转换的动作。

四、命令行操作

ROS2提供了生命周期命令行

ros2 lifecycle get /my_node                        # 查询状态
ros2 lifecycle list /my_node                       # 查询可用转换
ros2 lifecycle set /my_node configure              # 触发状态转换
ros2 lifecycle set /my_node activate
ros2 lifecycle set /my_node deactivate
ros2 lifecycle set /my_node cleanup
ros2 lifecycle set /my_node shutdown
ros2 lifecycle nodes                               # 列出所有生命周期节点
Logo

立足具身智能前沿赛道,致力于搭建全球化、开源化、全栈式技术交流与实践共创平台。

更多推荐