前言
通常,一个节点需要对其自身参数或另一个节点的参数的更改做出响应。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(TARGETSparameter_event_handlerDESTINATION 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++(中文版)》,如有需要可以私信或评论区留下邮箱,免费发放)
本篇完。