当前位置: 首页 > news >正文

AimRT 从零到一:官方示例精讲 —— 一、工具链与基本概念

工具链与基本概念

aimrt_cli​ 工具

用法示例

aimrt_cli gen -p [config.yaml] -o [output_folder]
# 示例:
aimrt_cli gen -p helloworld.yaml -o ./helloworld/
  • 配置驱动:通过 YAML 定义项目结构/编译选项/部署模式
  • 工程生成:自动创建 CMake 工程、模块模板、配置文件
  • 安全机制:输出目录需为空,避免文件覆盖冲突

配置文档示例:

直接看示例可能无法理解,快进到后续示例中我们自行编写的配置文件,对照学习

# 基础信息配置(必填项)
base_info:# 项目名称,将作为代码的命名空间project_name: test_prj# 构建模式标签,可自定义编译选项# 格式为 {PROJECT_NAME}_{OPTION_NAME},若无需要可置为空列表 []build_mode_tags: ["EXAMPLE", "SIMULATION", "TEST_CAMERA"]# AIMRT引入选项配置(必须使用单引号包裹值)aimrt_import_options:# 是否构建运行时AIMRT_BUILD_RUNTIME: 'ON'# 是否使用fmt库AIMRT_USE_FMT_LIB: 'ON'# 是否使用protobuf构建AIMRT_BUILD_WITH_PROTOBUF: 'ON'# 是否使用本地protoc编译器AIMRT_USE_LOCAL_PROTOC_COMPILER: 'OFF'# 是否使用protoc python插件AIMRT_USE_PROTOC_PYTHON_PLUGIN: 'OFF'# 是否与ROS2一起构建AIMRT_BUILD_WITH_ROS2: 'ON'# 依赖的标准模块配置(可选)
depends_std_modules:- name: xxx  # 依赖库名称(应与实际库名一致)git_repository: https://github.com/xxx/xxx.git  # 库地址git_tag: v0.1.5  # 版本标签import_options:  # 导入选项(暂不支持)XXX: 'ON'- name: yyygit_repository: https://github.com/yyy/yyy.gitgit_tag: v0.1.11# 协议配置(可选)
protocols:- name: my_proto  # 协议名称type: protobuf   # 协议类型(protobuf/ros2)options:         # 选项(暂不支持)xxx: xxx- name: my_ros2_prototype: ros2options:zzz: zzz# 构建模式标签,仅在指定模式下构建build_mode_tag: ["EXAMPLE"]- name: example_prototype: protobuf# 未设置build_mode_tag表示在所有模式下都构建build_mode_tag: ["EXAMPLE"]# 模块配置(可选)
modules:- name: my_foo_module  # 模块名称- name: my_bar_module- name: exmaple_module# 仅在EXAMPLE模式下构建build_mode_tag: ["EXAMPLE"]options:  # 选项(暂不支持)aaa: aaa# 模块包配置(可选)
pkgs:- name: pkg1  # 包名称modules:    # 包含的模块- name: my_foo_module  # 模块名namespace: local     # 命名空间(自定义模块用local)- name: my_bar_modulenamespace: localoptions:sss: sss- name: pkg2modules:- name: exmaple_modulenamespace: local- name: ep_example_bar_modulenamespace: ep_example_aimrt_module  # 外部模块使用其实际命名空间build_mode_tag: ["EXAMPLE"]  # 仅在EXAMPLE模式下构建options:sss: sss# 部署配置(可选)
deploy_modes:- name: exmaple_mode  # 部署模式名称build_mode_tag: ["EXAMPLE"]  # 构建模式检查deploy_ins:  # 部署实例配置- name: local_ins_1  # 实例名称pkgs:    # 依赖的包- name: pkg1options:disable_modules: []  # 禁用的模块列表- name: local_ins_2  # 简单实例(无包配置)- name: remote_ins_123# 简单部署模式(默认在所有模式下构建)- name: deploy_mode_1- name: deploy_mode_2

CMake 依赖修正(cmake/GetAimRT.cmake​)

aimrt_cli​工具生成的项目框架,还需要指定仓库和版本

