5-监视参数更改(c++)

背景

    通常,节点需要响应对其自身参数或其他节点参数的更改。ParameterEventHandler类可以很容易地监听参数更改,以便您的代码可以响应它们。本节介绍如何使用c++版本的ParameterEventHandler类来监视节点自身参数的更改以及对另一个节点参数的更改。

基础准备

    在开始本教程之前,您应该首先熟悉以下教程:

    理解参数6-理解参数-CSDN博客
    在类中使用参数(c++)8-在类中使用参数-CSDN博客

任务

    在本教程中,您将创建一个包含一些示例代码的新包,编写一些使用ParameterEventHandler类的c++代码,并测试生成的代码。

1. 创建一个包

    首先,打开一个新的终端并source ROS 2,这样ros2命令就可以工作了。
    创建一个名为ros2_ws的新工作目录。
    回想一下,包应该在src目录中创建,而不是在工作区的根目录中。因此,进入到ros2_ws/src,然后在那里创建一个新包:

ros2 pkg create --build-type ament_cmake cpp_parameter_event_handler --dependencies rclcpp

    您的终端将返回一条消息,验证包cpp_parameter_event_handler及其所有必要的文件和文件夹的创建。
    --dependencies参数会自动将必要的依赖行添加到package.xml和CMakeLists.txt中。

1.1更新package.xml

    因为您在包创建过程中使用了--dependencies选项,所以您不必手动向package.xml或CMakeLists.txt添加依赖项。但是,与往常一样,请确保在package.xml中添加描述、维护人员电子邮件和名称以及许可信息。

<description>C++ parameter events client tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>

2 编写c++节点

    在ros2_ws/src/cpp_parameter_event_handler/src目录中,创建一个名为parameter_event_handler.cpp的新文件,并在其中粘贴以下代码:

#include <memory>

#include "rclcpp/rclcpp.hpp"

class SampleNodeWithParameters : public rclcpp::Node
{
public:
  SampleNodeWithParameters()
  : Node("node_with_parameters")
  {
    this->declare_parameter("an_int_param", 0);

    // Create a parameter subscriber that can be used to monitor parameter changes
    // (for this node's parameters as well as other nodes' parameters)
    param_subscriber_ = std::make_shared<rclcpp::ParameterEventHandler>(this);

    // Set a callback for this node's integer parameter, "an_int_param"
    auto cb = [this](const rclcpp::Parameter & p) {
        RCLCPP_INFO(
          this->get_logger(), "cb: Received an update to parameter \"%s\" of type %s: \"%ld\"",
          p.get_name().c_str(),
          p.get_type_name().c_str(),
          p.as_int());
      };
    cb_handle_ = param_subscriber_->add_parameter_callback("an_int_param", cb);
  }

private:
  std::shared_ptr<rclcpp::ParameterEventHandler> param_subscriber_;
  std::shared_ptr<rclcpp::ParameterCallbackHandle> cb_handle_;
};

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<SampleNodeWithParameters>());
  rclcpp::shutdown();

  return 0;
}

2.1代码释义

    包含第一个语句#include <memory>,以便代码可以利用std::make_shared模板。接下来,#include“rclcpp/rclcpp.hpp”允许代码引用rclcpp接口提供的各种功能,包括ParameterEventHandler类。
    在类声明之后,代码定义了一个类SampleNodeWithParameters。该类的构造函数声明了一个整数形参an_int_param,默认值为0。接下来,代码创建一个ParameterEventHandler,它将用于监视参数的更改。最后,代码创建一个lambda函数,并将其设置为在an_int_param更新时调用的回调函数。

    注意:保存add_parameter_callback返回的句柄是非常重要的;否则,回调将无法正确注册。

SampleNodeWithParameters()
: Node("node_with_parameters")
{
  this->declare_parameter("an_int_param", 0);

  // Create a parameter subscriber that can be used to monitor parameter changes
  // (for this node's parameters as well as other nodes' parameters)
  param_subscriber_ = std::make_shared<rclcpp::ParameterEventHandler>(this);

  // Set a callback for this node's integer parameter, "an_int_param"
  auto cb = [this](const rclcpp::Parameter & p) {
      RCLCPP_INFO(
        this->get_logger(), "cb: Received an update to parameter \"%s\" of type %s: \"%ld\"",
        p.get_name().c_str(),
        p.get_type_name().c_str(),
        p.as_int());
    };
  cb_handle_ = param_subscriber_->add_parameter_callback("an_int_param", cb);
}

    SampleNodeWithParameters之后是一个典型的main函数,它初始化ROS,旋转示例节点以便它可以发送和接收消息,然后在用户在控制台中输入^C后关闭。

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<SampleNodeWithParameters>());
  rclcpp::shutdown();

  return 0;
}

