ROS 2边学边练(26)-- 监测参数变化(C++)

前言

        通常,一个节点需要对其自身参数或另一个节点的参数的更改做出响应。ParameterEventHandler类使监听参数更改变得容易,这样代码就可以对它们做出响应。

动动手

创建一个包

        进入工作空间根路径的src下(ros2_ws/src),创建名为ParameterEventHandler的功能包:

$ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_parameter_event_handler --dependencies rclcpp

        如有需要可再更新下package.xml的一些信息(最好还是养成一种更新的习惯):

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

码个码

        在刚创建的功能包ParameterEventHandler的src路径下创建parameter_event_handler.cpp,将下面C++代码复制进去:

#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;
}
代码解释

        头文件#include<memory>,以使代码可以使用std::make_shared模板。接下来,#include“rclcpp/crccpp.hpp”,以允许代码引用rclcpp接口提供的各种功能,包括ParameterEventHandler类。

        在类声明之后,代码定义了一个类SampleNodeWithParameters。该类的构造函数声明一个整数参数an_int_param,默认值为0。接下来,该代码创建一个ParameterEventHandler,用于监视参数的更改。最后,该代码创建一个lambda函数,并将其设置为每当更新_int_param时要调用的回调。

        在类声明之后,代码定义了一个类SampleNodeWithParameters。该类的构造函数声明一个整数参数an_int_param,默认值为0。接下来,该代码创建一个ParameterEventHandler,用于监视参数的更改。最后,该代码创建一个lambda函数,并将其设置为每当更新_int_param时要调用的回调。

修改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}
)

构建运行

        首先依然是最好检查下依赖,进入工作空间根路径下:

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

        构建一下:

$colcon build --packages-select cpp_parameter_event_handler

        在新的终端source下环境:

$source install/setup.bash

        开始运行:

$ros2 run cpp_parameter_event_handler parameter_event_handler

        我们打开另外一个终端,source环境,并运行下面修改参数的命令,看看parameter_event_handler终端会打印出什么内容:

$ros2 param set node_with_parameters an_int_param 43

 

 

监视另一个节点参数更改事件

        我们来修改下SampleNodeWithParameters类的构造函数,添加一个回调函数,实现对另外一个节点参数改变事件的监视。我们将使用parameter_blackboard例子应用程序来托管一个双参数,监视该双参数的更新。按下面内容对构造函数进行修改:

// 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);
private:
  std::shared_ptr<rclcpp::ParameterEventHandler> param_subscriber_;
  std::shared_ptr<rclcpp::ParameterCallbackHandle> cb_handle_;
  std::shared_ptr<rclcpp::ParameterCallbackHandle> cb_handle2_;  // Add this
};

        再次回到工作空间根路径重新构建包:

$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

        打开另外一个终端(记得source环境),运行parameter_blackboard例子:

$ros2 run demo_nodes_cpp parameter_blackboard

 

        我们再打开另外一个终端,设置下parameter_blackboard例子中的参数:

$ros2 param set parameter_blackboard a_double_param 3.45

        我们再看看返回:

(关于C++的一些新特性,ROS(2)中用的挺多的,如果对此不熟悉,比如我本人,挺影响ROS的后续学习,不过可以找些书籍充个电,工欲善其事必先利其器嘛,我这有两本电子书《深入应用C++11:代码优化与工程级应用》、《Effective Modern C++(中文版)》,如有需要可以私信或评论区留下邮箱,免费发放)

本篇完。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-20 22:58:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-20 22:58:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-20 22:58:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-20 22:58:03       18 阅读

热门阅读

  1. Tomcat简介

    2024-04-20 22:58:03       15 阅读
  2. 【数据库】

    2024-04-20 22:58:03       18 阅读
  3. Redis-批处理

    2024-04-20 22:58:03       15 阅读
  4. Rust编程入门教程

    2024-04-20 22:58:03       20 阅读
  5. 学习笔记2024/4/17

    2024-04-20 22:58:03       16 阅读
  6. Android笔记: mkdirs失败,不生效怎么办

    2024-04-20 22:58:03       37 阅读
  7. 计算机网络——应用层(4)DHCP和套接字编程

    2024-04-20 22:58:03       13 阅读
  8. Led驱动程序

    2024-04-20 22:58:03       12 阅读
  9. Springboot整合物联网IOT的MQTT协议

    2024-04-20 22:58:03       13 阅读