ROS2中的LifecycleNode生命周期节点

本文参考:ros2 node_lifecycle
ros2中加入了一种区别于普通的node节点的管理节点LifecycleNode,这种节点有点像是状态机,会在几种不同的状态中切换。

LifecycleNode 节点的状态主要分为基本状态(Primary States)和切换状态(Transition States)。主要状态是任何节点都可以做相应的任务的稳态,切换状态切换过程中短暂的临时状态。这些中间状态的结果用于指示两个主要状态之间的转换是否成功。

主要状态分为4种:
unconfigured
inactive
active
shutdown

切换状态分为6种:
configuring
activating
deactivating
cleaningup
shuttingdown
ErrorProcessing

关于状态的切换可以看这张图:
在这里插入图片描述

Unconfigured

节点实例化之后就会立马进入这个状态,节点出错之后也会返回到这个状态。

有效的状态转换:

  • 可以通过configure切换到Inactive状态
  • 可以通过shutdown切换到Finalized状态

Inactive

这个状态代表节点目前没有进行任何处理。这个状态的主要目的是让节点进行(重新)配置(比如改变配置参数、增加或删除topic的发布和订阅等)而不在运行时改变它的行为。

在这个状态时,节点不会接受任何运行时间来读取topic、进行数据处理或是回应service的请求等。Inactive状态下不会对收到的任何来自管理话题的数据进行读取或者是处理。数据保留将会取决于为主题配置的QoS策略。同时service请求也不会被回应(对请求者来说,会立马fail)。

有效的状态转换:

  • 通过shutdown切换到Finalized
  • 通过cleanup切换到Unconfigured
  • 通过acticate切换到Active

Active

这个lifecycle节点的主要状态。在这个状态时,节点会进行一些处理、回应service请求、读取和处理数据、产生输出等。

如果这个状态下节点或是系统发生了不能处理的错误,那么节点会切换到ErrorProcessing状态。

有效的状态切换:

  • 通过deactivate切换到Inactive
  • 通过shutdown切换到Finalized

Finalized

该状态是节点被销毁前会立马就结束的状态。这个状态只会通往销毁。

有效的状态切换:

  • 通过destroy被消除分配(deallocated)

Configuring

节点的conConfigure回调函数会被调用,来允许节点加载配置以及进行必要的设置。

节点的配置通常都会涉及到一些在节点的生命周期中必须被执行一次的任务,比如说申请内存、配置不会改变的topic的发布/订阅等等。

节点也会用此来设置一些它的整个生命周期中必须保留的资源(不论是active状态还是inactive状态),比如说topic的发布/订阅器,持续需要的内存空间以及初始的配置参数。

有效的状态切换:

  • 如果conConfigure回调函数成功被调用,那么节点会切换到Inactive状态。
  • 如果回调函数出现失败代码(需要具体的代码),那么节点就会返回到Unconfigured状态。
  • 如果回调函数引发或return了别的值,则节点将转换为ErrorProcessing状态。

CleaningUp

节点的onCleanup回调函数会被调用。函数中应当清除所有状态并返回到与初次创建时一样的状态。

有效的状态切换;

  • 如果onCleanup回调函数成功执行,就会被切换到Unconfigured状态。
  • 如果执行出错就会切换到ErrorProcessing

Activating

节点的onActivate回调函数会被调用。函数中应当做好开始执行前的最后准备,包括获得只在节点active期间会用到的资源,比如对硬件的访问。理想情况下,不应该在这里执行需要大量时间的准备工作(比如冗长的硬件初始化,我猜测可能是单目SLAM的初始化这种)。

有效的状态切换;

  • 如果onActivate回调函数成功执行,就会被切换到Active状态。
  • 如果执行出错就会切换到ErrorProcessing

Deactivating

节点的onDeactivate回调函数会被调用。函数中应当执行清除操作以便开始执行,并做onActivate中相反的操作。

有效的状态切换;

  • 如果onDeactivate回调函数成功执行,就会被切换到Active状态。
  • 如果执行出错就会切换到ErrorProcessing

ShuttingDown

节点的onShutdown回调函数会被调用。函数中应当执行销毁前的必要的清除。该状态应当可以从除了Finalized的所有状态进入,函数中应当将节点返回到初始状态。

有效的状态切换;

  • 如果onShutdown回调函数成功执行,就会被切换到Finalized状态。
  • 如果执行出错就会切换到ErrorProcessing

ErrorProcessing

该状态是清除所有错误的地方。可以从所有状态进入该状态。如果错误被成功处理,那么会返回到Unconfigured状态,如果没有执行所有的清理,那它必须失败然后切换到Finalized状态并等待销毁。

ErrorProcessing切换可以是回调函数(或是回调函数中的函数)中生成的错误返回值以及未捕获的异常。

有效的状态切换;

  • 如果onError回调函数成功执行,就会被切换到Unconfigured状态。期望的是onError会清除先前状态的所有状态。比如说如果是从Active进入的,那么必须提供onDeactivateonCleanup的来返回成功。
  • 如果执行出错就会切换到Finalized

实例

可以看下面的实例

#include <iostream>
#include <rclcpp/rclcpp.hpp>
#include <rclcpp_lifecycle/lifecycle_node.hpp>

#include "lifecycle_msgs/msg/transition.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

class my_lifecyclenode : public rclcpp_lifecycle::LifecycleNode {
   
public:
    // 构造函数
    // lifecyclenode 的构造函数都有相同的参数
    explicit my_lifecyclenode(const std::string& node_name, bool intra_process_comms = false)
        : rclcpp_lifecycle::LifecycleNode(node_name,
                                          rclcpp::NodeOptions().use_intra_process_comms(intra_process_comms)) {
   }
    void func() {
    std::cout << "in func" << std::endl; }

    // on_configure回调函数会在lifecyclenode进入configuring状态时被调用
    // 根据返回值的不同,节点会进入inactive或者停留在unconfigured
    // RANSITION_CALLBACK_SUCCESS transitions to "inactive"
    // RANSITION_CALLBACK_FAILURE transitions to "unconfigured"
    // TRANSITION_CALLBACK_ERROR or any uncaught exceptions to "errorprocessing"
    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_configure(
        const rclcpp_lifecycle::State&) {
   
        RCLCPP_INFO(get_logger(), "on_configure() is called.");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    // 没啥好说的,参考on_configure回调函数和前文
    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_activate(
        const rclcpp_lifecycle::State&) {
   
        RCUTILS_LOG_INFO_NAMED(get_name(), "on_activate() is called.");
        std::this_thread::sleep_for(2s);
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
    }

    //
    rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn on_deactivate(
        const rclcpp_lifecycle::State&) {
   
        RCUTILS_LOG_INFO_NAMED(get_name(), "on_deactivate() is called.");
        return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值