Parameter示例
官方仓库:parameter
AimRT 中提供了一个简单的模块级 Key-Val 参数功能,模块可以通过调用CoreRe
f句柄的GetParameterHandle()
接口,获取aimrt::parameter::ParameterHandleRef
句柄,来使用此功能。
该句柄提供的核心接口如下:
namespace aimrt::parameter {
class ParameterHandleRef {
public:
std::string GetParameter(std::string_view key) const;
void SetParameter(std::string_view key, std::string_view val) const;
};
} // namespace aimrt::parameter
使用注意点如下:
-
std::string GetParameter(std::string_view key)
接口:用于获取参数。- 如果不存在 key,则返回空字符串。
- 该接口是线程安全的。
-
void SetParameter(std::string_view key, std::string_view val)
接口:用于设置/更新参数。- 如果不存在 key,则新建一个 key-val 参数对。
- 如果存在 key,则更新 key 所对应的 val 值为最新值。
- 该接口是线程安全的。
-
无论是设置参数还是获取参数,都是模块级别的,不同模块的参数互相独立、互不可见。
配置文件(configuration_parameter.yaml
)
依据官方示例项目结构自行编写YAML配置文件:
yaml
# 基础信息
base_info:
project_name: Parameter # 项目名称
build_mode_tags: ["EXAMPLE", "SIMULATION", "TEST_CAMERA"] # 构建模式标签
aimrt_import_options: # AimRT框架的构建选项
AIMRT_BUILD_TESTS: "OFF" # 是否构建测试代码
AIMRT_BUILD_EXAMPLES: "ON" # 是否构建示例代码
AIMRT_BUILD_DOCUMENT: "OFF" # 是否构建文档
AIMRT_BUILD_RUNTIME: "ON" # 是否构建运行时核心
AIMRT_BUILD_CLI_TOOLS: "OFF" # 是否构建命令行工具
AIMRT_BUILD_WITH_PROTOBUF: "ON" # 是否启用Protobuf支持
AIMRT_USE_LOCAL_PROTOC_COMPILER: "OFF" # 是否使用本地protoc编译器
AIMRT_BUILD_WITH_ROS2: "OFF" # 是否集成ROS2支持
AIMRT_BUILD_NET_PLUGIN: "OFF" # 是否构建网络插件
AIMRT_BUILD_ROS2_PLUGIN: "OFF" # 是否构建ROS2插件
# 模块
modules:
- name: parameter_module
# pkg
pkgs:
- name: parameter_pkg # 包名
modules:
- name: parameter_module
# 部署
deploy_modes:
- name: local_deploy # 部署模式名称
deploy_ins: # 部署实例
- name: local_ins_parameter # 实例名称
pkgs:
- name: parameter_pkg # 实例加载的包
module目录
parameter_module
一个最基本的 cpp parameter 示例,演示内容包括:
- 如何使用 AimRT 的 Parameter 功能;
- 此示例创建了一个
ParameterModule
,会在其Start
的阶段循通过 SetParameter 和 GetParameter 方法设置和获取参数的值,并通过日志打印出来;
模块定义
yaml
#pragma once
#include "aimrt_module_cpp_interface/module_base.h"
namespace Parameter::parameter_module {
// 参数模块类,继承自AIMRT模块基类
class ParameterModule : public aimrt::ModuleBase {
public:
ParameterModule() = default;
~ParameterModule() override = default;
// 返回模块信息
ModuleInfo Info() const override {
return ModuleInfo{.name = "ParameterModule"}; // 模块名称
}
// 模块初始化接口
bool Initialize(aimrt::CoreRef core) override;
// 模块启动接口
bool Start() override;
// 模块关闭接口
void Shutdown() override;
private:
// 获取日志记录器
auto GetLogger() { return core_.GetLogger(); }
// 设置参数的循环任务
void SetParameterLoop();
// 获取参数的循环任务
void GetParameterLoop();
private:
aimrt::CoreRef core_; // AIMRT核心引用
aimrt::executor::ExecutorRef work_executor_; // 执行器
aimrt::parameter::ParameterHandleRef parameter_handle_; // 参数操作句柄
std::atomic_bool run_flag_ = true; // 运行标志,控制循环是否继续
std::promise<void> set_loop_stop_sig_; // 设置参数循环停止信号
std::promise<void> get_loop_stop_sig_; // 获取参数循环停止信号
};
} // namespace Parameter::parameter_module
parameter_handle_
句柄可以用来设置和获取参数
模块实现
初始化阶段
cpp
bool ParameterModule::Initialize(aimrt::CoreRef core) {
// 保存AIMRT框架核心引用
core_ = core;
try {
// 获取执行器
work_executor_ = core_.GetExecutorManager().GetExecutor("work_thread_pool");
AIMRT_CHECK_ERROR_THROW(
work_executor_ && work_executor_.SupportTimerSchedule(),
"获取执行器'work_thread_pool'失败");
// 获取参数操作句柄
parameter_handle_ = core_.GetParameterHandle();
AIMRT_CHECK_ERROR_THROW(parameter_handle_, "获取参数句柄失败");
} catch (const std::exception& e) {
AIMRT_ERROR("初始化失败, {}", e.what());
return false;
}
AIMRT_INFO("初始化成功");
return true;
}
-
获取执行器
work_executor_
-
获取参数操作句柄
parameter_handle_
运行阶段
cpp
// 启动模块
bool ParameterModule::Start() {
try {
// 将SetParameterLoop方法绑定到当前对象,并提交到工作线程池执行
work_executor_.Execute(std::bind(&ParameterModule::SetParameterLoop, this));
// 将GetParameterLoop方法绑定到当前对象,并提交到工作线程池执行
work_executor_.Execute(std::bind(&ParameterModule::GetParameterLoop, this));
} catch (const std::exception& e) {
AIMRT_ERROR("启动失败, {}", e.what());
return false;
}
AIMRT_INFO("启动成功");
return true;
}
// 设置参数循环任务
void ParameterModule::SetParameterLoop() {
try {
AIMRT_INFO("开始设置参数循环");
uint32_t count = 0;
while (run_flag_) {
count++;
AIMRT_INFO("设置参数循环计数: {} -------------------------", count);
// 构造键值对
std::string key = "key-" + std::to_string(count);
std::string val = "val-" + std::to_string(count);
// 设置参数
parameter_handle_.SetParameter(key, val);
AIMRT_INFO("设置参数, 键: '{}', 值: '{}'", key, val);
// 休眠1秒
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
AIMRT_INFO("退出设置参数循环");
} catch (const std::exception& e) {
AIMRT_ERROR("设置参数循环异常退出, {}", e.what());
}
// 通知循环已停止
set_loop_stop_sig_.set_value();
}
// 获取参数循环任务
void ParameterModule::GetParameterLoop() {
try {
AIMRT_INFO("开始获取参数循环");
uint32_t count = 0;
while (run_flag_) {
count++;
AIMRT_INFO("获取参数循环计数: {} -------------------------", count);
// 构造键
std::string key = "key-" + std::to_string(count);
// 获取参数值
auto val = parameter_handle_.GetParameter(key);
AIMRT_INFO("获取参数, 键: '{}', 值: '{}'", key, val);
// 休眠1秒
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
AIMRT_INFO("退出获取参数循环");
} catch (const std::exception& e) {
AIMRT_ERROR("获取参数循环异常退出, {}", e.what());
}
// 通知循环已停止
get_loop_stop_sig_.set_value();
}
- 两个循环独立运行但通过共享的
parameter_handle_
交互
**设置参数循环工作流程:**SetParameterLoop()
- 进入无限循环,直到
run_flag_
变为false - 每次循环生成递增的键值对(key-1/val-1, key-2/val-2...)
- 通过参数句柄存储这些参数
- 每次操作后休眠1秒
- 退出时发送停止信号
**获取参数循环工作流程:**GetParameterLoop()
- 进入无限循环,直到
run_flag_
变为false - 每次循环尝试获取对应键的参数值
- 记录获取到的参数值
- 每次操作后休眠1秒
- 退出时发送停止信号
停止阶段
cpp
void ParameterModule::Shutdown() {
try {
run_flag_ = false; // 设置停止标志
set_loop_stop_sig_.get_future().wait(); // 等待设置参数循环停止
get_loop_stop_sig_.get_future().wait(); // 等待获取参数循环停止
} catch (const std::exception& e) {
AIMRT_ERROR("关闭失败, {}", e.what());
return;
}
AIMRT_INFO("关闭成功");
}
对应的启动配置文件
cpp
aimrt:
log:
core_lvl: INFO # Trace/Debug/Info/Warn/Error/Fatal/Off
backends:
- type: console
executor:
executors:
- name: work_thread_pool
type: asio_thread
options:
thread_num: 2
module:
pkgs:
- path: ./libparameter_pkg.so
enable_modules: [ParameterModule]
modules:
- name: ParameterModule
log_lvl: INFO