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配置文件:

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()

  1. 进入无限循环,直到run_flag_变为false
  2. 每次循环生成递增的键值对(key-1/val-1, key-2/val-2...)
  3. 通过参数句柄存储这些参数
  4. 每次操作后休眠1秒
  5. 退出时发送停止信号

**获取参数循环工作流程:**​GetParameterLoop()

  1. 进入无限循环,直到run_flag_变为false
  2. 每次循环尝试获取对应键的参数值
  3. 记录获取到的参数值
  4. 每次操作后休眠1秒
  5. 退出时发送停止信号
停止阶段
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
相关推荐
cosX+sinY1 小时前
10 基于Gazebo和Rviz实现导航仿真,包括SLAM建图,地图服务,机器人定位,路径规划
机器人
wuqingshun3141592 小时前
经典算法 最长单调递增子序列
java·c++·算法·蓝桥杯·机器人
nuannuan2311a6 小时前
2P4M-ASEMI机器人功率器件专用2P4M
机器人
维度攻城狮19 小时前
通过DeepSeek大语言模型控制panda机械臂,听懂人话,拟人性回答。智能机械臂助手又进一步啦
大语言模型·控制·ros2·moveit·deepseek·rviz2
layneyao19 小时前
AI在医疗领域的10大应用:从疾病预测到手术机器人
人工智能·机器人
遨博学院1 天前
机器人结构认知与安装
机器人
小柒的博客1 天前
联合体union的特殊之处
c语言·机器人
Robot2511 天前
「地平线」创始人余凯:自动驾驶尚未成熟,人形机器人更无从谈起
人工智能·科技·机器学习·机器人·自动驾驶
跳跳糖炒酸奶1 天前
第二章、Isaaclab强化学习包装器(1)
人工智能·python·算法·ubuntu·机器人