监测参数变化 (C++)
目标 学习使用 ParameterEventHandler 类监控和响应参数变化。
辅导水平: 中级
时间 20 分钟
背景介绍
通常情况下,节点需要对自身参数或其他节点参数的变化做出响应。ParameterEventHandler 类可轻松监听参数变化,以便您的代码能对其做出响应。本教程将向您展示如何使用 C++ 版本的 ParameterEventHandler 类来监听节点自身参数的变化以及其他节点参数的变化。
先决条件
在开始本教程之前,您应首先完成以下教程:
任务
在本教程中,您将创建一个包含一些示例代码的新包,编写一些使用 ParameterEventHandler 类的 C++ 代码,并测试生成的代码。
1 创建软件包
首先,打开一个新终端,然后 为您的 ROS 2 安装提供源代码 以便 玫瑰2
命令即可运行。
跟进 本说明 创建一个名为 ros2_ws
.
回顾一下,软件包应在 来源
目录,而不是工作区的根目录。因此,导航到 ros2_ws/src
然后在那里创建一个新软件包:
ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_parameter_event_handler --ependencies rclcpp
您的终端将返回一条信息,验证是否创建了软件包 cpp_parameter_event_handler
及其所有必要的文件和文件夹。
"(《世界人权宣言》) --依赖
参数会自动在 package.xml
和 CMakeLists.txt
.
1.1 更新 package.xml
因为您使用了 --依赖
选项,就不必在创建软件包时手动将依赖关系添加到 package.xml
或 CMakeLists.txt
.不过,请务必一如既往地将说明、维护者电子邮件和姓名以及许可证信息添加到 package.xml
.
<描述>;C++ 规范 活动 客户 教程</description>;
维护者 电子邮件="[email protected]";>;您的 名称维护人员</maintainer>;
许可证Apache-2.0</license>;
2 编写 C++ 节点
内部 ros2_ws/src/cpp_parameter_event_handler/src
目录下,新建一个名为 parameter_event_handler.cpp
并粘贴以下代码:
#include <内存>;
#include "rclcpp/rclcpp.hpp";
类 带参数的样本节点 : 公 rclcpp::节点
{
公:
带参数的样本节点()
: 节点("node_with_parameters";)
{
此->;declare_parameter("an_int_param";, 0);
// 创建一个参数订阅者,用于监控参数变化
// (用于此节点参数和其他节点参数)
参数订阅者 = 标准::共享<;rclcpp::参数事件处理程序>;(此);
// 为该节点的整数参数 "an_int_param" 设置回调;
汽车 cb = [此](缢 rclcpp::参数 及样品; p) {
RCLCPP_INFO(
此->;get_logger(), "cb:收到参数更新 \";%s\"; 的 %s 类型: \";%ld\";";,
p.获取名称().c_str(),
p.get_type_name().c_str(),
p.as_int());
};
cb_handle_ = 参数订阅者->;添加参数回调("an_int_param";, cb);
}
私人:
标准::共享_ptr<;rclcpp::参数事件处理程序>; 参数订阅者;
标准::共享_ptr<;rclcpp::参数回调柄>; cb_handle_;
};
int 主要(int 参数, 烧焦 ** 参数)
{
rclcpp::启动(参数, 参数);
rclcpp::后旋(标准::共享<;带参数的样本节点>;());
rclcpp::关闭();
返回 0;
}
2.1 检查代码
第一项声明、 #include <内存>;
包含在内,以便代码可以使用 std::make_shared 模板。下一个 #include "rclcpp/rclcpp.hpp";
允许代码引用 rclcpp 接口提供的各种功能,包括 ParameterEventHandler 类。
在类声明之后,代码定义了一个类、 带参数的样本节点
.类的构造函数声明了一个整数参数 参数
的默认值为 0。 接下来,代码会创建一个 参数事件处理程序
用于监控参数的变化。最后,代码创建了一个 lambda 函数,并将其设置为每当 参数
已更新。
备注
保存由 添加参数回调
否则,将无法正确注册回调。
带参数的样本节点()
: 节点("node_with_parameters";)
{
此->;declare_parameter("an_int_param";, 0);
// 创建一个参数订阅者,用于监控参数变化
// (用于此节点参数和其他节点参数)
参数订阅者 = 标准::共享<;rclcpp::参数事件处理程序>;(此);
// 为该节点的整数参数 "an_int_param" 设置回调;
汽车 cb = [此](缢 rclcpp::参数 及样品; p) {
RCLCPP_INFO(
此->;get_logger(), "cb:收到参数更新 \";%s\"; 的 %s 类型: \";%ld\";";,
p.获取名称().c_str(),
p.get_type_name().c_str(),
p.as_int());
};
cb_handle_ = 参数订阅者->;添加参数回调("an_int_param";, cb);
}
继 带参数的样本节点
是一个典型的 主要
函数初始化 ROS,启动样本节点使其可以发送和接收信息,然后在用户在控制台输入 ^C 后关闭。
int 主要(int 参数, 烧焦 ** 参数)
{
rclcpp::启动(参数, 参数);
rclcpp::后旋(标准::共享<;带参数的样本节点>;());
rclcpp::关闭();
返回 0;
}
2.2 添加可执行文件
要编译这段代码,首先打开 CMakeLists.txt
文件,并在依赖关系下面添加以下代码行 find_package(rclcpp 必填)
add_executable(parameter_event_handler src/parameter_event_handler.cpp)
ament_target_dependencies(parameter_event_handler rclcpp)
install(TARGETS
参数事件处理程序
目的地 lib/${PROJECT_NAME}
)
3 构建和运行
运行 rosdep
在工作区的根目录 (ros2_ws
) 在构建前检查是否缺少依赖项:
rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y
rosdep 只能在 Linux 上运行,因此可以跳到下一步。
rosdep 只能在 Linux 上运行,因此可以跳到下一步。
返回工作区的根目录、 ros2_ws
然后创建新软件包:
colcon build --packages-select cpp_parameter_event_handler
打开一个新终端,导航至 ros2_ws
并获取设置文件:
install/setup.bash
install/setup.bash
调用 install/setup.bat
现在运行节点:
ros2 运行 cpp_parameter_event_handler 参数事件处理程序
节点现在处于活动状态,只有一个参数,每当该参数更新时就会打印一条信息。要测试这一点,请打开另一个终端,像以前一样输入 ROS 设置文件(.install/setup.bash),然后执行以下命令:
ros2 param set node_with_parameters an_int_param 43
运行节点的终端将显示类似下面的信息:
[INFO] [1606950498.422461764] [node_with_parameters]: cb:收到对整数类型参数 "an_int_param" 的更新:"43";
我们之前在节点中设置的回调已被调用,并显示了新的更新值。现在,您可以在终端中使用 ^C 终止正在运行的 parameter_event_handler 示例。
3.1 监控另一节点参数的变化
您还可以使用 ParameterEventHandler 监控另一个节点的参数变化。让我们更新 SampleNodeWithParameters 类,以便同时监控另一个节点中参数的变化。我们将使用 parameter_blackboard 演示应用程序来托管一个双参数,并对其更新进行监控。
首先更新构造函数,在现有代码后添加以下代码:
// 现在,添加一个回调以监控远程节点参数的任何变化。在此
// 情况下,我们提供远程节点名称。
汽车 cb2 = [此](缢 rclcpp::参数 及样品; p) {
RCLCPP_INFO(
此->;get_logger(), "cb2:收到参数更新 \";%s\"; 的类型:%s: \";%.02lf\";";,
p.获取名称().c_str(),
p.get_type_name().c_str(),
p.as_double());
};
汽车 远程节点名称 = 标准::字符串("parameter_blackboard";);
汽车 远程参数名 = 标准::字符串("a_double_param";);
cb_handle2_ = 参数订阅者->;添加参数回调(远程参数名, cb2, 远程节点名称);
然后再添加一个成员变量、 cb_handle2
的附加回调句柄:
私人:
标准::共享_ptr<;rclcpp::参数事件处理程序>; 参数订阅者;
标准::共享_ptr<;rclcpp::参数回调柄>; cb_handle_;
标准::共享_ptr<;rclcpp::参数回调柄>; cb_handle2_; // 添加以下内容
};
在终端中,返回工作区的根目录、 ros2_ws
然后像以前一样编译更新的软件包:
colcon build --packages-select cpp_parameter_event_handler
然后获取设置文件:
install/setup.bash
install/setup.bash
调用 install/setup.bat
现在,要测试对远程参数的监控,首先运行新建的 parameter_event_handler 代码:
ros2 运行 cpp_parameter_event_handler 参数事件处理程序
接下来,从另一个模板(ROS 已初始化)运行 parameter_blackboard 演示程序,如下所示:
ros2 run demo_nodes_cpp parameter_blackboard
最后,让我们从第三个终端(ROS 已初始化)在 parameter_blackboard 节点上设置一个参数:
ros2 参数设置参数_黑板 a_double_param 3.45
执行该命令后,您应该会在 parameter_event_handler 窗口中看到输出,表明参数更新时调用了回调函数:
[INFO] [1606952588.237531933] [node_with_parameters]: cb2: 收到对参数"a_double_param"的更新,参数类型:double: "3.45";
摘要
您创建了一个带有参数的节点,并使用 ParameterEventHandler 类设置了一个回调,以监控该参数的变化。您还使用了相同的类来监控远程节点的变化。ParameterEventHandler 是一种监控参数变化的便捷方法,这样您就可以对更新值作出响应。