2.2添加可执行文件

    要构建此代码,首先打开CMakeLists.txt文件,并在依赖项find_package(rclcpp REQUIRED)下面添加以下代码行

add_executable(parameter_event_handler src/parameter_event_handler.cpp)
ament_target_dependencies(parameter_event_handler rclcpp)

install(TARGETS
  parameter_event_handler
  DESTINATION lib/${PROJECT_NAME}
)

3构建并运行

    在构建之前,在工作区的根目录(ros2_ws)中运行rosdeep以检查缺失的依赖项是很好的做法:

rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y

    导航到工作区的根目录ros2_ws,并构建新包:

colcon build --packages-select cpp_parameter_event_handler

    打开一个新终端,进入到ros2_ws,并source:

. install/setup.bash

    现在运行节点:

ros2 run cpp_parameter_event_handler parameter_event_handler

    该节点现在处于活动状态,有一个参数,并且在更新该参数时将打印一条消息。要对此进行测试,请打开另一个终端并像前面一样source(./install/setup.bash),并执行如下命令:

ros2 param set node_with_parameters an_int_param 43

    运行该节点的终端将显示类似如下的消息:

[INFO] [1606950498.422461764] [node_with_parameters]: cb: Received an update to parameter "an_int_param" of type integer: "43"

    我们之前在节点中设置的回调已被调用,并显示了更新后的新值。现在可以在终端中使用^C终止正在运行的parameter_event_handler示例。

3.1监控其他节点参数的变化

    您还可以使用ParameterEventHandler监视另一个节点参数的参数更改。更新SampleNodeWithParameters类,以监视另一个节点中参数的更改。我们将使用parameter_blackboard demo来管理双参数,并且监视该参数的更新。
    首先更新构造函数,在现有代码之后添加以下代码:

// Now, add a callback to monitor any changes to the remote node's parameter. In this
// case, we supply the remote node name.
auto cb2 = [this](const rclcpp::Parameter & p) {
    RCLCPP_INFO(
      this->get_logger(), "cb2: Received an update to parameter \"%s\" of type: %s: \"%.02lf\"",
      p.get_name().c_str(),
      p.get_type_name().c_str(),
      p.as_double());
  };
auto remote_node_name = std::string("parameter_blackboard");
auto remote_param_name = std::string("a_double_param");
cb_handle2_ = param_subscriber_->add_parameter_callback(remote_param_name, cb2, remote_node_name);

    然后为额外的回调函数添加另一个成员变量cb_handle2:

private:
  std::shared_ptr<rclcpp::ParameterEventHandler> param_subscriber_;
  std::shared_ptr<rclcpp::ParameterCallbackHandle> cb_handle_;
  std::shared_ptr<rclcpp::ParameterCallbackHandle> cb_handle2_;  // Add this
};

    在终端中,进入到工作区的根目录ros2_ws,并像前面一样编译更新后的包:

colcon build --packages-select cpp_parameter_event_handler

    然后source一下:

source install/setup.bash

    现在,为了测试参数的监控,首先运行新编译的parameter_event_handler代码:

ros2 run cpp_parameter_event_handler parameter_event_handler

    接下来,从另一个终端(已初始化ROS)运行parameter_blackboard demo,如下所示:

ros2 run demo_nodes_cpp parameter_blackboard

    最后,在第三个终端(已初始化ROS),在parameter_blackboard节点上设置一个参数:

ros2 param set parameter_blackboard a_double_param 3.45

    执行此命令后,您应该在parameter_event_handler窗口中看到输出,表明在参数更新时调用了回调函数:

[INFO] [1606952588.237531933] [node_with_parameters]: cb2: Received an update to parameter "a_double_param" of type: double: "3.45"

总结

    创建了一个带有参数的节点,并使用ParameterEventHandler类设置了一个回调,以监视对该参数的更改。还使用相同的类来监视对远程节点的更改。ParameterEventHandler是监视参数变化的一种方便的方法,这样就可以对更新后的值做出响应。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值