【AimRT】AimRT Hello World

目录

  • 一、工程结构
  • 二、源码说明
    • /CMakeLists.txt
    • /cmake/GetAimRT.cmake
    • /src/CMakeLists.txt
    • /src/module/helloworld_module/CMakeLists.txt
    • /src/app/helloworld_app/CMakeLists.txt
    • /src/install/cfg/helloworld_cfg.yaml
    • /src/module/helloworld_module/helloworld_module.h
    • /src/module/helloworld_module/helloworld_module.cc
    • /src/app/helloworld_app/main.cc
  • 三、编译与运行

官方 Hello World 文档链接:https://docs.aimrt.org/tutorials/quick_start/helloworld_cpp.html

这里对其增加一些说明。

目前 AimRT 仅支持从源码安装,并且对于第三方依赖,也是通过拉取源码的方式安装,该方式通过 CMake 的FetchContent 实现,虽然该方式可以增强AimRT环境配置的兼容性,但对于封闭网络开发与网络不好的用户不太友好,而且部署一次环境是局部生效的,同一台电脑再新建一个工程还需要拉取源码安装一次。

该 Hello World Demo 涉及以下内容:

  • 基于 CMake FetchContent 通过源码引用 AimRT;
  • 编写一个基础的基于 AimRT CPP 接口的Module
  • 使用基础的日志功能;
  • 使用基础的配置功能;
  • 以 App 模式集成Module
  • 编译项目,并运行进程以执行Module中的逻辑。

一、工程结构

├── CMakeLists.txt                    
├── cmake
│   └── GetAimRT.cmake                # 基于 CMake FetchContent 通过源码引用 AimRT
└── src├── CMakeLists.txt├── install                      # 存放部署时的一些配置、启动脚本等│   └── cfg│       └── helloworld_cfg.yaml  # AimRT配置文件 ├── module                       # 存放业务逻辑代码│   └── helloworld_module│       ├── CMakeLists.txt│       ├── helloworld_module.cc # Module源文件│       └── helloworld_module.h  # Module头文件└── app                          # 以App模式集成Module└── helloworld_app         ├── CMakeLists.txt└── main.cc

二、源码说明

/CMakeLists.txt

根 CMake ,用于构建工程。

# 指定项目所需的最低CMake版本
cmake_minimum_required(VERSION 3.24)# 定义项目的名称为helloworld,并指定该项目将使用C和C++语言
project(helloworld LANGUAGES C CXX)# 设置项目使用的C++标准为C++20
set(CMAKE_CXX_STANDARD 20)
# 要求CMake确保编译器支持指定的C++标准。
# 如果编译器不支持该标准,CMake配置将失败。
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 禁用编译器特定的扩展
set(CMAKE_CXX_EXTENSIONS OFF)# 包含一个名为GetAimRT.cmake的CMake模块
# 用于通过源码引用 AimRT
include(cmake/GetAimRT.cmake)# 添加并处理src子目录
add_subdirectory(src)

/cmake/GetAimRT.cmake

通过源码引用 AimRT

