AimRT 从零到一:官方示例精讲 —— 五、Parameter示例.md
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配置文件:
# 基础信息
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 方法设置和获取参数的值,并通过日志打印出来;
模块定义
#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_
句柄可以用来设置和获取参数
模块实现
初始化阶段
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_
运行阶段
// 启动模块
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秒
- 退出时发送停止信号
停止阶段
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("关闭成功");
}
对应的启动配置文件
aimrt:log:core_lvl: INFO # Trace/Debug/Info/Warn/Error/Fatal/Offbackends:- type: consoleexecutor:executors:- name: work_thread_pooltype: asio_threadoptions:thread_num: 2module:pkgs:- path: ./libparameter_pkg.soenable_modules: [ParameterModule]modules:- name: ParameterModulelog_lvl: INFO