# cmake/GetAimRT.cmake
FetchContent_Declare(aimrtGIT_REPOSITORY https://github.com/AimRT/aimrt.gitGIT_TAG v0.8.3)  # 必须指定版本号

aimrt_main主进程

AimRT 提供的aimrt_main​可执行程序,在运行时根据配置文件加载动态库形式的Pkg​,导入其中的Module

项目工作流程

YAML 配置文件
aimrt_cli 工具
生成完整工程
CMake 编译
可执行程序
动态库
aimrt_main 加载

集成业务逻辑的两种方式(App与Pkg)

AimRT 框架可以通过两种方式来集成业务逻辑,分别是 App模式Pkg模式,实际采用哪种方式需要根据具体场景进行判断。两者的区别如下:

  • App模式:在开发者自己的 Main 函数中直接链接 AimRT 运行时库,编译时直接将业务逻辑代码编译进主程序:

    • 优势:没有 dlopen 这个步骤,没有 so,只会有最终一个 exe。
    • 劣势:可能会有第三方库的冲突;无法独立的发布Module​,想要二进制发布只能直接发布 exe。
    • 使用场景:一般用于小工具、小型 Demo 场景,没有太大的模块解耦需求;
  • Pkg模式:使用 AimRT 提供的 aimrt_main 可执行程序,在运行时根据配置文件加载动态库形式的Pkg​,导入其中的Module​类:

    • 优势:编译业务Module​时只需要链接非常轻量的 AimRT 接口层,不需要链接 AimRT 运行时库,减少潜在的依赖冲突问题;可以二进制发布 so;独立性较好。
    • 劣势:框架基于 dlopen 加载Pkg​,极少数场景下会有一些兼容性问题。
    • 使用场景:一般用于中大型项目,对模块解耦、二进制发布等有较强烈需求时;

无论采用哪种方式都不影响业务逻辑,且两种方式可以共存,实际采用哪种方式需要根据具体场景进行判断。

注意,上述说的两种方式只是针对 Cpp 开发接口。如果是使用 Python 开发,则只支持App模式。

执行器

Executor​,或者叫执行器,是指一个可以运行任务的抽象概念,一个执行器可以是一个 Fiber、Thread 或者 Thread Pool,我们平常写的代码也是默认的直接指定了一个执行器:Main 线程。一般来说,能提供以下接口的就可以算是一个执行器:

void Execute(std::function<void()>&& task);

还有一种Executor​提供定时执行的功能,可以指定在某个时间点或某段时间之后再执行任务。其接口类似如下:

void ExecuteAt(std::chrono::system_clock::time_point tp, std::function<void()>&& task);
void ExecuteAfter(std::chrono::nanoseconds dt, std::function<void()>&& task);

在 AimRT 中,执行器功能由接口层实际执行器的实现两部分组成,两者相互解耦。接口层定义了执行器的抽象 Api,提供投递任务的接口。而实现层则负责实际的任务执行,根据实现类型的不同有不一样的表现。AimRT 官方提供了几种执行器,例如基于 Asio 的线程池、基于 Tbb 的无锁线程池、基于时间轮的定时执行器等。

开发者使用 AimRT 的执行器功能时,在业务层将任务打包成一个闭包,然后调用接口层的 API,将任务投递到具体的执行器内,而执行器会根据自己的调度策略,在一定时机执行投递过来的任务。具体逻辑流程如下图所示:

请添加图片描述

http://www.xdnf.cn/news/209107.html

相关文章:

  • css3伸缩盒模型第一章(主轴以及伸缩盒模型)
  • P1903 [国家集训队] 数颜色 / 维护队列 Solution
  • neo4j暴露公网ip接口——给大模型联通知识图谱
  • Python 使用一等函数实现设计模式(案例分析:重构“策略”模式)
  • Linux 服务管理两种方式service和systemctl
  • Node.js 事件循环和线程池任务完整指南​
  • 香港科技大学广州|可持续能源与环境学域博士招生宣讲会—四川大学专场
  • 阿里云服务迁移实战: 05-OSS迁移
  • 【Linux系统】systemV共享内存
  • 基于tabula对pdf中多个excel进行识别并转换成word中的优化(五)
  • Go语言之路————接口、泛型
  • SpringMVC再复习1
  • MODSIM选型指南:汽车与航空航天企业如何选择仿真平台
  • 极客天成参与”AI助力智慧城市构建”主题演讲暨招商引智专题推介活动
  • 哈希表笔记(一 )
  • 【东枫电子】AI-RAN:利用人工智能驱动的计算基础设施变革 RAN
  • 后端部署:Flask + pymysql + MySQL迁移到服务器(以Linux为例)
  • Android Framework常见问题
  • 包装类的缓存机制
  • SELinux 从理论到实践:深入解析与实战指南
  • 算法题(137):丢手绢
  • 在yolo中Ultralytics是什么意思呢?超越分析的智能
  • 篮球足球体育球员综合资讯网站模板
  • git学习之git常用命令
  • MySQL 在 CentOS 7 环境下的安装教程
  • Go 语言中的 `recover()` 函数详解
  • 快速了解Go+微服务(概念和一个例子)
  • CA添加删除辅小区信令流程
  • 联邦学习与安全多方计算的结合是隐私保护机器学习领域
  • Android启动应用时屏蔽RecyclerView滑动,延时后再允许滑动,Kotlin