# 包含FetchContent模块,该模块提供了一系列函数和宏,用于从远程仓库获取内容
include(FetchContent)message("get aimrt ...")# 使用FetchContent_Declare函数声明一个名为aimrt的外部项目
FetchContent_Declare(aimrtGIT_REPOSITORY https://github.com/AimRT/aimrt.git # 项目仓库链接GIT_TAG v0.9.2) # 项目版本# 获取aimrt项目属性
# 用于检查项目是否已经被下载、配置和构建
FetchContent_GetProperties(aimrt)# 检查aimrt项目是否已经下载并准备好用于构建
# 如果项目尚未准备好,则调用FetchContent_MakeAvailable函数下载、配置和构建该项目,
# 并将其添加到当前项目的构建系统中,使其可用
if(NOT aimrt_POPULATED)FetchContent_MakeAvailable(aimrt)
endif()

/src/CMakeLists.txt

引用 src 下的各个子目录

add_subdirectory(module/helloworld_module)
add_subdirectory(app/helloworld_app)

/src/module/helloworld_module/CMakeLists.txt

创建helloworld_module静态库

# 递归地查找当前源目录(${CMAKE_CURRENT_SOURCE_DIR})下所有以.cc结尾的文件,
# 并将这些文件的路径列表赋值给变量src
file(GLOB_RECURSE src ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)# 创建一个名为helloworld_module的静态库目标
add_library(helloworld_module STATIC)
# 为helloworld_module静态库创建一个别名目标helloworld::helloworld_module
# 别名目标允许以更具命名空间风格的方式引用库,这在大型项目中尤其有用,可以避免名称冲突
add_library(helloworld::helloworld_module ALIAS helloworld_module)# 将之前通过file(GLOB_RECURSE ...)找到的源文件(变量src)添加到helloworld_module目标的私有源文件中
# PRIVATE意味这些文件仅对helloworld_module目标本身可见,不会传播到依赖于它的其他目标
target_sources(helloworld_module PRIVATE ${src})# 为helloworld_module目标添加公共头文件目录
# 公共头文件目录意味着这些目录不仅可用于构建helloworld_module本身,
# 还可用于构建依赖于helloworld_module的任何目标
target_include_directories(helloworld_modulePUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)# 指定helloworld_module目标需要链接的库
target_link_libraries(helloworld_module# yaml-cpp库是私有依赖项,仅用于构建helloworld_module本身,不会传播到依赖于它的其他目标PRIVATE yaml-cpp::yaml-cpp # 公共依赖项,不仅用于构建helloworld_module,还用于构建依赖于helloworld_module的任何目标PUBLIC aimrt::interface::aimrt_module_cpp_interface)

/src/app/helloworld_app/CMakeLists.txt

创建helloworld_app可执行文件

# 递归地查找当前源目录(${CMAKE_CURRENT_SOURCE_DIR})下所有以.cc结尾的文件,
# 并将这些文件的路径列表赋值给变量src
file(GLOB_RECURSE src ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)# 添加名为helloworld_app的可执行文件
add_executable(helloworld_app)# 为helloworld_app目标指定源文件
target_sources(helloworld_app PRIVATE ${src})# 为helloworld_app目标指定头文件
target_include_directories(helloworld_appPRIVATE ${CMAKE_CURRENT_SOURCE_DIR})# 为helloworld_app目标指定链接库
target_link_libraries(helloworld_appPRIVATE aimrt::runtime::core helloworld::helloworld_module)

/src/install/cfg/helloworld_cfg.yaml

配置文件

aimrt:log: # log配置core_lvl: Debug # 内核日志等级,可选项:Trace/Debug/Info/Warn/Error/Fatal/Off,不区分大小写backends: # 日志后端- type: console # 控制台日志options:color: true # 是否要彩色打印module_filter: "(.*)" # 支持以正则表达式的形式,来配置哪些模块的日志可以通过本后端处理pattern: "[%c.%f][%l][%t][%n][%G:%R @%F] %v" # 日志格式化输出- type: rotate_file # 将日志打印到文件中options:path: ./log # 日志文件存放目录filename: examples_cpp_hello_world.log # 日志文件名称# 模块自定义业务配置,以模块名称为节点名
HelloWorldModule:name: "HelloWorldModule"array: - name: helloenable: true- name: worldenable: false

/src/module/helloworld_module/helloworld_module.h

Module头文件

// 防止头文件在当前编译单元中被多次引用
#pragma once#include "aimrt_module_cpp_interface/module_base.h"// 定义一个 HelloWorldModule 类,继承自aimrt::ModuleBase
class HelloWorldModule : public aimrt::ModuleBase
{
public:HelloWorldModule() = default;~HelloWorldModule() override = default;// 模块信息,包括name、version、author、description等aimrt::ModuleInfo Info() const override{return aimrt::ModuleInfo{.name = "HelloWorldModule",.major_version = 0,.minor_version = 1,.patch_version = 0,.build_version = 0,.author = "vistar",.description = "AimRT hello world model"};}// 初始化模块资源bool Initialize(aimrt::CoreRef core) override;// 启动模块bool Start() override;// 关闭模块void Shutdown() override;private:// 返回一个日志记录器实例auto GetLogger() { return core_.GetLogger(); }private:aimrt::CoreRef core_;aimrt::parameter::ParameterHandleRef parameter_handle_;
};

/src/module/helloworld_module/helloworld_module.cc

Module源文件

#include "helloworld_module/helloworld_module.h"
#include "yaml-cpp/yaml.h"bool HelloWorldModule::Initialize(aimrt::CoreRef core)
{// Save aimrt framework handlecore_ = core;// LogAIMRT_INFO("Init HelloWorldModule.");try{// Read cfgauto file_path = core_.GetConfigurator().GetConfigFilePath();if (!file_path.empty()){// 将配置写入到临时文件中,使用YAML-CPP加载配置YAML::Node config = YAML::LoadFile(file_path.data());std::string moduleName = config["name"].as<std::string>();AIMRT_INFO("moduleName: {}", moduleName);for (const auto &itemNode : config["array"]){std::string itemName = itemNode["name"].as<std::string>();bool enable = itemNode["enable"].as<bool>();AIMRT_INFO("name: {}, enable: {}", itemName, enable);}}}catch (const std::exception &e){AIMRT_ERROR("Init failed, {}", e.what());return false;}AIMRT_INFO("Init HelloWorldModule succeeded.");return true;
}bool HelloWorldModule::Start()
{AIMRT_INFO("Start HelloWorldModule succeeded.");return true;
}void HelloWorldModule::Shutdown()
{AIMRT_INFO("Shutdown HelloWorldModule succeeded.");
}

/src/app/helloworld_app/main.cc

#include <csignal>
#include <iostream>#include "core/aimrt_core.h"
#include "helloworld_module/helloworld_module.h"using namespace aimrt::runtime::core;AimRTCore *global_core_ptr_ = nullptr;// 信号处理函数
void SignalHandler(int sig)
{if (global_core_ptr_ && (sig == SIGINT || sig == SIGTERM)){global_core_ptr_->Shutdown();return;}raise(sig);
};int32_t main(int32_t argc, char **argv)
{// 注册 ctrl+c 信号监听,用 SignalHandler 函数处理signal(SIGINT, SignalHandler);// 注册 kill 信号监听,用 SignalHandler 函数处理signal(SIGTERM, SignalHandler);std::cout << "AimRT start." << std::endl;try{// 实例化 AimRTCoreAimRTCore core;global_core_ptr_ = &core;// register moduleHelloWorldModule helloworld_module;core.GetModuleManager().RegisterModule(helloworld_module.NativeHandle());// 通过命令行参数读取配置文件路径AimRTCore::Options options;options.cfg_file_path = argv[1];// 初始化AimRT,初始化注册的 Modulecore.Initialize(options);// 启动AimRT,启动注册的 Module// 阻塞主线程等待结束core.Start();core.Shutdown();global_core_ptr_ = nullptr;}catch (const std::exception &e){std::cout << "AimRT run with exception and exit. " << e.what() << std::endl;return -1;}std::cout << "AimRT exit." << std::endl;return 0;
}

三、编译与运行

编译工程和普通编译CMake工程操作一样:

# 在根CMakeList.txt同级目录执行
# 生成构建文件,配置项目
cmake -B build# 编译和链接可执行文件和库文件
cd build
make -j

运行AimRT可执行文件,需要传入配置文件。

编译完成后,将生成的可执行文件helloworld_app和配置文件helloworld_cfg.yaml拷贝到一个目录下,然后执行以下命令运行进程:

./helloworld_app helloworld_cfg.yaml

欢迎加QQ群,一起讨论学习:894013891

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp H5 对接 声网,截图

文章目录 安装依赖创建容器容器样式 javascript代码ImageDataToBlob 方法 控制控制台LOG输出 安装依赖 版本"agora-rtc-sdk-ng": "^4.22.0", 创建容器 <template><view class"videoValue " id"videoValue"><u-toast…

Global 远程需求

需求 1 周期&#xff1a;半年 rate&#xff1a;税后 30-40k/月&#xff0c;free 模式 公司&#xff1a;外资咨询 项目地点&#xff1a;远程为主 语言要求&#xff1a;英语 具体JD Task Description&#xff1a; •Refinement of user stories (together with Product Own…

Pycharm连接远程解释器

这里写目录标题 0 前言1 给项目添加解释器2 通过SSH连接3 找到远程服务器的torch环境所对应的python路径&#xff0c;并设置同步映射&#xff08;1&#xff09;配置服务器的系统环境&#xff08;2&#xff09;配置服务器的conda环境 4 进入到程序入口&#xff08;main.py&#…

kafka使用以及基于zookeeper集群搭建集群环境

一、环境介绍 zookeeper下载地址&#xff1a;https://zookeeper.apache.org/releases.html kafka下载地址&#xff1a;https://kafka.apache.org/downloads 192.168.142.129 apache-zookeeper-3.8.4-bin.tar.gz kafka_2.13-3.6.0.tgz 192.168.142.130 apache-zookee…

rsync命令常用同步方案

rsync是一个高效的文件同步工具&#xff0c;广泛应用于本地和远程备份、镜像及同步任务。它通过增量同步、压缩传输以及远程协议&#xff08;如SSH&#xff09;等技术&#xff0c;显著提高了文件传输的效率。本文将介绍rsync命令的常用参数、工作原理、常见同步方案&#xff0c…

JavaScript学习-入门篇

​ JavaScript的运行环境 开发环境就是开发JavaScript代码所需的环境&#xff0c;一般建议新手刚刚开始使用一些记事本工具&#xff08;如sublime、editPlus、VScode&#xff09;&#xff0c;锻炼代码的手感。等学习到一定阶段&#xff0c;就可以使用集成开发工具IDE&#xff0…

SQL把字符串按逗号分割成记录

在 SQL 中&#xff0c;可以通过以下方法将字符串按逗号分割&#xff0c;并将每个分割的值作为单独的记录插入到结果集中。以下是针对不同数据库系统的实现方法&#xff1a; 1. 使用 STRING_SPLIT&#xff08;SQL Server 2016&#xff09; STRING_SPLIT 是 SQL Server 提供的内置…

大模型系列18-AI Agents

什么是AI Agents Al Agent智能体&#xff0c;是指一种能够模拟人类思考和行为来自动执行任务&#xff0c;以解决复杂问题的程序或系统 架构图 思考->行动->观测 思考依赖记忆以及规划决策&#xff0c;行动依赖工具&#xff0c;观测依赖感知 举例 长沙今天白天和晚上的…

mysql自定义安装

1、下载安装包 我是在windows上安装&#xff0c;所以选择“Mysql Installer for Windows” 2、安装mysql 双击“mysql-installer-community-8.0.40.0.msi”&#xff0c;开始启动安装 这里选择安装项&#xff0c;这里只选择了两项。workbench是图形化管理工具&#xff0c;比较吃…

22408操作系统期末速成/复习(考研0基础上手)

第一部分:计算题&#xff1a; 考察范围&#xff1a;&#xff08;标红的是重点考&#xff09; 第一章&#xff1a;CPU利用率&#xff1a; 第二章&#xff1a; 进程调度算法&#xff08;需要注意不同调度算法的优先级和题目中给出的是否可以抢占【分为可抢占和不可抢占&#xff…

数据去重与重复数据的高效处理策略

在实际业务中&#xff0c;数据去重是一个非常常见的需求&#xff0c;特别是在日志数据、用户操作记录或交易记录等领域。去重不仅仅是删除重复数据&#xff0c;更重要的是按照业务规则保留最有价值的数据记录。 本文将探讨如何在 SQL 中高效地处理重复数据&#xff0c;通过 DI…

综合能源建模:理论、方法与实践

一、引言 随着全球能源需求的持续增长以及对能源安全、环境保护和可持续性发展的日益关注&#xff0c;综合能源系统&#xff08;Integrated Energy System&#xff0c;IES&#xff09;作为一种能够整合多种能源资源、实现能源高效利用和协同优化的解决方案&#xff0c;正逐渐成…

【Leetcode 热题 100】74. 搜索二维矩阵

问题背景 给你一个满足下述两条属性的 m n m \times n mn 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 t a r g e t target target&#xff0c;如果 t a r g e t target target 在矩阵中&…

DOS攻击的原理和实现 (网络安全)hping3和Slowloris的运用

DoS攻击的原理和实现 DoS攻击&#xff08;Denial of Service Attack&#xff0c;拒绝服务攻击&#xff09;是指通过恶意手段使目标服务器、服务或网络资源无法正常提供服务&#xff0c;从而影响正常用户的访问。DoS攻击通常通过消耗目标系统的资源&#xff08;如带宽、内存、处…

Elasticsearch与数据库数据一致性:最佳实践与解决方案

在现代应用程序中&#xff0c;Elasticsearch&#xff08;ES&#xff09;作为一个高效的分布式搜索引擎&#xff0c;常常与数据库一同使用&#xff0c;以提供强大的搜索、分析和数据可视化功能。然而&#xff0c;数据库和Elasticsearch之间的同步与一致性常常成为一个挑战。如何…

jquery实现的网页版扫雷小游戏源码

源码介绍 这是一款基于jQuery实现的经典扫雷小游戏源码&#xff0c;玩家根据游戏规则进行游戏&#xff0c;末尾再在确定的地雷位置单击右键安插上小红旗即可赢得游戏&#xff01;是一款非常经典的jQuery游戏代码。本源码改进了获胜之后的读数暂停功能。 效果预览 源码下载 j…

接口隔离原则,到底什么需要隔离?

接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09;是SOLID五大设计原则之一&#xff0c;其核心思想是&#xff1a;客户端不应该被迫依赖于它不使用的方法&#xff1b;接口应当尽量小而专一&#xff0c;避免创建“胖”接口&#xff08;即一个接口中定义…

对计网大题的一些指正(中间介绍一下CDM的原理和应用)

目录 前言&#xff1a; &#xff08;1&#xff09;五层原理体系结构每层功能&#xff1a; 下面是文档的答案&#xff1a; 我在之前的博客里面有介绍过五层原理体系结构&#xff0c; 按理来说&#xff0c;第五层应该是应用层才对&#xff0c;而会话层的功能应该被放到应用层…

Arduino UNO 驱动1.8 TFT屏幕显示中文

背景 最近入手了一块1.8寸的tft屏幕&#xff0c;通过学习文档&#xff0c;已经掌握了接线&#xff0c;显示英文、数字、矩形区域、划线、画点等操作&#xff0c; 但是想显示中文的时候操作比较复杂。 问题 1、arduino uno 驱动这款屏幕目前使的是自带的<TFT.h> 库操作…

【论文阅读】Anchor-based fast spectral ensemble clustering

论文地址&#xff1a;Anchor-based fast spectral ensemble clustering - ScienceDirect 代码地址&#xff1a; 摘要 集成聚类通过融合多个基础聚类方法&#xff0c;可以获得更好且更稳健的结果&#xff0c;因此受到广泛关注。尽管近年来已经出现了许多代表性的算法&#xff…