【ROS2】节点生命周期管理

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_state 和 goal_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_state 和 goal_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 # 列出所有生命周期节点
更多推荐



所有评论(0)