diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..d78088634 Binary files /dev/null and b/.DS_Store differ diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 000000000..fb924621d Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/Home.md b/docs/Home.md index 4e88f8176..b9ae929a6 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -791,6 +791,22 @@ sidebar_custom_props: }, ], }, + { + products_name: "Cubie A7A", + products_photo_url: "/home/product-pictures/a7a.webp", + products_link: "/cubie/a7a", + docs: + [ + { + docs_link: "/cubie/a7a", + docs_photo_type: "Overview", + docs_name_en: "Overview", + docs_name_zh: "Cubie A7A 概览", + docs_info_en: "Overview of the cubie a7a", + docs_info_zh: "Radxa Cubie A7A 概览", + }, + ], + }, ], }, ], diff --git a/docs/common/.DS_Store b/docs/common/.DS_Store new file mode 100644 index 000000000..a0b52f9a8 Binary files /dev/null and b/docs/common/.DS_Store differ diff --git a/docs/common/ai/_cubie_acuity_env.mdx b/docs/common/ai/_cubie_acuity_env.mdx new file mode 100644 index 000000000..87c35602e --- /dev/null +++ b/docs/common/ai/_cubie_acuity_env.mdx @@ -0,0 +1,105 @@ +ACUITY Toolkit 是一个端到端的模型转换,模型量化,模型编译的集成离线开发工具,ACUITY 支持多种 AI 框架的模型转换,并能直接生成模型运行的代码。 +![SDK](/img/e/e54c/rs400_npu_2.webp) + +ACUITY Toolkit 以 Docker Image 的形式安装,在安装 ACUITY 前请用户在 X86 PC 上自行安装 Docker。 + +## 安装 Docker + +请根据不同平台在用户 X86 PC 上安装 Docker, 更多 Docker 安装请参考 [dockerdocs](https://docs.docker.com/engine/install/) + +这里以 Ubuntu 为例子安装 Docker。 + +### 卸载旧版本 Docker + + + +```bash +for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done +``` + + + +### 配置 docker apt 仓库 + + + +```bash +# Add Docker's official GPG key: +sudo apt-get update +sudo apt-get install ca-certificates curl +sudo install -m 0755 -d /etc/apt/keyrings +sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc +sudo chmod a+r /etc/apt/keyrings/docker.asc + +# Add the repository to Apt sources: +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt-get update +``` + + + +### 安装 docker + + + +```bash +sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +``` + + + +## 安装 ACUITY + +### 获取 ACUITY 下载包 + +在 [全志网盘](https://netstorage.allwinnertech.com:5001/sharing/Mh23BhPHq) 下载 ACUITY docker 压缩包并解压 + + + +```bash +unzip docker_images_v2.0.x.zip +``` + + + +### 载入镜像 + + + +```bash +cd docker_images_v2.0.x +unzip ubuntu-npu_v2.0.10.tar.zip +sudo docker load -i ubuntu-npu_v2.0.10.tar +``` + + + +当 docker 镜像载入完成后可以在 `docker images` 中看到此镜像, 名字为 `ubuntu‑npu:v2.0.10` + +### 创建 docker 容器 + + + +```bash +mkdir docker_data && cd docker_data +sudo docker run ‑‑ipc=host ‑itd ‑v ${PWD}:/workspace ‑‑name allwinner_v2.0.10 ubuntu‑npu:v2.0.10 /bin/bash +``` + + + +当 docker 容器创建完成后可以在 `docker ps -a` 中看到此容器, 名字为 `allwinner_v2.0.10` + +### 进入 docker 容器 + +请使用 `docker ps -a` 查看 `allwinner_v2.0.1` 容器 ID + + + +```bash +sudo docker exec ‑it 容器ID /bin/bash +``` + + diff --git a/docs/common/ai/_cubie_acuity_sdk.mdx b/docs/common/ai/_cubie_acuity_sdk.mdx new file mode 100644 index 000000000..34dcc40df --- /dev/null +++ b/docs/common/ai/_cubie_acuity_sdk.mdx @@ -0,0 +1,113 @@ +:::tip 适配主板 + +- 瑞莎 Cubie A5E +- 瑞莎 Cubie A7A +- 瑞莎 Cubie A7Z + +全志科技 T527 / A733 SoC 搭载的是 Vivante VIP9000 系列 NPU。 + +::: + +Vivante Machine Learning SDK 是一个强大的工具套件,可帮助开发者在支持的主板上部署和加速 AI 推理任务。通过 VIP9000 系列 NPU 的硬件加速,能够显著提升 AI 模型的推理性能。 + +Vivante Machine Learning SDK 支持多种模型框架,如 TensorFlow, TensorFlow Lite, PyTorch, Caffe, DarkNet, ONNX, Keras 等框架模型的转换,可将多种 AI 模型编译成可以在 Vivante VIP9000 系列 NPU 推理的模型格式。 + +要使用 NPU 对不同框架的 AI 模型进行部署和推理前,需要进行以下两步: + +- 解析模型结构,将模型算子转换为中间表示 IR(Intermediate Representation)。 +- 将中间表示 IR 编译为机器特定的指令。 + +以上两个步骤均可以使用 **在线模式(online)** 和 **离线模式 (offline)** 进行实现, 为了方便理解, 在线模式称为 **Runtime Inferencing**, 离线模式称为 **Offline Compilation**。 + +![SDK](/img/e/e54c/rs400_npu_1.webp) + +## Runtime Inferencing + +使用 Runtime Inferencing 模式用户仅需关注原模型框架而无需关注目标部署平台,转换中间表示 IR 和模型编译的步骤可以运行在任何平台上,用户无需维护,让目标平台驱动自动处理底层加速, +适合跨平台的软件使用。 + +:::info +有关所有 Runtime Inferencing 的详细使用方法,请参考 [Vivante TIM-VX - Tensor Interface Module](https://github.com/VeriSilicon/TIM-VX) 开源仓库。 +本文档不针对 Runtime Inferencing 提供详细使用方法。 +::: + +## Offline Compilation + +使用 ACUITY Toolkit 可以将原模型在部署前先编译成 NPU 可运行的格式, +且支持 UINT8, PCQ(INT8), INT16, BF16 量化和混合量化,并在模型编译时自动进行算子融合优化模型结构,可以打大大降低模型初始化速度和资源开销,适合紧凑的嵌入式设备使用。 +ACUITY Toolkit 可自动生成基于 OpenVX 驱动的跨平台模型部署代码和预编译 NBG 模型部署代码。 + +- Machine Code Generator - Network Binary Graph (NBG) + + NBG(Network Binary Graph) 可直接部署在 Vivante NPU 上。由于 NBG 本身就是机器代码形式,因此无需进一步编译, 直接发送指令到硬件即可完成模型初始化, 可以使用 OpenVX 驱动和 VIPLite 驱动运行。 + +- Source Code Generator - OpenVX Code + + OpenVX 代码生成器会生成一个 OpenVX 源代码(C 语言)项目,该项目可以部署在 Vivante NPU 上,使用 OpenVX 进行驱动。由于生成的 OpenVX 应用是图级的中间表示(IR),因此在部署到硬件设备时,OpenVX 运行时驱动仍需执行即时(JIT)编译。这种格式的优势在于,它能够利用离线工具所进行模型优化,并保持应用的跨平台特性。 + +| | NBG 项目 | OpenVX 项目 | +| ------------------ | -------- | ----------- | +| 跨平台应用支持 | 否 | 是 | +| 即时(JIT)编译 | 否 | 是 | +| 即时模型初始化时间 | 是 | 否 | +| 支持 OpenVX 驱动 | 是 | 是 | +| 支持 VIPLite 驱动 | 是 | 否 | + +## 模式对比 + +| | Runtime Inferencing | Offline Compilation | +| ------------------ | ------------------- | ------------------- | +| 跨平台应用支持 | Yes | No | +| 易维护 | Yes | No | +| 模型算子融合 | No | Yes | +| 即时模型初始化时间 | No | Yes | +| 模型量化 | No | Yes | + +## Vivante ML 软件栈 + +### ACUITY Toolkit + +ACUITY Toolkit 是一个端到端的模型转换,模型量化,模型编译的集成离线开发工具,ACUITY 支持多种 AI 框架的模型转换,并能直接生成模型运行的代码。 + +![SDK](/img/e/e54c/rs400_npu_2.webp) + +:::tip 安装与使用文档 + +- [ACUITY 环境配置](./cubie_acuity_env) + +- [ACUITY Toolkit 使用方法](./cubie_acuity_usage) + +- [ACUITY 量化精度优化](./cubie_quant_acc_improve) + +::: + +### TIM-VX - Tensor Interface Module + +TIM-VX 是由 VeriSilicon 提供的一款软件集成模块,旨在简化神经网络在其 ML 加速器上的部署。它作为运行时框架(如 Android NN、TensorFlow Lite、MLIR、TVM 等)的后端绑定接口,提供了高效的推理支持。是 Runtime Inferencing 主要的在线开发模块。 +:::info +有关所有 Runtime Inferencing 的详细使用方法,请参考 [Vivante TIM-VX - Tensor Interface Module](https://github.com/VeriSilicon/TIM-VX) 开源仓库。 +本文档不针对 Runtime Inferencing 提供详细使用方法。 +::: + +### Vivante Unified Driver + +Vivante Unified Driver 为 NPU(神经网络处理单元)提供了标准化的编程接口。该驱动栈支持 OpenVX 和 OpenCL 等业界标准 API,并兼容 Linux 与 Android 操作系统。 + +### Vivante VIPLite Driver + +VIPLite Driver 是一款为嵌入式系统(如 Linux 或 RTOS)设计的轻量级驱动。它能够以极低的开销加载并运行 ACUITY 预编译的神经网络模型。 +{/* :::tip */} +{/* RTD1619B 系统并未移殖 VIPLite Driver */} +{/* ::: */} + +### Unified 和 VIPLite 驱动对比 + +| 项目 | Unified Driver | VIPLite Driver | +| ------------------------ | --------------- | ----------------------------------------- | +| 工作环境 | Android / Linux | Android / Linux / RTOS / Bare Metal / DSP | +| 离线编译(NBG) | 支持 | 支持 | +| 运行时即时编译(JIT) | 支持 | 不支持 | +| 多 VIP 支持 | 支持 | 支持 | +| 内存占用 | 数十 MB | 数十 KB | +| 支持 MMU(内存管理单元) | 支持 | 支持 | +| 多图支持(Multi-Graph) | 支持 | 支持 | diff --git a/docs/common/ai/_cubie_acuity_usage.mdx b/docs/common/ai/_cubie_acuity_usage.mdx new file mode 100644 index 000000000..85595b0db --- /dev/null +++ b/docs/common/ai/_cubie_acuity_usage.mdx @@ -0,0 +1,549 @@ +这里将以 Keras 格式的 MobileNetV2 目标识别模型为例子,将使用 Acuity Toolkit 对模型进行解析,量化和编译,并生成项目代码,并使用 Vivante IDE 进行模拟仿真,最后在 VIP9000 系列 NPU 上进行推理。 + +## NPU 版本对照表 + +| 产品 | 算力 | 平台 | NPU 版本 | NPU 软件版本 | +| --------- | ------ | ---- | -------- | ------------ | +| Radxa A5E | 2 Tops | T527 | v2 | v1.13 | +| Radxa A7A | 3 Tops | A733 | v3 | v2.0 | + +{/* ## 配置环境变量 */} +{/* - 初始化 ACUITY pegasus.py 脚本 */} +{/* ```bash */} +{/* python3 ~/work/Acuity/toolkit/bin/pegasus.py completion */} +{/* source ~/work/Acuity/toolkit/bin/pegasus_completion */} +{/* ``` */} +{/* - 配置 pegasus 工具脚本环境变量 */} +{/* ```bash */} +{/* export PATH=$PATH:~/work/Acuity/acuity_examples/scripts */} +{/* ``` */} + +{/* - 配置 ACUITY_PATH 变量 */} +{/* ```bash */} +{/* export ACUITY_PATH=~/work/Acuity/toolkit/bin */} +{/* ``` */} + +{/* - 配置 SOC_BOARD 变量 */} +{/* ```bash */} +{/* export SOC_BOARD="1619b" */} +{/* ``` */} + +{/* - 配置 Vivante IDE 命令行工具路径变量 */} +{/* ```bash */} +{/* export IDE=~/VeriSilicon/VivanteIDE5.10.0/cmdtools */} +{/* ``` */} + +## 下载例子仓库 + +在 [ACUITY Docker 容器](./cubie_acuity_env#创建-docker-容器) 中下载示例仓库 + +下载仓库 + + + +```bash +git clone https://github.com/ZIFENG278/ai-sdk.git +``` + + + +配置模型编译脚本 + + + +```bash +cd ai-sdk/models +source env.sh v3 # NPU_VERSION +cp ../scripts/* . +``` + + + +:::tip +指定 NPU_VERSION, A733 指定 `v3`, T527 指定 `v1.13`。 信息对照请参考 [NPU 版本对照表](#npu-版本对照表) +::: + +## 模型解析 + +在 Docker 中进入示例仓库中的 ai-sdk/models/MobileNetV2_Imagenet 模型例子目录。 + + + +```bash +cd ai-sdk/models/MobileNetV2_Imagenet +``` + + + +此目录中包含以下文件,其中: + +- MobilNetV2_Imagenet.h5 为原模型文件(必要)。 +- channel_mean_value.txt 为模型输入的 mean 和 scale 值的文件。 +- dataset.txt 为模型量化的校准文件集文件。 +- space_shuttle_224x224.jpg 为测试输入图片和教准集中包含的校准图片 。 +- input_outputs.txt 包含模型输入输出节点文件。(如果有必要需设置输出节点,避免量化失败) + +```bash +. +|-- MobileNetV2_Imagenet.h5 +|-- channel_mean_value.txt +|-- dataset.txt +|-- inputs_outputs.txt +`-- space_shuttle_224x224.jpg + +0 directories, 5 files +``` + +### 导入模型 + +`pegasus_import.sh` 模型导入脚本,可以将多种不同的 AI 框架模型进行模型结构和权重解析, 并输出模型解析后的文件: + +- 模型架构会保存在 MODEL_DIR.json +- 模型权重会保存在 MODEL_DIR.data +- 自动生成模型输入文件模板 MODEL_DIR_inputmeta.yml +- 自动生成模型后处理文件模板 MODEL_DIR_postprocess_file.yml + + + +```bash +# pegasus_import.sh MODEL_DIR +./pegasus_import.sh MobileNetV2_Imagenet/ +``` + + + +参数: + +- MODEL_DIR 包含源模型文件的文件夹 + +### 手动修改模型输入文件 + +这里需要按照模型输入预处理的 mean, scale 对 `MobileNetV2_Imagenet_inputmeta.yml` 中的 mean 和 scale 进行手动设置。 +这里以 MobileNetV2_ImageNet 为例子,因为 MobileNet 的输出为 (1,224,224,3) RGB 三通道,根据模型预处理公式: + +```bash +x1 = (x - mean) / std +x1 = (x - mean) * scale +scale = 1 / std +``` + +因为训练数据集为 ImageNet, 这里 ImageNet 训练集的归一化 mean 为 [0.485, 0.456, 0.406],std 为 [0.229, 0.224, 0.225], +这里需要进行进行反归一化计算。归一化数据参考 [pytorch 文档](https://docs.pytorch.org/vision/main/models/generated/torchvision.models.mobilenet_v2.html) + +```bash +# mean +0.485 * 255 = 123.675 +0.456 * 255 = 116.28 +0.406 * 255 = 103.53 +``` + +```bash +# scale +1 / (0.229 * 255) = 0.01712 +1 / (0.224 * 255) = 0.01751 +1 / (0.225 * 255) = 0.01743 +``` + +这里按照计算得出 mean 和 scale 修改 `MobileNetV2_Imagenet_inputmeta.yml` 中 mean 和 scale 的数值: + +```vim +mean: +- 123.675 +- 116.28 +- 103.53 +scale: +- 0.01712 +- 0.01751 +- 0.01743 +``` + +## 量化模型 + +模型在进行转换之前,可以对模型进行不同类型的量化,ACUITY 支持 uint8 / int16 / bf16 / pcq (int8 per-channel quantized)多种量化方式, +如使用 float 表示不进行量化。 + +使用 `pegasus_quantize.sh` 脚本可对模型进行指定类型的量化。 +:::tip +如果源模型本身已经是量化模型,这里无需进行量化,否则会报错。 +::: + + + +```bash +# pegasus_quantize.sh MODEL_DIR QUANTIZED ITERATION +pegasus_quantize.sh MobileNetV2_Imagenet int16 10 +``` + + + +量化会生成对应量化方式的量化文件 MODEL_DIR_QUANTIZED.quantize + +| QUANTIZED | TYPE | QUANTIZER | +| --------- | ----- | --------------------------- | +| uint8 | uint8 | asymmetric_affine | +| int16 | int16 | dynamic_fixed_point | +| pcq | int8 | perchannel_symmetric_affine | +| bf16 | bf16 | qbfloat16 | + +{/* ### 进行 pcq int8 量化 */} +{/* ```bash */} +{/* # pegasus_quantize.sh MODEL_DIR QUANTIZED ITERATION */} +{/* pegasus_quantize.sh MobileNetV2_Imagenet pcq 10 */} +{/* ``` */} + +{/* ### 进行 int16 量化 */} +{/* ```bash */} +{/* # pegasus_quantize.sh MODEL_DIR QUANTIZED ITERATION */} +{/* pegasus_quantize.sh MobileNetV2_Imagenet int16 10 */} +{/* ``` */} + +{/* ### 进行 bf16 量化 */} +{/* ```bash */} +{/* # pegasus_quantize.sh MODEL_DIR QUANTIZED ITERATION */} +{/* pegasus_quantize.sh MobileNetV2_Imagenet bf16 10 */} +{/* ``` */} + +## 推理量化模型 + +模型经过量化后,性能会有不同程度的提升,但是精度会稍微降低,经过量化的模型可以通过 `pegasus_inference.sh` 进行推理,验证量化后模型精度是否满足。 +测试推理的输入为 dataset.txt 里的第一张图片。 +![space_shuttle](/img/e/e54c/rs400_npu_3.webp) + +### 推理 float 类型模型 + +推理未量化的 float 模型,得到结果作为量化模型结果的参考 + + + +```bash +# pegasus_inference.sh MODEL_DIR QUANTIZED ITERATION +pegasus_inference.sh MobileNetV2_Imagenet/ float +``` + + + +推理结果输出为 + +```bash +I 07:01:06 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : +I 07:01:06 812: 0.9990391731262207 +I 07:01:06 814: 0.0001562383840791881 +I 07:01:06 627: 8.89502334757708e-05 +I 07:01:06 864: 6.59249781165272e-05 +I 07:01:06 536: 2.808812860166654e-05 +``` + +这里输出的 top5 置信度最高为 812, 对应 label 为 `space shuttle`, 这与实际的输入图片类型吻合, 这表明模型输入预处理的 mean 和 scale 设置正确。 + +推理的 tensor 同时保存在 MODEL_DIR/inf/MODEL_DIR_QUANTIZED 文件夹中 + +- iter_0_input_1_158_out0_1_224_224_3.qnt.tensor 为原图片的 tensor +- iter_0_input_1_158_out0_1_224_224_3.tensor 为经过预处理后的模型输入 tensor +- iter_0_attach_Logits_Softmax_out0_0_out0_1_1000.tensor 为模型的输出 tensor + +```bash +. +|-- iter_0_attach_Logits_Softmax_out0_0_out0_1_1000.tensor +|-- iter_0_input_1_158_out0_1_224_224_3.qnt.tensor +`-- iter_0_input_1_158_out0_1_224_224_3.tensor + +0 directories, 3 files +``` + +### 推理 uint8 量化模型 + + + +```bash +# pegasus_inference.sh MODEL_DIR QUANTIZED ITERATION +pegasus_inference.sh MobileNetV2_Imagenet/ uint8 +``` + + + +推理结果输出为 + +```bash +I 07:02:20 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : +I 07:02:20 904: 0.8729746341705322 +I 07:02:20 530: 0.012925799004733562 +I 07:02:20 905: 0.01022859662771225 +I 07:02:20 468: 0.006405209191143513 +I 07:02:20 466: 0.005068646278232336 +``` + +:::warning +这里输出的 top5 置信度最高为 904, 这里需要注意的是 904 对应 label 是 `wig` 这与输入的图片结果并不一致, +并且与 float 类型的推理结果不一致,这意味着 uint8 量化后出现精度损失,此时可应用更高精度的量化模型,比如 **pcq** 或 **int16** 。 对于提高模型精度的方法请参考 [**混合量化**](cubie_quant_acc_improve#混合量化) +::: + +### 推理 pcq 量化模型 + + + +```bash +# pegasus_inference.sh MODEL_DIR QUANTIZED ITERATION +pegasus_inference.sh MobileNetV2_Imagenet/ pcq +``` + + + +推理结果输出为 + +```bash +I 03:36:41 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : +I 03:36:41 812: 0.9973124265670776 +I 03:36:41 814: 0.00034916045842692256 +I 03:36:41 627: 0.00010834729619091377 +I 03:36:41 833: 9.26952125155367e-05 +I 03:36:41 576: 6.784773722756654e-05 +``` + +这里输出的 top5 置信度最高为 812, 对应 label 为 `space shuttle`, 这与实际的输入图片类型吻合,且与 float 类型推理结果一致,这表明在 pcq 量化时精度正确。 + +### 推理 int16 量化模型 + + + +```bash +# pegasus_inference.sh MODEL_DIR QUANTIZED ITERATION +pegasus_inference.sh MobileNetV2_Imagenet/ int16 +``` + + + +推理结果输出为 + +```bash +I 06:54:23 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : +I 06:54:23 812: 0.9989829659461975 +I 06:54:23 814: 0.0001675251842243597 +I 06:54:23 627: 9.466391202295199e-05 +I 06:54:23 864: 6.788487371522933e-05 +I 06:54:23 536: 3.0241633794503286e-05 +``` + +这里输出的 top5 置信度最高为 812, 对应 label 为 `space shuttle`, 这与实际的输入图片类型吻合,且与 float 类型推理结果一致,这表明在 int16 量化时精度正确。 + +## 模型编译并导出 + +`pegasus_export_ovx.sh` 可以导出 NPU 推理所需的模型文件和项目代码, + +这里以 INT16 量化模型为例子 + + + +```bash +# pegasus_export_ovx.sh MODEL_DIR QUANTIZED +pegasus_export_ovx.sh MobileNetV2_Imagenet int16 +``` + + + +生成 OpenVX 项目和 NBG 项目路径: + +- MODEL_DIR/wksp/MODEL_DIR_QUANTIZED : 跨平台的 OpenVX 项目,需要硬件即时编译 (JIT) 进行模型初始化。 +- MODEL_DIR/wksp/MODEL_DIR_QUANTIZED_nbg_unify: NBG 格式,预编译机器码格式,低开销,初始化速度快。 + +```bash +(.venv) root@focal-v4l2:~/work/Acuity/acuity_examples/models/MobileNetV2_Imagenet/wksp$ ls +MobileNetV2_Imagenet_int16 MobileNetV2_Imagenet_int16_nbg_unify +``` + +:::tip +在 NBG 项目中可得到 `network_binary.nb` 模型文件。编译后的模型可复制到板端使用 vpm_run 或者 awnn API 进行板端推理 +::: + +## 使用 Vivante IDE 模拟运行推理 + +使用 Vivante IDE 可以在 X86 PC 上的 ACUITY Docker 中对生成的目标模型和 OpenVX 项目进行验证。 + +### 导入 Vivante IDE 所需环境变量 + + + +```bash +export USE_IDE_LIB=1 +export VIVANTE_SDK_DIR=~/Vivante_IDE/VivanteIDE5.11.0/cmdtools/vsimulator +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/Vivante_IDE/VivanteIDE5.11.0/cmdtools/common/lib:~/Vivante_IDE/VivanteIDE5.11.0/cmdtools/vsimulator/lib +unset VSI_USE_IMAGE_PROCESS +``` + + + +### 模拟运行跨平台 OpenVX 项目 + +#### 编译可执行文件 + + + +```bash +cd MobileNetV2_Imagenet/wksp/MobileNetV2_Imagenet_int16 +make -f makefile.linux +``` + + + +生成的目标文件为 MODEL_DIR_QUANTIZED 的二进制可执行文件。 + +#### 运行可执行文件 + + + +```bash +# Usage: ./mobilenetv2imagenetint16 data_file inputs... +./mobilenetv2imagenetint16 MobileNetV2_Imagenet_int16.export.data ../../space_shuttle_224x224.jpg +``` + + + +运行结果: + +```bash +Create Neural Network: 11ms or 11426us +Verify... +Verify Graph: 2430ms or 2430049us +Start run graph [1] times... +Run the 1 time: 229309.52ms or 229309520.00us +vxProcessGraph execution time: +Total 229309.53ms or 229309536.00us +Average 229309.53ms or 229309536.00us + --- Top5 --- +812: 0.999023 +814: 0.000146 +627: 0.000084 +864: 0.000067 + 0: 0.000000 +``` + +### 模拟运行 NBG 项目 + +:::tip +使用 Vivante IDE 运行 NBG 项目耗时会增大 +::: + +#### 编译可执行文件 + + + +```bash +cd MobileNetV2_Imagenet/wksp/MobileNetV2_Imagenet_int16_nbg_unify +make -f makefile.linux +``` + + + +生成的目标文件为 MODEL_DIR_QUANTIZED 的二进制可执行文件。 + +#### 运行可执行文件 + + + +```bash +# Usage: ./mobilenetv2imagenetint16 data_file inputs... +./mobilenetv2imagenetint16 network_binary.nb ../../space_shuttle_224x224.jpg +``` + + + +运行结果: + +```bash +Create Neural Network: 4ms or 4368us +Verify... +Verify Graph: 2ms or 2482us +Start run graph [1] times... +Run the 1 time: 229388.50ms or 229388496.00us +vxProcessGraph execution time: +Total 229388.52ms or 229388512.00us +Average 229388.52ms or 229388512.00us + --- Top5 --- +812: 0.999023 +814: 0.000146 +627: 0.000084 +864: 0.000067 + 0: 0.000000 +``` + +{/* ## 板端使用 NPU 推理模型 */} +{/* 经过模拟推理确认 OpenVX 项目或 NBG 项目可用后,可以使用交叉编译将目标项目编译成在板端执行的可执行文件。 */} + +{/* ### 导入交叉编译所需环境变量 */} +{/* ```bash */} +{/* unset USE_IDE_LIB */} +{/* unset VIVANTE_SDK_DIR */} +{/* export OVXLIB_DIR=~/work/library/acuity-root-dir/ovxlib-package-dev/arm64 */} +{/* export AQROOT=~/work/library/acuity-root-dir */} +{/* ``` */} + +{/* ### 编译项目 */} +{/* #### 编译跨平台 OpenVX 项目 */} +{/* ```bash */} +{/* cd MobileNetV2_Imagenet/wksp/MobileNetV2_Imagenet_int16 */} +{/* make -f makefile.linux */} +{/* ``` */} +{/* 生成目标文件夹 `bin_r`, 将所生成的 `bin_r` 文件夹拷贝到板端, 将 MobileNetV2_Imagenet_int16.export.data 和测试图片拷贝到板端。 */} + +{/* #### 编译 NBG 项目 */} +{/* ```bash */} +{/* cd MobileNetV2_Imagenet/wksp/MobileNetV2_Imagenet_int16_nbg_unify */} +{/* make -f makefile.linux */} +{/* ``` */} +{/* 生成目标文件夹 `bin_r`, 将所生成的 `bin_r` 文件夹拷贝到板端, 将 network_binary.nb NBG 模型和测试图片拷贝到板端。 */} + +## 板端 NPU 推理 + +板端 使用 NPU 推理 NBG 格式模型,可使用 `vpm_run` 工具进行推理测试, + +`vpm_run` 安装与使用请参考 [**vpm_run 模型测试工具**](cubie_vpm_run) + +{/* ### 板端执行 */} + +{/* #### 拷贝 ACUITY 动态库 */} +{/* 将以下 ACUITY ARM64 动态库文件夹路径拷贝到板端 */} +{/* ```bash */} +{/* library/acuity-root-dir/lib/arm64/1619b */} +{/* ``` */} + +{/* #### 导入动态库路径变量 */} +{/* 请注意修改 `ACUITY_LIB_PATH` 值为拷贝过来的 `1619b` 路径 */} +{/* ```bash */} +{/* export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ACUITY_LIB_PATH */} +{/* ``` */} + +{/* #### 运行跨平台 OpenVX 项目 */} +{/* ```bash */} +{/* root@Stark:/home/nas/MobileNetV2/openvx_bin_r# ./mobilenetv2imagenetint16 ./MobileNetV2_Imagenet_int16.export.data ../space_shuttle_224x224.jpg */} +{/* Create Neural Network: 112ms or 112315us */} +{/* Verify... */} +{/* Verify Graph: 13812ms or 13812824us */} +{/* Start run graph [1] times... */} +{/* Run the 1 time: 23.40ms or 23400.61us */} +{/* vxProcessGraph execution time: */} +{/* Total 23.50ms or 23503.09us */} +{/* Average 23.50ms or 23503.09us */} +{/* --- Top5 --- */} +{/* 812: 0.999023 */} +{/* 814: 0.000173 */} +{/* 627: 0.000109 */} +{/* 864: 0.000089 */} +{/* 0: 0.000000 */} +{/* ``` */} +{/* #### 运行 NBG 项目 */} +{/* ```bash */} +{/* root@Stark:/home/nas/MobileNetV2/NBG_bin_r# ./mobilenetv2imagenetint16 ./network_binary.nb ../space_shuttle_224x224.jpg */} +{/* Create Neural Network: 19ms or 19022us */} +{/* Verify... */} +{/* Verify Graph: 9ms or 9578us */} +{/* Start run graph [1] times... */} +{/* Run the 1 time: 22.33ms or 22325.72us */} +{/* vxProcessGraph execution time: */} +{/* Total 22.39ms or 22392.98us */} +{/* Average 22.39ms or 22392.98us */} +{/* --- Top5 --- */} +{/* 812: 0.999023 */} +{/* 814: 0.000173 */} +{/* 627: 0.000109 */} +{/* 864: 0.000089 */} +{/* 0: 0.000000 */} +{/* ``` */} diff --git a/docs/common/ai/_cubie_lenet.mdx b/docs/common/ai/_cubie_lenet.mdx new file mode 100644 index 000000000..f6e6f3381 --- /dev/null +++ b/docs/common/ai/_cubie_lenet.mdx @@ -0,0 +1,303 @@ +:::tip +本文档旨在演示如何在 Allwinner T527/A733 系列芯片上运行板端推理 LeNet 手写数字分类模型。 +::: + +主板部署 LeNet 需要两个步骤 + +- PC 端利用 [ACUITY Toolkit](./cubie_acuity_sdk#acuity-toolkit) 将不同框架下的模型转换成 NBG 格式模型 +- 板端利用 awnn API 板端推理模型 + +## 下载 ai-sdk 示例仓库 + + + +```bash +git clone https://github.com/ZIFENG278/ai-sdk.git +``` + + + +## PC 端模型转换 + +:::tip +Radxa 已提供预转换好的 `lenet.nb` 模型,用户可直接参考 [**板端推理 LeNet** ](#板端推理-lenet) 跳过 PC 端模型转换章节 +::: + +:::tip +LeNet 示例所使用的文件已经包含在[ai-sdk 示例仓库](https://github.com/ZIFENG278/ai-sdk.git)的 `models/lenet` 中 +::: + +- 进入 ACUITY Toolkit Docker 容器 + + ACUTIY Toolkit Docker 环境准备请参考 [ACUITY Toolkit 环境配置](./cubie_acuity_env) + + 配置环境变量 + + + + ```bash + cd ai-sdk/models + source env.sh v3 #NPU_VERSION + ``` + + + + A733 选择 `v3`, T527 选择 `v2` + :::tip + NPU 版本选择请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) + ::: + +- 进入 lenet 模型目录 + + + + ```bash + cd ai-sdk/models/lenet + ``` + + + +- 制作量化校准集合 + + 使用适量图片做量化校准集合,量化图片以图片路经形式保存在 `dataset.txt` + + + + ```bash + vim dataset.txt + ``` + + + + ```vim + ./input_image/6.jpg 6 + ./input_image/1.jpg 1 + ./input_image/2.jpg 2 + ./input_image/5.jpg 5 + ./input_image/3.jpg 3 + ./input_image/4.jpg 4 + ./input_image/8.jpg 8 + ./input_image/7.jpg 7 + ./input_image/0.jpg 0 + ./input_image/9.jpg 9 + ``` + +- 目录包含文件 + + ```bash + . + |-- channel_mean_value.txt + |-- dataset.txt + |-- input_image + | |-- 0.jpg + | |-- 1.jpg + | |-- 2.jpg + | |-- 3.jpg + | |-- 4.jpg + | |-- 5.jpg + | |-- 6.jpg + | |-- 7.jpg + | |-- 8.jpg + | `-- 9.jpg + |-- lenet.caffemodel + `-- lenet.prototxt + ``` + +- 解析模型 + + :::tip + pegasus 脚本在 ai-sdk/scripts 中,可复制到 models 目录中 + ::: + + 使用 `pegasus_import.sh` 将模型解析为 IR 中见表达式,会得到 `lenet.json` 包含模型结构 和 `lenet.data` 包含模型权重 + + + + ```bash + ./pegasus_import.sh lenet/ + ``` + + + +- 修改 lenet_inputmeta.yml 文件 + + 这里修改 scale 值, 根据公式 scale = 1 / std + + ```bash + scale = 1 / 255 + scale = 0.00392157 + ``` + + ```bash + input_meta: + databases: + - path: dataset.txt + type: TEXT + ports: + - lid: input_0 + category: image + dtype: float32 + sparse: false + tensor_name: + layout: nchw + shape: + - 1 + - 1 + - 28 + - 28 + fitting: scale + preprocess: + reverse_channel: true + mean: + - 0 + scale: + - 0.00392157 + preproc_node_params: + add_preproc_node: false + preproc_type: IMAGE_GRAY + # preproc_dtype_converter: + # quantizer: asymmetric_affine + # qtype: uint8 + # scale: 1.0 + # zero_point: 0 + preproc_image_size: + - 28 + - 28 + preproc_crop: + enable_preproc_crop: false + crop_rect: + - 0 + - 0 + - 28 + - 28 + preproc_perm: + - 0 + - 1 + - 2 + - 3 + redirect_to_output: false + ``` + +- 量化模型 + + 使用 `pegasus_quantize.sh` 将模型量化成 uint8 类型 + + + + ```bash + ./pegasus_quantize.sh lenet/ uint8 10 + ``` + + + +- 编译模型 + + 使用 `./pegasus_export_ovx.sh` 将模型量编译为 NBG 模型格式 + + + + ```bash + ./pegasus_export_ovx.sh lenet/ uint8 + ``` + + + + NBG 模型保存在 `lenet/wksp/lenet_uint8_nbg_unify/network_binary.nb` + +## 板端推理 LeNet + +进入 LeNet 示例代码文件目录路经 + + + +```bash +cd ai-sdk/examples/lenet +``` + + + +### 编译示例 + + + +```bash +make AI_SDK_PLATFORM=a733 +make install AI_SDK_PLATFORM=a733 INSTALL_PREFIX=./ +``` + + + +参数解析: + +`AI_SDK_PLATFORM`: 指定 SoC,可选 **`a733`**, **`t527`** + +`INSTALL_PREFIX`: 指定安装路经 + +### 运行示例 + +导入环境变量 + + + +```bash +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/NPU_VERSION # NPU_SW_VERSION +``` + + + +:::tip +指定 NPU_SW_VERSION, A733 选择 `v2.0`, T527 选择 `v1.13`, NPU 信息对照请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) +::: + +进入示例安装目录 + + + +```bash +cd INSTALL_PREFIX/etc/npu/lenet +# ./lenet nbg_model input_picture +./lenet ./model/lenet.nb ./input_data/lenet.dat +``` + + + +:::tip +示例会自动安装 radxa 提供的 lenet.nb 模型,这里可手动指定用户转换的 NBG 模型路经。 +::: + +
+ + lenet input image +
+ +```bash +(.venv) rock@radxa-cubie-a7a:~/ai-sdk/examples/lenet/etc/npu/lenet$ ./lenet ./model/network_binary.nb ./input_data/lenet.dat +./lenet nbg input +VIPLite driver software version 2.0.3.2-AW-2024-08-30 +viplite init OK. +VIPLite driver version=0x00020003... +VIP cid=0x1000003b, device_count=1 +* device[0] core_count=1 +awnn_init total: 4.07 ms. + vip_create_network ./model/network_binary.nb: 1.10 ms. +input 0 dim 28 28 1 1, data_format=2, name=input/output[0], elements=134284329, scale=0.003922, zero_point=0 +create input buffer 0: 784 +output 0 dim 10 1, data_format=1, name=uid_8_sub_uid_1_out_0, elements=10, none-quant +create output buffer 0: 20 +memory pool size=0 bytes + load_param ./model/network_binary.nb: 0.24 ms. + prepare network ./model/network_binary.nb: 0.13 ms. + set network io ./model/network_binary.nb: 0.01 ms. +awnn_create total: 1.54 ms. +memcpy(0xffffacd12000, 0xaaaada2fed20, 784) load_input_data: 0.01 ms. + vip_flush_buffer input: 0.01 ms. +awnn_set_input_buffers total: 0.04 ms. + vip_run_network: 0.22 ms. + vip_flush_buffer output: 0.00 ms. + fp16 memcpy: 0.00 ms. + tensor to fp: 0.01 ms. +awnn_run total: 0.27 ms. +0.999512 0.000000 0.000120 0.000000 0.000000 0.000163 0.000152 0.000000 0.000000 0.000082 +awnn_destroy total: 0.47 ms. +awnn_uninit total: 0.67 ms. +``` diff --git a/docs/common/ai/_cubie_nbinfo.mdx b/docs/common/ai/_cubie_nbinfo.mdx new file mode 100644 index 000000000..27d2925e8 --- /dev/null +++ b/docs/common/ai/_cubie_nbinfo.mdx @@ -0,0 +1,173 @@ +`nbinfo` 是用于分析 NBG 模型文件的 PC 端命令行工具,运行于 X86 Linux 平台。 + +`nbinfo` 针对 NBG 模型的分析内容包括: + +1. 模型输入/输出信息,包含 tensor 形状、量化参数、内存等信息; +2. 模型运行时内存分析,包含总的运存大小、系统内存大小、feature map 大小统计等等; +3. 模型各层统计分析,包含总层数、各层的运算子类型、各层的量化信息等等。 + +## NBinfo 下载 + + + +```bash +wget https://github.com/ZIFENG278/ai-sdk/raw/refs/heads/main/tools/nbinfo +``` + + + +## NBinfo 使用方法 + +```bash +Usage: nbinfo + +Options: +-a print [a]ll info +-b print [b]rief summary +-n print [n]bg header +-l print [l]ayers +-o print [o]perations +-in print [in]put +-out print [out]put +-m print [m]emory +-m -d print [m]emory, shows detail memory profile +-m -f print [m]emory, for creating network from flash project +-h [h]elp +``` + +| 选项 | 含义说明 | +| ------- | --------------------------------------------------------------------------------------------- | +| `-a` | 打印 **所有** 信息(all info) | +| `-b` | 打印 **简要** 摘要(brief summary) | +| `-n` | 打印 **nbg 文件头**(nbg header) | +| `-l` | 打印 **层** 信息(layers) | +| `-o` | 打印 **操作** 信息(operations) | +| `-in` | 打印 **输入** 信息(input) | +| `-out` | 打印 **输出** 信息(output) | +| `-m` | 打印 **内存** 信息(memory) | +| `-m -d` | 打印 **内存** 信息,并显示详细内存配置(detail memory profile) | +| `-m -f` | 打印 **内存** 信息,用于 **从 flash 项目创建网络**(for creating network from flash project) | +| `-h` | 显示 **帮助** 信息(help) | + +## NBinfo 使用示例 + +### 查看模型简要信息 + + + +```bash +nbinfo -b network_binary.nb +``` + + + +```bash +******************************************************************************** +Overall Info +******************************************************************************** +Network Name: yolov5s-sim_uint8_NCHW +Version: 0x20000 +Target: 0x1000003b +Core Count: 1 +AXI SRAM Size: 0 +VIP SRAM Size: 0x80000 +Memory Pool Size (bytes): 3892224 +Memory Pool Alignment: 64 +Layer Count: 78 +Operation Count: 1101 +Input Count: 1 +Output Count 3 +CheckSum Value: 0xd902cff2 +******************************************************************************** +``` + +### 查看模型输入信息 + + + +```bash +nbinfo -in network_binary.nb +``` + + + +```bash +******************************************************************************** +Input Table +******************************************************************************** +Input 0 +Dim Count: 4 +Size of Dim[0]: 640 +Size of Dim[1]: 640 +Size of Dim[2]: 3 +Size of Dim[3]: 1 +Data Format: VIP_BUFFER_FORMAT_UINT8 +Data Type: VIP_BUFFER_TYPE_TENSOR +Quantization Format: VIP_BUFFER_QUANTIZE_TF_ASYMM +TF Scale: 0.003922 +TF Zeropoint: 0 +Memory Size (bytes): 1228800 +input name: input/output[0] +******************************************************************************** +``` + +### 查看模型输出信息 + + + +```bash +nbinfo - network_binary.nb +``` + + + +```bash +******************************************************************************** +Output Table +******************************************************************************** +Output 0 +Dim Count: 5 +Size of Dim[0]: 85 +Size of Dim[1]: 80 +Size of Dim[2]: 80 +Size of Dim[3]: 3 +Size of Dim[4]: 1 +Data Format: VIP_BUFFER_FORMAT_UINT8 +Data Type: VIP_BUFFER_TYPE_TENSOR +Quantization Format: VIP_BUFFER_QUANTIZE_TF_ASYMM +TF Scale: 0.085919 +TF Zeropoint: 211 +Memory Size (bytes): 1632000 +output name: uid_5_out_0 +******************************************************************************** +Output 1 +Dim Count: 5 +Size of Dim[0]: 85 +Size of Dim[1]: 40 +Size of Dim[2]: 40 +Size of Dim[3]: 3 +Size of Dim[4]: 1 +Data Format: VIP_BUFFER_FORMAT_UINT8 +Data Type: VIP_BUFFER_TYPE_TENSOR +Quantization Format: VIP_BUFFER_QUANTIZE_TF_ASYMM +TF Scale: 0.071616 +TF Zeropoint: 204 +Memory Size (bytes): 408000 +output name: uid_4_out_0 +******************************************************************************** +Output 2 +Dim Count: 5 +Size of Dim[0]: 85 +Size of Dim[1]: 20 +Size of Dim[2]: 20 +Size of Dim[3]: 3 +Size of Dim[4]: 1 +Data Format: VIP_BUFFER_FORMAT_UINT8 +Data Type: VIP_BUFFER_TYPE_TENSOR +Quantization Format: VIP_BUFFER_QUANTIZE_TF_ASYMM +TF Scale: 0.072006 +TF Zeropoint: 196 +Memory Size (bytes): 102016 +output name: uid_3_out_0 +******************************************************************************** +``` diff --git a/docs/common/ai/_cubie_quant_acc_improve.mdx b/docs/common/ai/_cubie_quant_acc_improve.mdx new file mode 100644 index 000000000..ab6c2edfb --- /dev/null +++ b/docs/common/ai/_cubie_quant_acc_improve.mdx @@ -0,0 +1,148 @@ +使用 ACUITY 进行量化时,模型精度会略微损失,如果遇到精度损失过大且不满足当前项目需求时,可以使用 **Kullback-Laiber Divergence (KLD) 量化** 或者进行 **混合量化** + +如果模型精度不满足,可先使用 KLD 量化算法量化模型,再检查精度是否满足,如精度仍然不满足,再对模型进行混合量化。 + +## 使用 KLD 量化 + +要使用 KLD 量化,可在 `pegasus_quantized.sh` 中添加以下选项 + +```bash +cmd="$PEGASUS quantize \ + --model ${NAME}.json \ + --model-data ${NAME}.data \ + --iterations ${Q_ITER} \ + --device CPU \ + --with-input-meta ${NAME}_inputmeta.yml \ + --rebuild \ + --model-quantize ${NAME}_${POSTFIX}.quantize \ + --quantizer ${QUANTIZER} \ + --qtype ${QUANTIZED} \ +################################# + --algorithm kl_divergence \ + --batch-size 100 \ + --divergence-first-quantize-bits 12 + --MLE" +################################# +``` + +`--algorithm kl_divergence` 设置 KLD 量化 + +`--divergence-first-quantize-bits` 设置 2^12 KLD 直方图箱 + +`--batch-size` 设置模型量化输入数量 + +(可选)`--MLE` 如果使用 KLD 量化精度仍然不符合,可以使用 MLE 选项获得更高精度,但会增加量化耗时 + +## 混合量化 + +混合量化目的是将指定模型中的特定层使用精度较高的数据类型,其他层使用精度较低的数据类型,以保证最终结果的精度。 +如果一个量化后的模型精度无法满足需求,并且无法通过协同量化(Co-quantization)进行提升,例如 [Kullback-Laiber Divergence 量化](#使用-kld-量化),那么可以采用混合量化来避免精度损失。 + +### 混合量化例子 + +这里以上一章节的 [MobileNetV2_ImaegNet](./cubie_acuity_usage#量化模型) 的 uint8 为例子,此模型直接使用 ACUITY 进行 uint8 量化后精度损失,推理得到的结果与浮点模型存在明显精度损失。 + +MobileNetV2_ImageNet 在经过 uint8 直接量化后与浮点模型的结果对比 + +- float 模型推理结果 + ```bash + I 07:01:06 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : + I 07:01:06 812: 0.9990391731262207 + I 07:01:06 814: 0.0001562383840791881 + I 07:01:06 627: 8.89502334757708e-05 + I 07:01:06 864: 6.59249781165272e-05 + I 07:01:06 536: 2.808812860166654e-05 + ``` +- uint8 模型推理结果 + ```bash + I 07:02:20 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : + I 07:02:20 904: 0.8729746341705322 + I 07:02:20 530: 0.012925799004733562 + I 07:02:20 905: 0.01022859662771225 + I 07:02:20 468: 0.006405209191143513 + I 07:02:20 466: 0.005068646278232336 + ``` + +### 进行混合量化 + +#### 统计需要混合量化的层 + +在量化脚本 `pegasus_quantized.sh` 中添加 `--compute-entropy` 参数 + +```bash +cmd="$PEGASUS quantize \ + --model ${NAME}.json \ + --model-data ${NAME}.data \ + --iterations ${Q_ITER} \ + --device CPU \ + --with-input-meta ${NAME}_inputmeta.yml \ + --rebuild \ + --model-quantize ${NAME}_${POSTFIX}.quantize \ + --quantizer ${QUANTIZER} \ + --qtype ${QUANTIZED} \ +################################# + --compute-entropy" +################################# +``` + + + +```bash +# pegasus_quantize.sh MODEL_DIR QUANTIZED ITERATION +pegasus_quantize.sh MobileNetV2_Imagenet uint8 10 +``` + + + +执行量化脚本 `pegasus_quantize.sh` 后会生成 `MODEL_DIR_QUANTIZE.quantize` 和 `entropy.txt` + +- MODEL_DIR_QUANTIZE.quantize 文件包含量化模型的数据, 其中 customized_quantize_layers 里的层为自动统计出需要使用混合量化的层 +- entropy.txt 记录每一层在此次量化中的熵值。 熵值越高,量化精度越低。范围为 [0, 1]。 + +用户可以参考 `entropy.txt` 的值对 MODEL_DIR_QUANTIZE.quantize 中的 customized_quantize_layers 里的层适当进行增删修改。 + +#### 执行混合量化命令 + +:::tip +量化命令在执行 pegasus_quantized.sh 时会在顶部打印量化命令, 将 `--rebuild` 替换为 `--hybrid` 即可 +::: + + + +```bash +python3 ~/acuity-toolkit-whl-6.30.22/bin/pegasus.py quantize --model MobileNetV2_Imagenet.json --model-data MobileNetV2_Imagenet.data --iterations 1 --device CPU --with-input-meta MobileNetV2_Imagenet_inputmeta.yml --hybrid --model-quantize MobileNetV2_Imagenet_uint8.quantize --quantizer asymmetric_affine --qtype uint8 --compute-entropy +``` + + + +命令执行完后会更新 ACUITY 模型权重 `.data` 文件,和生成新的 ACUITY 模型结构 `quantize.json` 文件。 + +### 混合量化结果 + +执行完混合量化后,使用 pegasus_inference.sh 进行 uint8 混合量化模型的推理 + +因为混合量化后模型结构发生改变, 请先修改 `pegasus_inference.sh` 中 `--model` 参数为新的 ACUITY 模型结构 `quantize.json` 文件 + + + +```bash +# pegasus_inference.sh MODEL_DIR QUANTIZED ITERATION +pegasus_inference.sh MobileNetV2_Imagenet/ uint8 +``` + + + +推理输出结果为 + +```bash +I 04:00:10 Iter(0), top(5), tensor(@attach_Logits/Softmax/out0_0:out0) : +I 04:00:10 812: 0.9987972974777222 +I 04:00:10 404: 0.0001131662429543212 +I 04:00:10 814: 6.176823808345944e-05 +I 04:00:10 627: 4.6059416490606964e-05 +I 04:00:10 833: 4.153002373641357e-05 +``` + +此时经过混合量化后的模型,在推理完成后打印的 Top5 结果中,812 置信度最高且置信度达 0.998,这与浮点模型的结果一致,证明混合量化后的 uint8 模型已成功减少模型精度损失。 + +接下来可以继续 NPU 的部署工作进行 [模型编译并导出](./cubie_acuity_usage#模型编译并导出), **因为混合量化后模型结构发生改变,在进行模型转换时请使用混合量化生成的 ACUITY 模型结构 `quantize.json` 文件名作为 `--model` 参数**。 diff --git a/docs/common/ai/_cubie_resnet50.mdx b/docs/common/ai/_cubie_resnet50.mdx new file mode 100644 index 000000000..effb33156 --- /dev/null +++ b/docs/common/ai/_cubie_resnet50.mdx @@ -0,0 +1,359 @@ +:::tip +本文档旨在演示如何在 Allwinner T527/A733 系列芯片上运行板端推理 ResNet50 物体分类模型。 +::: + +此示例用 [resnet50-v2-7.onnx](https://github.com/onnx/models/blob/main/validated/vision/classification/resnet/model/resnet50-v2-7.onnx) 中预训练好的 ONNX 格式模型为例子通过模型转换到板端推理做完整示例。 + +主板部署 ResNet50 需要两个步骤 + +- PC 端利用 [ACUITY Toolkit](./cubie_acuity_sdk#acuity-toolkit) 将不同框架下的模型转换成 NBG 格式模型 +- 板端利用 awnn API 板端推理模型 + +## 下载 ai-sdk 示例仓库 + + + +```bash +git clone https://github.com/ZIFENG278/ai-sdk.git +``` + + + +## PC 端模型转换 + +:::tip +Radxa 已提供预转换好的 `resnet50.nb` 模型,用户可直接参考 [**板端推理 ResNet50** ](#板端推理-resnet50) 跳过 PC 端模型转换章节 +::: + +- 进入 ACUITY Toolkit Docker 容器 + + ACUTIY Toolkit Docker 环境准备请参考 [ACUITY Toolkit 环境配置](./cubie_acuity_env) + + 配置环境变量 + + + + ```bash + cd ai-sdk/models + source env.sh v3 #NPU_VERSION + ``` + + + + A733 选择 `v3`, T527 选择 `v2` + :::tip + NPU 版本选择请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) + ::: + +- 下载 resnet50 onnx 模型 + + + + ```bash + mkdir resnet50-sim && cd resnet50-sim + wget https://github.com/onnx/models/raw/refs/heads/main/validated/vision/classification/resnet/model/resnet50-v2-7.onnx -O resnet50.onnx + ``` + + + +- 固定输入 + + 使用 NPU 推理仅接受固定输入尺寸,这里使用 onnxsim 进行输入固定 + + + + ```bash + pip3 install onnxsim onnxruntime + onnxsim resnet50.onnx resnet50-sim.onnx --overwrite-input-shape 1,3,224,224 + ``` + + + +- 制作量化校准集合 + + 使用适量图片做量化校准集合,量化图片以图片路经形式保存在 `dataset.txt` + + + + ```bash + vim dataset.txt + ``` + + + + ```vim + ./space_shuttle_224x224.jpg + ``` + + ![space_shuttle](/img/e/e54c/rs400_npu_3.webp) + +- 制作模型输入输出文件 + + 可使用 [netron](https://netron.app/) 确认 onnx 模型输入输出的名字 + + + + ```bash + vim inputs_outputs.txt + ``` + + + + ```vim + --inputs data --input-size-list '3,224,224' --outputs 'resnetv24_dense0_fwd' + ``` + + {" "} + +
+ + resnet50 in/output name +
+ +- 目录包含文件 + + ```bash + . + |-- dataset.txt + |-- inputs_outputs.txt + |-- resnet50-sim.onnx + |-- resnet50.onnx + `-- space_shuttle_224x224.jpg + ``` + +- 解析模型 + + :::tip + pegasus 脚本在 ai-sdk/scripts 中,可复制到 models 目录中 + ::: + + 使用 `pegasus_import.sh` 将模型解析为 IR 中见表达式,会得到 `resnet50-sim.json` 包含模型结构 和 `resnet50-sim.data` 包含模型权重 + + + + ```bash + ./pegasus_import.sh resnet50-sim/ + ``` + + + +- 修改 resnet50-sim_inputmeta.yml 文件 + + 因为训练数据集为 ImageNet, 这里 ImageNet 训练集的归一化 mean 为 [0.485, 0.456, 0.406],std 为 [0.229, 0.224, 0.225], + 这里需要进行进行反归一化计算。归一化数据参考 [pytorch 文档](https://docs.pytorch.org/vision/main/models/generated/torchvision.models.mobilenet_v2.html) + + ```bash + # mean + 0.485 * 255 = 123.675 + 0.456 * 255 = 116.28 + 0.406 * 255 = 103.53 + ``` + + ```bash + # scale + 1 / (0.229 * 255) = 0.01712 + 1 / (0.224 * 255) = 0.01751 + 1 / (0.225 * 255) = 0.01743 + ``` + + 这里按照计算得出 mean 和 scale 修改 `resnet50-sim_inputmeta.yml` 中 mean 和 scale 的数值: + + ```vim + mean: + - 123.675 + - 116.28 + - 103.53 + scale: + - 0.01712 + - 0.01751 + - 0.01743 + ``` + + ```bash + input_meta: + databases: + - path: dataset.txt + type: TEXT + ports: + - lid: data_142 + category: image + dtype: float32 + sparse: false + tensor_name: + layout: nchw + shape: + - 1 + - 3 + - 224 + - 224 + fitting: scale + preprocess: + reverse_channel: true + mean: + - 123.675 + - 116.28 + - 103.53 + scale: + - 0.01712 + - 0.01751 + - 0.01743 + preproc_node_params: + add_preproc_node: false + preproc_type: IMAGE_RGB + # preproc_dtype_converter: + # quantizer: asymmetric_affine + # qtype: uint8 + # scale: 1.0 + # zero_point: 0 + preproc_image_size: + - 224 + - 224 + preproc_crop: + enable_preproc_crop: false + crop_rect: + - 0 + - 0 + - 224 + - 224 + preproc_perm: + - 0 + - 1 + - 2 + - 3 + redirect_to_output: false + ``` + +- 量化模型 + + 使用 `pegasus_quantize.sh` 将模型量化成 uint8 类型 + + + + ```bash + ./pegasus_quantize.sh resnet50-sim/ uint8 10 + ``` + + + +- 编译模型 + + 使用 `./pegasus_export_ovx.sh` 将模型量编译为 NBG 模型格式 + + + + ```bash + ./pegasus_export_ovx.sh resnet50-sim/ uint8 + ``` + + + + NBG 模型保存在 `resnet50-sim/wksp/resnet50-sim_uint8_nbg_unify/network_binary.nb` + +## 板端推理 ResNet50 + +进入 resnet50 示例代码文件目录路经 + + + +```bash +cd ai-sdk/examples/resnet50 +``` + + + +### 编译示例 + + + +```bash +make AI_SDK_PLATFORM=a733 +make install AI_SDK_PLATFORM=a733 INSTALL_PREFIX=./ +``` + + + +参数解析: + +`AI_SDK_PLATFORM`: 指定 SoC,可选 **`a733`**, **`t527`** + +`INSTALL_PREFIX`: 指定安装路经 + +### 运行示例 + +导入环境变量 + + + +```bash +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/NPU_VERSION # NPU_SW_VERSION +``` + + + +:::tip +指定 NPU_SW_VERSION, A733 选择 `v2.0`, T527 选择 `v1.13`, NPU 信息对照请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) +::: + +进入示例安装目录 + + + +```bash +cd INSTALL_PREFIX/etc/npu/resnet50 +# ./resnet50 nbg_model input_picture +./resnet50 model/resnet50.nb ./input_data/dog_224_224.jpg +``` + + + +:::tip +示例会自动安装 radxa 提供的 resnet50.nb 模型,这里可手动指定用户转换的 NBG 模型路经。 +::: + +
+ + resnet50 demo input image +
+ +```bash +(.venv) rock@radxa-cubie-a7a:~/ai-sdk/examples/resnet50/etc/npu/resnet50$ ./resnet50 ./model/network_binary.nb ./input_data/dog_224_224.jpg +./resnet50 nbg input +VIPLite driver software version 2.0.3.2-AW-2024-08-30 +viplite init OK. +VIPLite driver version=0x00020003... +VIP cid=0x1000003b, device_count=1 +* device[0] core_count=1 +awnn_init total: 4.47 ms. + vip_create_network ./model/network_binary.nb: 13.10 ms. +input 0 dim 224 224 3 1, data_format=2, name=input/output[0], elements=1833508979, scale=0.018657, zero_point=113 +create input buffer 0: 150528 +output 0 dim 1000 1, data_format=2, name=uid_1_out_0, elements=1000, scale=0.131327, zero_point=44 +create output buffer 0: 1000 +memory pool size=1606656 bytes + load_param ./model/network_binary.nb: 0.19 ms. + prepare network ./model/network_binary.nb: 2.58 ms. + set network io ./model/network_binary.nb: 0.01 ms. +awnn_create total: 15.93 ms. +get jpeg success. +trans data success. +memcpy(0xffff96348000, 0xffff96162010, 150528) load_input_data: 0.04 ms. + vip_flush_buffer input: 0.01 ms. +awnn_set_input_buffers total: 0.06 ms. +awnn_set_input_buffers success. + vip_run_network: 8.30 ms. + vip_flush_buffer output: 0.01 ms. + int8/uint8 1000 memcpy: 0.00 ms. + tensor to fp: 0.02 ms. +awnn_run total: 8.35 ms. +awnn_run success. +class_postprocess.cpp run. +========== top5 ========== +class id: 231, prob: 13.395374, label: collie +class id: 230, prob: 12.082102, label: Shetland sheepdog, Shetland sheep dog, Shetland +class id: 169, prob: 10.900157, label: borzoi, Russian wolfhound +class id: 160, prob: 8.930249, label: Afghan hound, Afghan +class id: 224, prob: 7.222996, label: groenendael +class_postprocess success. +awnn_destroy total: 1.47 ms. +awnn_uninit total: 0.70 ms. +``` diff --git a/docs/common/ai/_cubie_vpm_run.mdx b/docs/common/ai/_cubie_vpm_run.mdx new file mode 100644 index 000000000..073d4cedb --- /dev/null +++ b/docs/common/ai/_cubie_vpm_run.mdx @@ -0,0 +1,161 @@ +:::tip +本文档旨在演示如何在 Allwinner T527/A733 系列芯片上运行模型测试工具 `vpm_run`。 +::: + +vpm_run 是一个基于 VIPLite 驱动的端侧程序,主要用于快速验证模型文件和测试。 + +- vpm_run 可作为一个通用的模型运行环境,可运行任何部署正确的 NBG 模型文件。 +- vpm_run 基于 VIPLite 网络层 API。 +- vpm_run 具备默认的后处理程序 TOP5。 + +## 下载 ai-sdk 示例仓库 + + + +```bash +git clone https://github.com/ZIFENG278/ai-sdk.git +``` + + + +## 板端使用 vpm_run + +进入 vpm_run 示例代码文件目录路经 + + + +```bash +cd ai-sdk/examples/vpm_run +``` + + + +### 编译示例 + + + +```bash +make AI_SDK_PLATFORM=a733 +make install AI_SDK_PLATFORM=a733 INSTALL_PREFIX=./ +``` + + + +参数解析: + +`AI_SDK_PLATFORM`: 指定 SoC,可选 **`a733`**, **`t527`** + +`INSTALL_PREFIX`: 指定安装路经 + +使用方法 + +```bash +vpm_run -s sample.txt -l loop_run_count -d device_index +-s sample.txt: to include one ore more network binary graph (NBG) data file resource. + See sample.txt for details. +-l loop_run_count: the number of loop run network. +-d device_index: specify this NBG runs device. +-t time_out: specify milliseconds time out of network. +-b bypass_level: set value 1 to bypass saving output txt/binary file and showing top5. +--show_top5 level: set value 1 to show top5 when bypass_level is 0. +--save_txt level: set value 1 to save txt output when bypass_level is 0. +-c core_index: specify this start core index of device. +--layer_profile_dump: set value 1 to enable NPD function. +--preload: set value 1 to enable preload coeff into vipsram. +--op_segment: set which operations will be run. example: --op_segment 10,20 means run 10 ~ 20 +--layer_dump: layer dump. eg: --layer_dump -1 dump all layer, --layer_dump 19, --layer_dump 18,20 +-h : help +example: ./vpm_run -s sample.txt -l 10 -d 1 specify the NBG runs 10 times on device 1. +``` + +### 运行示例 + +- 导入环境变量 + + + + ```bash + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/NPU_VERSION # NPU_SW_VERSION + ``` + + + + :::tip + 指定 NPU_SW_VERSION, A733 选择 `v2.0`, T527 选择 `v1.13`, NPU 信息对照请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) + ::: + +- 制作配置文件 + + 此示例配置文件执行两个 NGB 模型,第一个是多输入模型,保存输出文件,且与 golden 进行对比,第二个是单输入模型, 不保存输出文件。 + + ```vim + [network] + ./network_binary.nb + [input] + #多输入模型,则配置多个输入文件;单输入模型,则配置1个输入文件。 + ./input_0.dat + ./input_1.dat + [golden] + #可选 + ./int8_output_003.dat + [output] + #可选 + ./output_0.dat + + [network] + ./network_binary_single.nb + [input] + ./input1.tensor + ``` + + sample.txt 文件的示例如上所示,主要标签介绍如下: + + - **[network]**:NBG 文件的路径。 + - **[input]**:输入数据的路径。输入数据的格式支持两种:Acuity Toolkits 工具 inference 阶段生成的 input.tensor 文件;IDE 工具仿真阶段生成的 input.dat 文件。 + - **[golden]**:可选的 golden 数据的路径。如果存在 golden 标签,将其作为 golden 数据和 vpm_run 运行输出的 tensor 做 binary 比对,比对一致打印 pass,比对不一致将退出 vpm_run。 + - **[output]**:可选的。输出数据的保存路径。 + +- 进入示例安装目录 + + + + ```bash + cd INSTALL_PREFIX/etc/npu/vpm_ru + ./vpm_run -s sample.txt -l 1 + ``` + + + + ```bash + (.venv) rock@radxa-cubie-a7a:~/ai-sdk/examples/vpm_run/etc/npu/vpm_run$ ./vpm_run -s sample.txt -l 1 + loop_count=1, device_index=0, core_index=-1, file_name=sample.txt, time_out=0x0, bypass=1 + enable_npd=0, preload=0 + show_top50, save_txt=0 + init vip lite, driver version=0x00020003... + VIPLite driver software version 2.0.3.2-AW-2024-08-30 + vip lite init OK. + + cid=0x1000003b, device_count=1 + device[0] core_count=1 + config file read network count=1 + init test resources, task_count: 1 ... + create/prepare networks ... + task i=0, binary name: ./network_binary.nb + nbg name=./network_binary.nb + create network 0: 12354 us. + input 0 dim 3 224 224 1, data_format=5, quant_format=1, name=input/output[0], dfp=13 + output 0 dim 1000 1 0 0, data_format=1, name=uid_2_sub_uid_1_out_0, none-quant + memory pool size=1073536byte + network core count=1 + prepare network 0: 1409 us. + golden file count=0 + input 0 name: ./input_0.dat + read input and golden 0: 541 us. + task: 0, loop count: 1 + start to run network=./network_binary.nb + run time for this network 0: 3160 us. + run network done... + profile inference time=2945us, cycle=2916338 + destroy test resource task_count=1 + vpm run ret=0 + ``` diff --git a/docs/common/ai/_cubie_yolact.mdx b/docs/common/ai/_cubie_yolact.mdx new file mode 100644 index 000000000..3106b147a --- /dev/null +++ b/docs/common/ai/_cubie_yolact.mdx @@ -0,0 +1,130 @@ +:::tip +本文档旨在演示如何在 Allwinner T527/A733 系列芯片上运行板端推理 YOLACT 物体分割模型。 +::: + +主板部署 YOLACT 需要两个步骤 + +- PC 端利用 [ACUITY Toolkit](./cubie_acuity_sdk#acuity-toolkit) 将不同框架下的模型转换成 NBG 格式模型 +- 板端利用 awnn API 板端推理模型 + +## 下载 ai-sdk 示例仓库 + + + +```bash +git clone https://github.com/ZIFENG278/ai-sdk.git +``` + + + +## 板端推理 YOLACT + +进入 YOLACT 示例代码文件目录路经 + + + +```bash +cd ai-sdk/examples/yolact +``` + + + +### 编译示例 + + + +```bash +make AI_SDK_PLATFORM=a733 +make install AI_SDK_PLATFORM=a733 INSTALL_PREFIX=./ +``` + + + +参数解析: + +`AI_SDK_PLATFORM`: 指定 SoC,可选 **`a733`**, **`t527`** + +`INSTALL_PREFIX`: 指定安装路经 + +### 运行示例 + +- 导入环境变量 + + + +```bash +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/NPU_VERSION # NPU_SW_VERSION +``` + + + +:::tip +指定 NPU_SW_VERSION, A733 选择 `v2.0`, T527 选择 `v1.13`, NPU 信息对照请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) +::: + +进入示例安装目录 + + + +```bash +cd INSTALL_PREFIX/etc/npu/yolact +# ./yolact nbg_model input_picture +./yolact ./model/yolact.nb ./input_data/dog_550_550.jpg +``` + + + +:::tip +示例会自动安装 radxa 提供的 yolact.nb 模型,这里可手动指定用户转换的 NBG 模型路经。 +::: + +```bash +(.venv) rock@radxa-cubie-a7a:~/ai-sdk/examples/yolact/etc/npu/yolact$ ./yolact ./model/yolact.nb ./input_data/dog_550_550.jpg +./yolact nbg input +VIPLite driver software version 2.0.3.2-AW-2024-08-30 +viplite init OK. +VIPLite driver version=0x00020003... +VIP cid=0x1000003b, device_count=1 +* device[0] core_count=1 +awnn_init total: 3.75 ms. + vip_create_network ./model/yolact.nb: 17.04 ms. +input 0 dim 550 550 3 1, data_format=2, name=input/output[0], elements=1833508979, scale=0.018629, zero_point=114 +create input buffer 0: 907500 +output 0 dim 4 19248 1, data_format=2, name=uid_9_out_0, elements=76992, scale=0.057314, zero_point=142 +create output buffer 0: 76992 +output 1 dim 81 19248 1, data_format=1, name=uid_8_sub_uid_1_out_0, elements=1559088, none-quant +create output buffer 1: 3118176 +output 2 dim 32 19248 1, data_format=1, name=uid_7_out_0, elements=615936, none-quant +create output buffer 2: 1231872 +output 3 dim 4 19248, data_format=1, name=uid_6_sub_uid_1_out_0, elements=76992, none-quant +create output buffer 3: 153984 +output 4 dim 32 138 138 1, data_format=2, name=uid_239_out_0, elements=609408, scale=0.065950, zero_point=0 +create output buffer 4: 609408 +memory pool size=15062336 bytes + load_param ./model/yolact.nb: 3.10 ms. + prepare network ./model/yolact.nb: 12.38 ms. + set network io ./model/yolact.nb: 0.01 ms. +awnn_create total: 32.61 ms. +memcpy(0xffff78e62000, 0xffff76df8010, 907500) load_input_data: 0.25 ms. + vip_flush_buffer input: 0.01 ms. +awnn_set_input_buffers total: 0.29 ms. + vip_run_network: 97.06 ms. + vip_flush_buffer output: 0.02 ms. + int8/uint8 76992 memcpy: 0.18 ms. + fp16 memcpy: 7.48 ms. + fp16 memcpy: 1.77 ms. + fp16 memcpy: 0.17 ms. + int8/uint8 609408 memcpy: 0.66 ms. + tensor to fp: 52.01 ms. +awnn_run total: 149.16 ms. +2 = 0.99268 at 88.14 115.14 327.19 x 302.04 +8 = 0.87305 at 339.16 71.52 158.58 x 87.82 +17 = 0.75830 at 89.21 215.20 132.53 x 301.23 +awnn_destroy total: 3.74 ms. +awnn_uninit total: 0.71 ms. +``` + +
+ + yolact demo result +
diff --git a/docs/common/ai/_cubie_yolov5.mdx b/docs/common/ai/_cubie_yolov5.mdx new file mode 100644 index 000000000..dbf900e21 --- /dev/null +++ b/docs/common/ai/_cubie_yolov5.mdx @@ -0,0 +1,351 @@ +:::tip +本文档旨在演示如何在 Allwinner T527/A733 系列芯片上运行板端推理 YOLOv5 物体检测模型。 +::: + +此示例用 [ultralytics/yolov5](https://github.com/ultralytics/yolov5/releases/tag/v6.0) 中预训练好的 ONNX 格式模型为例子通过模型转换到板端推理做完整示例。 + +主板部署 YOLOv5 需要两个步骤 + +- PC 端利用 [ACUITY Toolkit](./cubie_acuity_sdk#acuity-toolkit) 将不同框架下的模型转换成 NBG 格式模型 +- 板端利用 awnn API 板端推理模型 + +## 下载 ai-sdk 示例仓库 + + + +```bash +git clone https://github.com/ZIFENG278/ai-sdk.git +``` + + + +## PC 端模型转换 + +:::tip +Radxa 已提供预转换好的 `yolov5.nb` 模型,用户可直接参考 [**板端推理 YOLOv5** ](#板端推理-yolov5) 跳过 PC 端模型转换章节 +::: + +:::tip +yolov5 示例所使用的文件已经包含在[ai-sdk 示例仓库](https://github.com/ZIFENG278/ai-sdk.git)的 `models/yolov5s-sim` 中 +::: + +- 进入 ACUITY Toolkit Docker 容器 + + ACUTIY Toolkit Docker 环境准备请参考 [ACUITY Toolkit 环境配置](./cubie_acuity_env) + + 配置环境变量 + + + + ```bash + cd ai-sdk/models + source env.sh v3 #NPU_VERSION + ``` + + + + A733 选择 `v3`, T527 选择 `v2` + :::tip + NPU 版本选择请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) + ::: + +- 下载 yolov5s onnx 模型 + + + + ```bash + mkdir yolov5s-sim && cd yolov5s-sim + wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx + ``` + + + +- 固定输入 + + 使用 NPU 推理仅接受固定输入尺寸,这里使用 onnxsim 进行输入固定 + + + + ```bash + pip3 install onnxsim onnxruntime + onnxsim yolov5s.onnx yolov5s-sim.onnx --overwrite-input-shape 1,3,640,640 + ``` + + + +- 制作量化校准集合 + + 使用适量图片做量化校准集合,量化图片以图片路经形式保存在 `dataset.txt` + + + + ```bash + vim dataset.txt + ``` + + + + ```vim + images/COCO_train2014_000000000529.jpg + images/COCO_train2014_000000001183.jpg + images/COCO_train2014_000000002349.jpg + images/COCO_train2014_000000003685.jpg + images/COCO_train2014_000000004463.jpg + images/dog.jpg + ``` + +- 制作模型输入输出文件 + + 可使用 [netron](https://netron.app/) 确认 onnx 模型输入输出的名字 + + + + ```bash + vim inputs_outputs.txt + ``` + + + + ```vim + --inputs images --input-size-list '3,640,640' --outputs '350 498 646' + ``` + + {" "} + +
+ + yolov5s in/output name +
+ +- 目录包含文件 + + ```bash + . + |-- dataset.txt + |-- images + | |-- COCO_train2014_000000000529.jpg + | |-- COCO_train2014_000000001183.jpg + | |-- COCO_train2014_000000002349.jpg + | |-- COCO_train2014_000000003685.jpg + | |-- COCO_train2014_000000004463.jpg + | `-- dog.jpg + |-- inputs_outputs.txt + |-- yolov5s-sim.onnx + ``` + +- 解析模型 + + :::tip + pegasus 脚本在 ai-sdk/scripts 中,可复制到 models 目录中 + ::: + + 使用 `pegasus_import.sh` 将模型解析为 IR 中见表达式,会得到 `yolov5s-sim.json` 包含模型结构 和 `yolov5s-sim.data` 包含模型权重 + + + + ```bash + ./pegasus_import.sh yolov5s-sim/ + ``` + + + +- 修改 yolov5s-sim_inputmeta.yml 文件 + + 这里修改 scale 值, 根据公式 scale = 1 / std + + ```bash + scale = 1 / 255 + scale = 0.00392157 + ``` + + ```bash + input_meta: + databases: + - path: dataset.txt + type: TEXT + ports: + - lid: images_208 + category: image + dtype: float32 + sparse: false + tensor_name: + layout: nchw + shape: + - 1 + - 3 + - 640 + - 640 + fitting: scale + preprocess: + reverse_channel: true + mean: + - 0 + - 0 + - 0 + scale: + - 0.00392157 + - 0.00392157 + - 0.00392157 + preproc_node_params: + add_preproc_node: false + preproc_type: IMAGE_RGB + # preproc_dtype_converter: + # quantizer: asymmetric_affine + # qtype: uint8 + # scale: 1.0 + # zero_point: 0 + preproc_image_size: + - 640 + - 640 + preproc_crop: + enable_preproc_crop: false + crop_rect: + - 0 + - 0 + - 640 + - 640 + preproc_perm: + - 0 + - 1 + - 2 + - 3 + redirect_to_output: false + ``` + +- 量化模型 + + 使用 `pegasus_quantize.sh` 将模型量化成 uint8 类型 + + + + ```bash + ./pegasus_quantize.sh yolov5s-sim/ uint8 10 + ``` + + + +- 编译模型 + + 使用 `./pegasus_export_ovx.sh` 将模型量编译为 NBG 模型格式 + + + + ```bash + ./pegasus_export_ovx.sh yolov5s-sim/ uint8 + ``` + + + + NBG 模型保存在 `yolov5s-sim/wksp/yolov5s-sim_uint8_nbg_unify/network_binary.nb` + +## 板端推理 YOLOv5 + +进入 yolov5 示例代码文件目录路经 + + + +```bash +cd ai-sdk/examples/yolov5 +``` + + + +### 编译示例 + + + +```bash +make AI_SDK_PLATFORM=a733 +make install AI_SDK_PLATFORM=a733 INSTALL_PREFIX=./ +``` + + + +参数解析: + +`AI_SDK_PLATFORM`: 指定 SoC,可选 **`a733`**, **`t527`** + +`INSTALL_PREFIX`: 指定安装路经 + +### 运行示例 + +导入环境变量 + + + +```bash +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/NPU_VERSION # NPU_SW_VERSION +``` + + + +:::tip +指定 NPU_SW_VERSION, A733 选择 `v2.0`, T527 选择 `v1.13`, NPU 信息对照请参考 [NPU 版本对照表](./cubie_acuity_usage#npu-版本对照表) +::: + +进入示例安装目录 + + + +```bash +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/NPU_VERSION # NPU_SW_VERSION +cd INSTALL_PREFIX/etc/npu/yolov5 +# ./yolov5 nbg_model input_picture +./yolov5 ./model/yolov5.nb ./input_data/dog.jpg +``` + + + +:::tip +示例会自动安装 radxa 提供的 yolov5.nb 模型,这里可手动指定用户转换的 NBG 模型路经。 +::: + +```bash +(.venv) rock@radxa-cubie-a7a:~/ai-sdk/examples/yolov5/etc/npu/yolov5$ ./yolov5 ./model/network_binary.nb ./input_data/dog.jpg +./yolov5 nbg input +VIPLite driver software version 2.0.3.2-AW-2024-08-30 +viplite init OK. +VIPLite driver version=0x00020003... +VIP cid=0x1000003b, device_count=1 +* device[0] core_count=1 +awnn_init total: 5.49 ms. + vip_create_network ./model/network_binary.nb: 3.96 ms. +input 0 dim 640 640 3 1, data_format=2, name=input/output[0], elements=1833508979, scale=0.003922, zero_point=0 +create input buffer 0: 1228800 +output 0 dim 85 80 80 3 1, data_format=2, name=uid_5_out_0, elements=1632000, scale=0.085919, zero_point=211 +create output buffer 0: 1632000 +output 1 dim 85 40 40 3 1, data_format=2, name=uid_4_out_0, elements=408000, scale=0.071616, zero_point=204 +create output buffer 1: 408000 +output 2 dim 85 20 20 3 1, data_format=2, name=uid_3_out_0, elements=102000, scale=0.072006, zero_point=196 +create output buffer 2: 102000 +memory pool size=3892224 bytes + load_param ./model/network_binary.nb: 0.97 ms. + prepare network ./model/network_binary.nb: 2.56 ms. + set network io ./model/network_binary.nb: 0.01 ms. +awnn_create total: 7.55 ms. +yolov5_preprocess.cpp run. +memcpy(0xffff89621000, 0xffff886f8010, 1228800) load_input_data: 0.33 ms. + vip_flush_buffer input: 0.02 ms. +awnn_set_input_buffers total: 0.38 ms. + vip_run_network: 17.07 ms. + vip_flush_buffer output: 0.01 ms. + int8/uint8 1632000 memcpy: 2.72 ms. + int8/uint8 408000 memcpy: 0.46 ms. + int8/uint8 102000 memcpy: 0.11 ms. + tensor to fp: 28.64 ms. +awnn_run total: 45.75 ms. +yolov5_postprocess.cpp run. +detection num: 3 +16: 86%, [ 130, 222, 312, 546], dog + 7: 59%, [ 469, 78, 692, 171], truck + 1: 53%, [ 158, 133, 560, 424], bicycle +awnn_destroy total: 1.95 ms. +awnn_uninit total: 0.66 ms. +``` + +推理结果保存在 result.png 中 + +
+ + yolov5s demo output +
diff --git a/docs/common/radxa-os/application-dev/mediapipe-dev/_example.mdx b/docs/common/radxa-os/application-dev/mediapipe-dev/_example.mdx new file mode 100644 index 000000000..e8da9cd09 --- /dev/null +++ b/docs/common/radxa-os/application-dev/mediapipe-dev/_example.mdx @@ -0,0 +1,572 @@ +主要介绍 MediaPipe 的人脸检测、手掌检测、骨骼检测、整体检测、背景分割、3D 对象检测等示例。 + +:::tip +参考资料: + +- [MediaPipe 官方网站](https://github.com/google/mediapipe) +- [MediaPipe 参考示例](https://chuoling.github.io/mediapipe/) + ::: + +## 人脸检测 + +读取摄像头画面并进行人脸检测,在检测出来的人脸上绘制方框。 + +运行案例步骤: + +1. 新建 `face_detection.py` 文件 +2. 将代码复制到 `face_detection.py` 文件 +3. 使用 `python3 face_detection.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+face_detection.py + +``` +#!/usr/bin/env python3 +# -_- encoding: utf-8 -_- + +import cv2 +import mediapipe as mp +mp_face_detection = mp.solutions.face_detection +mp_drawing = mp.solutions.drawing_utils + +cap = cv2.VideoCapture(0) +with mp_face_detection.FaceDetection( +model_selection=0, min_detection_confidence=0.5) as face_detection: +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. +continue + + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + results = face_detection.process(image) + + # Draw the face detection annotations on the image. + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + if results.detections: + for detection in results.detections: + mp_drawing.draw_detection(image, detection) + # Flip the image horizontally for a selfie-view display. + cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1)) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 人脸面具 + +读取摄像头画面并进行人脸检测,在检测出来的人脸上贴上面具。 + +运行案例步骤: + +1. 新建 `face_mesh.py` 文件 +2. 将代码复制到 `face_mesh.py` 文件 +3. 使用 `python3 face_mesh.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+face_mesh.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import mediapipe as mp +mp_drawing = mp.solutions.drawing_utils +mp_drawing_styles = mp.solutions.drawing_styles +mp_face_mesh = mp.solutions.face_mesh + +drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1) +cap = cv2.VideoCapture(0) +with mp_face_mesh.FaceMesh( +max_num_faces=1, +refine_landmarks=True, +min_detection_confidence=0.5, +min_tracking_confidence=0.5) as face_mesh: +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. +continue + + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + results = face_mesh.process(image) + + # Draw the face mesh annotations on the image. + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + if results.multi_face_landmarks: + for face_landmarks in results.multi_face_landmarks: + mp_drawing.draw_landmarks( + image=image, + landmark_list=face_landmarks, + connections=mp_face_mesh.FACEMESH_TESSELLATION, + landmark_drawing_spec=None, + connection_drawing_spec=mp_drawing_styles + .get_default_face_mesh_tessellation_style()) + mp_drawing.draw_landmarks( + image=image, + landmark_list=face_landmarks, + connections=mp_face_mesh.FACEMESH_CONTOURS, + landmark_drawing_spec=None, + connection_drawing_spec=mp_drawing_styles + .get_default_face_mesh_contours_style()) + mp_drawing.draw_landmarks( + image=image, + landmark_list=face_landmarks, + connections=mp_face_mesh.FACEMESH_IRISES, + landmark_drawing_spec=None, + connection_drawing_spec=mp_drawing_styles + .get_default_face_mesh_iris_connections_style()) + # Flip the image horizontally for a selfie-view display. + cv2.imshow('MediaPipe Face Mesh', cv2.flip(image, 1)) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 手掌检测 + +读取摄像头画面并进行手掌检测,在检测出来的手掌上绘制骨骼。 + +运行案例步骤: + +1. 新建 `hand_detection.py` 文件 +2. 将代码复制到 `hand_detection.py` 文件 +3. 使用 `python3 hand_detection.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+hand_detection.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import mediapipe as mp +mp_drawing = mp.solutions.drawing_utils +mp_drawing_styles = mp.solutions.drawing_styles +mp_hands = mp.solutions.hands + +cap = cv2.VideoCapture(0) +with mp_hands.Hands( +model_complexity=0, +min_detection_confidence=0.5, +min_tracking_confidence=0.5) as hands: +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. +continue + + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + results = hands.process(image) + + # Draw the hand annotations on the image. + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + if results.multi_hand_landmarks: + for hand_landmarks in results.multi_hand_landmarks: + mp_drawing.draw_landmarks( + image, + hand_landmarks, + mp_hands.HAND_CONNECTIONS, + mp_drawing_styles.get_default_hand_landmarks_style(), + mp_drawing_styles.get_default_hand_connections_style()) + # Flip the image horizontally for a selfie-view display. + cv2.imshow('MediaPipe Hands', cv2.flip(image, 1)) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 骨骼检测 + +读取摄像头画面并进行人体检测,在检测出来的人体上绘制骨骼。 + +运行案例步骤: + +1. 新建 `pose_detection.py` 文件 +2. 将代码复制到 `pose_detection.py` 文件 +3. 使用 `python3 pose_detection.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+pose_detection.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import mediapipe as mp +mp_drawing = mp.solutions.drawing_utils +mp_drawing_styles = mp.solutions.drawing_styles +mp_pose = mp.solutions.pose + +cap = cv2.VideoCapture(0) +with mp_pose.Pose( +min_detection_confidence=0.5, +min_tracking_confidence=0.5) as pose: +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. +continue + + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + results = pose.process(image) + + # Draw the pose annotation on the image. + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + mp_drawing.draw_landmarks( + image, + results.pose_landmarks, + mp_pose.POSE_CONNECTIONS, + landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style()) + # Flip the image horizontally for a selfie-view display. + cv2.imshow('MediaPipe Pose', cv2.flip(image, 1)) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 整体检测 + +读取摄像头画面并进行整体检测,在检测出来的人体上绘制骨骼和面具。 + +运行案例步骤: + +1. 新建 `holistic_detection.py` 文件 +2. 将代码复制到 `holistic_detection.py` 文件 +3. 使用 `python3 holistic_detection.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+holistic_detection.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import mediapipe as mp +mp_drawing = mp.solutions.drawing_utils +mp_drawing_styles = mp.solutions.drawing_styles +mp_holistic = mp.solutions.holistic + +cap = cv2.VideoCapture(0) +with mp_holistic.Holistic( +min_detection_confidence=0.5, +min_tracking_confidence=0.5) as holistic: +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. +continue + + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + results = holistic.process(image) + + # Draw landmark annotation on the image. + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + mp_drawing.draw_landmarks( + image, + results.face_landmarks, + mp_holistic.FACEMESH_CONTOURS, + landmark_drawing_spec=None, + connection_drawing_spec=mp_drawing_styles + .get_default_face_mesh_contours_style()) + mp_drawing.draw_landmarks( + image, + results.pose_landmarks, + mp_holistic.POSE_CONNECTIONS, + landmark_drawing_spec=mp_drawing_styles + .get_default_pose_landmarks_style()) + # Flip the image horizontally for a selfie-view display. + cv2.imshow('MediaPipe Holistic', cv2.flip(image, 1)) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 背景分割 + +读取摄像头画面并进行人物的背景分割,将背景替换成单色背景。 + +运行案例步骤: + +1. 新建 `back_seg.py` 文件 +2. 将代码复制到 `back_seg.py` 文件 +3. 使用 `python3 back_seg.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+back_seg.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import mediapipe as mp +import numpy as np +mp_drawing = mp.solutions.drawing_utils +mp_selfie_segmentation = mp.solutions.selfie_segmentation + +BG_COLOR = (192, 192, 192) # gray +cap = cv2.VideoCapture(0) +with mp_selfie_segmentation.SelfieSegmentation( +model_selection=1) as selfie_segmentation: +bg_image = None +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") # If loading a video, use 'break' instead of 'continue'. +continue + + # Flip the image horizontally for a later selfie-view display, and convert + # the BGR image to RGB. + image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB) + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + results = selfie_segmentation.process(image) + + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + + # Draw selfie segmentation on the background image. + # To improve segmentation around boundaries, consider applying a joint + # bilateral filter to "results.segmentation_mask" with "image". + condition = np.stack( + (results.segmentation_mask,) * 3, axis=-1) > 0.1 + # The background can be customized. + # a) Load an image (with the same width and height of the input image) to + # be the background, e.g., bg_image = cv2.imread('/path/to/image/file') + # b) Blur the input image by applying image filtering, e.g., + # bg_image = cv2.GaussianBlur(image,(55,55),0) + if bg_image is None: + bg_image = np.zeros(image.shape, dtype=np.uint8) + bg_image[:] = BG_COLOR + output_image = np.where(condition, image, bg_image) + + cv2.imshow('MediaPipe Selfie Segmentation', output_image) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 3D 对象检测 + +读取摄像头画面并进行 3D 对象检测(支持鞋、椅子、杯子、相机四种模型),在检测出来的物体上绘制 3D 边界框。 + +运行案例步骤: + +1. 新建 `3d_object_detection.py` 文件 +2. 将代码复制到 `3d_object_detection.py` 文件 +3. 使用 `python3 3d_object_detection.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+3d_object_detection.py + +``` +#!/usr/bin/env python3 + +# -_- coding: utf-8 -_- + +import cv2 +import mediapipe as mp + +# Initialize MediaPipe components + +mp_drawing = mp.solutions.drawing_utils +mp_objectron = mp.solutions.objectron + +# Available models + +MODELS = ['Shoe', 'Chair', 'Cup', 'Camera'] +current_model = 0 # Start with first model + +# Initialize video capture + +cap = cv2.VideoCapture(0) + +# Create initial Objectron instance + +objectron = mp_objectron.Objectron( +static_image_mode=False, +max_num_objects=5, +min_detection_confidence=0.5, +min_tracking_confidence=0.99, +model_name=MODELS[current_model] +) + +while cap.isOpened(): +success, image = cap.read() +if not success: +print("Ignoring empty camera frame.") +continue + + # Process image + image.flags.writeable = False + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + results = objectron.process(image) + + # Draw results + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + + if results.detected_objects: + for detected_object in results.detected_objects: + mp_drawing.draw_landmarks( + image, detected_object.landmarks_2d, mp_objectron.BOX_CONNECTIONS) + mp_drawing.draw_axis(image, detected_object.rotation, + detected_object.translation) + + # # First flip the image for display + # image = cv2.flip(image, 1) + + # Then add text to the already-mirrored image + # Note: We adjust the x-position to account for mirroring + text_x = image.shape[1] - 200 # Right side position + cv2.putText(image, f"Model: {MODELS[current_model]}", (text_x, 30), + cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) + + # Show final view + cv2.imshow('MediaPipe Objectron', image) + + # Key handling + key = cv2.waitKey(5) & 0xFF + if key == 27 or key == ord('q'): # ESC or 'q' to quit + break + elif key == ord('f'): # 'f' for next model + current_model = (current_model + 1) % len(MODELS) + objectron = mp_objectron.Objectron( + static_image_mode=False, + max_num_objects=5, + min_detection_confidence=0.5, + min_tracking_confidence=0.99, + model_name=MODELS[current_model] + ) + print(f"Switched to model: {MODELS[current_model]}") + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
diff --git a/docs/common/radxa-os/application-dev/mediapipe-dev/_install.mdx b/docs/common/radxa-os/application-dev/mediapipe-dev/_install.mdx new file mode 100644 index 000000000..8d833eef3 --- /dev/null +++ b/docs/common/radxa-os/application-dev/mediapipe-dev/_install.mdx @@ -0,0 +1,68 @@ +MediaPipe 是由 Google Research 开发的一个开源、跨平台的机器学习框架,专注于实时多媒体处理。 + +## MediaPipe 特点 + +- 跨平台支持 + +支持 Android、iOS、Linux、macOS、Windows 等平台,提供统一的 API,减少平台适配工作量。 + +- 高效的实时处理 + +针对低延迟优化,适合实时应用,利用硬件加速(如 GPU、DSP)提升性能。 + +- 预构建的解决方案 + +提供多种开箱即用的机器学习模型和处理流水线(Pipeline),如人脸检测、手掌检测、骨骼检测、3D 对象检测等。 + +- 模块化与可扩展性 + +通过组合不同的计算单元(Calculators) 和数据流图(Graphs),用户可以自定义处理流水线。 + +支持集成自定义的 TensorFlow、TFLite 模型或其他 ML 模型。 + +- 轻量级 + +模型针对移动端优化,平衡精度与计算资源消耗。 + +## 安装 MediaPipe + +我们可以使用 `pip` 命令来安装 MediaPipe。 + +:::tip +安装 MediaPipe 前建议先将 Python3(推荐 Python 3.9+)和 OpenCV 安装好,OpenCV 可以参考 [OpenCV 安装](../opencv-dev/opencv_install)。 + +目前 MediaPipe 仅支持 Python 3.9 ~ Python 3.12 版本。 +::: + + + +``` +pip3 install mediapipe +``` + + + +## 验证 MediaPipe + +打开终端,在命令行输入 `python3` 进入 Python 交互模式。 + + + +``` +python3 +``` + + + +进入 Python 交互模式后,分别输入下面命令来验证 MediaPipe 是否安装成功。 + + + +``` +import mediapipe +print(mediapipe.__version__) +``` + + + +如果成功输出 MediaPipe 的版本号,说明 MediaPipe 安装成功。 diff --git a/docs/common/radxa-os/application-dev/ollama-dev/_example.mdx b/docs/common/radxa-os/application-dev/ollama-dev/_example.mdx new file mode 100644 index 000000000..4e45132f7 --- /dev/null +++ b/docs/common/radxa-os/application-dev/ollama-dev/_example.mdx @@ -0,0 +1,193 @@ +主要介绍 CLI(命令行)和 Python API 两种方式调用 Ollama。 + +:::tip +参考资料: + +- [Ollama 官方网站](https://ollama.com/) +- [Ollama GitHub](https://github.com/ollama/ollama) + ::: + +## Ollama 命令 + +Ollama 提供了丰富的命令行工具,可以方便的进行模型的拉取、运行、删除等操作。 + +我们可以使用 `ollama -h` 命令来查看 Ollama 的帮助信息。 + + + +``` +ollama -h +``` + + + +输出信息如下: + +``` +Large language model runner + +Usage: +ollama [flags] +ollama [command] + +Available Commands: +serve Start ollama +create Create a model from a Modelfile +show Show information for a model +run Run a model +stop Stop a running model +pull Pull a model from a registry +push Push a model to a registry +list List models +ps List running models +cp Copy a model +rm Remove a model +help Help about any command + +Flags: +-h, --help help for ollama +-v, --version Show version information + +Use "ollama [command] --help" for more information about a command. +``` + +## CLI 使用 + +CLI 是 Command-Line Interface(命令行界面) 的缩写,指的是通过终端或命令行输入命令来与程序交互的方式。 + +### 拉取模型 + +:::note + +Ollama 模型的参数和设备的内存有关,我们拉取模型的参数需要根据设备的内存大小来选择。 + +根据 Ollama 的官方文档提示 `You should have at least 8 GB of RAM available to run the 7B models, 16 GB to run the 13B models, and 32 GB to run the 33B models.`,我们可以预估自己设备应该选择对应的模型参数。 + +对于设备内存不大的用户,我们可以选择模型参数较小的模型,例如 `deepseek-r1:1.5b`。 +::: + +使用 `ollama pull` 命令来拉取模型:更多模型可以访问 [Ollama Library](https://ollama.com/library) 获取对应命令。 + + + +``` +ollama pull deepseek-r1:1.5b +``` + + + +整个拉取过程会在终端显示进度,拉取完成后,终端会输出类似下面信息: + +``` +pulling manifest +pulling aabd4debf0c8: 100% ▕███████████████████████████████████████████████████▏ 1.1 GB +pulling c5ad996bda6e: 100% ▕███████████████████████████████████████████████████▏ 556 B +pulling 6e4c38e1172f: 100% ▕███████████████████████████████████████████████████▏ 1.1 KB +pulling f4d24e9138dd: 100% ▕███████████████████████████████████████████████████▏ 148 B +pulling a85fe2a2e58e: 100% ▕███████████████████████████████████████████████████▏ 487 B +verifying sha256 digest +writing manifest +success +``` + +### 运行模型 + +使用 `ollama run` 命令来运行模型,若本地没有该模型,Ollama 会自动从远程仓库拉取模型。 + + + +``` +ollama run deepseek-r1:1.5b +``` + + + +成功运行后,终端会出现一个交互模式的界面。 + +我们可以直接提问 `Please introduce yourself`,模型会自动回复。 + +``` +> > > Please introduce yourself +> > > Hello! I'm DeepSeek-R1, an artificial intelligence assistant created by DeepSeek. I'm at your service and +> > > would be delighted to assist you with any inquiries or tasks you may have. + +> > > Send a message (/? for help) +``` + +:::tip +输入 `/bye` 或者 `Ctrl + D` 可以退出交互模式。 +::: + +## Python 使用 + +Ollama 提供简单易用的 Python 库,可以方便的进行模型的拉取、运行、删除等操作。 + +:::tip +使用 Ollama Python 库需要 Python 3.8 及以上版本。 + +我们推荐在 Conda 环境下安装和使用 ollama Python 库。 +::: + +我们可以使用 `pip` 命令来安装 Ollama Python 库。 + + + +``` +pip3 install ollama +``` + + + +### 普通响应 + +普通响应是同步的,模型会返回一个完整的响应(一次性输出回复)。 + +您可以使用 Jupyter Lab 的单元块来运行 Python 代码或者直接复制 Python 代码到 Python 文件中运行。 + +其中 Python 代码中的 `model` 参数需要确保本地已经拉取了对应的模型。 + + + +``` +from ollama import chat +from ollama import ChatResponse + +response: ChatResponse = chat(model='deepseek-r1:1.5b', messages=[ +{ +'role': 'user', +'content': 'Please introduce yourself', +}, +]) +print(response['message']['content']) + +# or access fields directly from the response object + +print(response.message.content) +``` + + + +### 流式响应 + +流式响应是异步的,模型会返回一个流式的响应(边生成边输出回复)。 + +您可以使用 Jupyter Lab 的单元块来运行 Python 代码或者直接复制 Python 代码到 Python 文件中运行。 + +其中 Python 代码中的 `model` 参数需要确保本地已经拉取了对应的模型。 + + + +``` +from ollama import chat + +stream = chat( + model='deepseek-r1:1.5b', + messages=[{'role': 'user', 'content': 'Please introduce yourself'}], + stream=True, +) + +for chunk in stream: + print(chunk['message']['content'], end='', flush=True) +``` + + diff --git a/docs/common/radxa-os/application-dev/ollama-dev/_install.mdx b/docs/common/radxa-os/application-dev/ollama-dev/_install.mdx new file mode 100644 index 000000000..ba9351667 --- /dev/null +++ b/docs/common/radxa-os/application-dev/ollama-dev/_install.mdx @@ -0,0 +1,73 @@ +Ollama 是一个强大的本地大语言模型(LLM)运行框架,让用户能够在自己的计算机上高效地运行各种开源大型语言模型。 + +## Ollama 特点 + +- 跨平台支持 + +支持 macOS、Linux 和 Windows 操作系统,满足不同用户群体的需求。 + +- 简单易用 + +提供简洁的命令行界面,使得下载、运行和管理大型语言模型变得非常便捷。 + +- 丰富的模型支持 + +支持运行多种开源大型语言模型,包括 DeepSeek、Qwen、LLama 等热门模型。 + +- 本地运行 + +所有模型都在本地运行,保障数据隐私和安全,无需依赖云端服务。 + +- 高效性能 + +针对本地环境优化,充分利用硬件资源,提供流畅的交互体验。 + +- 开发者友好 + +提供 API 接口,便于开发者将模型集成到自己的应用程序中。 + +## 安装 Ollama + +我们可以使用官方提供的 Linux 安装脚本来安装 Ollama。 + +打开终端,下载并运行安装脚本: + + + +``` +curl -fsSL https://ollama.com/install.sh | sh +``` + + + +终端会输出 ollama 的安装进度和安装信息,安装完成会输出类似下面信息: + +``` +> > > Installing ollama to /usr/local +> > > Downloading Linux arm64 bundle +> > > ######################################################################## 100.0% +> > > Creating ollama user... +> > > Adding ollama user to render group... +> > > Adding ollama user to video group... +> > > Adding current user to ollama group... +> > > Creating ollama systemd service... +> > > Enabling and starting ollama service... +> > > Created symlink /etc/systemd/system/default.target.wants/ollama.service → /etc/systemd/system/ollama.service. +> > > The Ollama API is now available at 127.0.0.1:11434. +> > > Install complete. Run "ollama" from the command line. +> > > WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode. +``` + +## 验证 Ollama + +我们可以使用 `ollama -v` 命令来查看 Ollama 的版本信息。 + + + +``` +ollama -v +``` + + + +如果成功输出 Ollama 的版本号,说明 Ollama 安装成功。 diff --git a/docs/common/radxa-os/application-dev/opencv-dev/_example.mdx b/docs/common/radxa-os/application-dev/opencv-dev/_example.mdx new file mode 100644 index 000000000..cc6da9fe0 --- /dev/null +++ b/docs/common/radxa-os/application-dev/opencv-dev/_example.mdx @@ -0,0 +1,782 @@ +主要介绍 OpenCV 图片的预览、摄像头调用以及视觉玩法示例。 + +## 图像预览 + +演示如何读取图片和摄像头画面并显示。 + +### 图片预览 + +读取图片并显示出来。 + +运行案例步骤: + +1. 新建 `preview_image.py` 文件 +2. 将代码复制到 `preview_image.py` 文件 +3. 使用 `python3 preview_image.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+preview_image.py + +``` +#!/usr/bin/env python3 +# -_- encoding: utf-8 -_- + +import cv2 + +# Read the image + +image_path = './radxa_logo.png' # Replace with your image path +image = cv2.imread(image_path) + +# Check if the image is loaded successfully + +if image is None: +print("Failed to load image. Please check the file path.") +else: # Display the image in a window +while True: +cv2.imshow('Preview', image) # Wait for 'q' key to quit +if cv2.waitKey(1) & 0xFF == ord('q'): +break +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +### 实时预览 + +读取摄像头画面并显示。 + +运行案例步骤: + +1. 新建 `preview_camera.py` 文件 +2. 将代码复制到 `preview_camera.py` 文件 +3. 使用 `python3 preview_camera.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +:::tip +其中代码中的 `cv2.VideoCapture(0)` 表示打开 `/dev/video0` 摄像头,若你有多个摄像头或者摄像头设备文件不为 `/dev/video0`,请根据实际情况修改代码。 +::: + +
+preview_camera.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 + +# Open the camera + +video_capture = cv2.VideoCapture(0) + +while True: # Read a frame from the camera +ret, frame = video_capture.read() + + # Check if the frame is read successfully + if not ret: + print("Failed to read frame. Please check the camera connection.") + break + + # Display the frame in a window + cv2.imshow('Preview', frame) + + # Wait for 'q' key to quit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# Release the camera and close the window + +video_capture.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## Harris 角点检测 + +Harris 角点检测(Harris Corner Detection)是一种经典的图像特征点检测算法,用于检测图像中的角点。 + +### 图片识别 + +读取图片并进行 Harris 角点检测。 + +运行案例步骤: + +1. 新建 `harris_image.py` 文件 +2. 将代码复制到 `harris_image.py` 文件 +3. 使用 `python3 harris_image.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+harris_image.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import numpy as np + +# Harris corner detection parameters + +block_size = 2 +ksize = 3 +k = 0.04 +threshold = 0.01 + +# Read the image + +image_path = './radxa_logo.png' # Replace with your image path +image = cv2.imread(image_path) + +# Check if the image is loaded successfully + +if image is None: +print("Failed to load image. Please check the file path.") +else: # Convert to grayscale +gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) +gray = np.float32(gray) + + # Apply Harris corner detection + dst = cv2.cornerHarris(gray, block_size, ksize, k) + + # Dilate corner points for better visualization + dst = cv2.dilate(dst, None) + + # Mark corners in red + image[dst > threshold * dst.max()] = [0, 0, 255] + + # Display the result + while True: + cv2.imshow('Harris Corners', image) + # Wait for 'q' key to quit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +### 实时检测 + +读取摄像头画面并进行 Harris 角点检测。 + +运行案例步骤: + +1. 新建 `harris_camera.py` 文件 +2. 将代码复制到 `harris_camera.py` 文件 +3. 使用 `python3 harris_camera.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +:::tip +其中代码中的 `cv2.VideoCapture(0)` 表示打开 `/dev/video0` 摄像头,若你有多个摄像头或者摄像头设备文件不为 `/dev/video0`,请根据实际情况修改代码。 +::: + +
+harris_camera.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import numpy as np + +# Harris corner detection parameters + +block_size = 2 +ksize = 3 +k = 0.04 +threshold = 0.01 + +# Initialize the camera + +cap = cv2.VideoCapture(0) + +# Check if the camera is opened successfully + +if not cap.isOpened(): +print("Error: Could not open camera.") +exit() + +while True: # Capture frame-by-frame +ret, frame = cap.read() + + # If frame is read correctly, ret is True + if not ret: + print("Error: Failed to capture frame.") + break + + # Create a copy of the frame for processing + display_frame = frame.copy() + + # Convert to grayscale + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + gray = np.float32(gray) + + # Apply Harris corner detection + dst = cv2.cornerHarris(gray, block_size, ksize, k) + + # Dilate corner points for better visualization + dst = cv2.dilate(dst, None) + + # Mark corners in red + display_frame[dst > threshold * dst.max()] = [0, 0, 255] + + # Display the resulting frame + cv2.imshow('Harris Corners - Camera', display_frame) + + # Press 'q' to exit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# When everything done, release the capture and close windows + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## Shi-Tomasi 角点检测 + +Shi-Tomasi 角点检测(Shi-Tomasi Corner Detection)是 Harris 角点检测的改进算法,用于检测图像中的角点。 + +### 图片识别 + +读取图片并进行 Shi-Tomasi 角点检测。 + +运行案例步骤: + +1. 新建 `shi_tomasi_image.py` 文件 +2. 将代码复制到 `shi_tomasi_image.py` 文件 +3. 使用 `python3 shi_tomasi_image.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+shi_tomasi_image.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import numpy as np + +# Shi-Tomasi corner detection parameters + +max_corners = 100 +quality_level = 0.01 +min_distance = 10 + +# Read the image + +image_path = './radxa_logo.png' # Replace with your image path +image = cv2.imread(image_path) + +# Check if the image is loaded successfully + +if image is None: +print("Failed to load image. Please check the file path.") +else: # Create a copy of the image for display +display_image = image.copy() + + # Convert to grayscale + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + + # Detect corners using Shi-Tomasi + corners = cv2.goodFeaturesToTrack(gray, max_corners, quality_level, min_distance) + + # Draw circles around detected corners + if corners is not None: + corners = np.int0(corners) + for corner in corners: + x, y = corner.ravel() + cv2.circle(display_image, (x, y), 5, (0, 255, 0), -1) # Green circles + + # Display the result + while True: + cv2.imshow('Shi-Tomasi Corners', display_image) + # Wait for 'q' key to quit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +### 实时检测 + +读取摄像头画面并进行 Shi-Tomasi 角点检测。 + +运行案例步骤: + +1. 新建 `shi_tomasi_camera.py` 文件 +2. 将代码复制到 `shi_tomasi_camera.py` 文件 +3. 使用 `python3 shi_tomasi_camera.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +:::tip +其中代码中的 `cv2.VideoCapture(0)` 表示打开 `/dev/video0` 摄像头,若你有多个摄像头或者摄像头设备文件不为 `/dev/video0`,请根据实际情况修改代码。 +::: + +
+shi_tomasi_camera.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import numpy as np + +# Shi-Tomasi corner detection parameters + +max_corners = 100 +quality_level = 0.01 +min_distance = 10 + +# Initialize the camera + +cap = cv2.VideoCapture(0) + +# Check if the camera is opened successfully + +if not cap.isOpened(): +print("Error: Could not open camera.") +exit() + +while True: # Capture frame-by-frame +ret, frame = cap.read() + + # If frame is read correctly, ret is True + if not ret: + print("Error: Failed to capture frame.") + break + + # Create a copy of the frame for display + display_frame = frame.copy() + + # Convert to grayscale + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + # Detect corners using Shi-Tomasi + corners = cv2.goodFeaturesToTrack(gray, max_corners, quality_level, min_distance) + + # Draw circles around detected corners + if corners is not None: + corners = np.int0(corners) + for corner in corners: + x, y = corner.ravel() + cv2.circle(display_frame, (x, y), 5, (0, 255, 0), -1) # Green circles + + # Display the resulting frame + cv2.imshow('Shi-Tomasi Corners - Camera', display_frame) + + # Press 'q' to exit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# When everything done, release the capture and close windows + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## ORB 特征检测 + +ORB(Oriented FAST and Rotated BRIEF)是一种高效的特征检测与描述算法,结合了 FAST 关键点检测器 和 BRIEF 描述符,并进行了改进以提升性能,尤其在计算效率和旋转不变性方面表现突出。 + +### 图片识别 + +读取图片并进行 ORB 特征检测。 + +运行案例步骤: + +1. 新建 `orb_image.py` 文件 +2. 将代码复制到 `orb_image.py` 文件 +3. 使用 `python3 orb_image.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+orb_image.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import numpy as np + +# Read the image + +image_path = './radxa_logo.png' # Replace with your image path +image = cv2.imread(image_path) + +# Check if the image is loaded successfully + +if image is None: +print("Failed to load image. Please check the file path.") +else: # Create a copy of the image for display +display_image = image.copy() + + # Convert to grayscale + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + + # Initialize ORB detector + orb = cv2.ORB_create(nfeatures=500) + + # Detect keypoints and compute descriptors + keypoints, descriptors = orb.detectAndCompute(gray, None) + + # Draw keypoints on the image + display_image = cv2.drawKeypoints(image, keypoints, None, color=(0, 255, 0), + flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT) + + # Display the result + while True: + cv2.imshow('ORB Features', display_image) + # Wait for 'q' key to quit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +### 实时检测 + +读取摄像头画面并进行 ORB 特征检测。 + +运行案例步骤: + +1. 新建 `orb_camera.py` 文件 +2. 将代码复制到 `orb_camera.py` 文件 +3. 使用 `python3 orb_camera.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +:::tip +其中代码中的 `cv2.VideoCapture(0)` 表示打开 `/dev/video0` 摄像头,若你有多个摄像头或者摄像头设备文件不为 `/dev/video0`,请根据实际情况修改代码。 +::: + +
+orb_camera.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import numpy as np + +# Initialize ORB detector + +orb = cv2.ORB_create(nfeatures=500) + +# Initialize the camera + +cap = cv2.VideoCapture(0) + +# Check if the camera is opened successfully + +if not cap.isOpened(): +print("Error: Could not open camera.") +exit() + +while True: # Capture frame-by-frame +ret, frame = cap.read() + + # If frame is read correctly, ret is True + if not ret: + print("Error: Failed to capture frame.") + break + + # Convert to grayscale + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + # Detect keypoints and compute descriptors + keypoints, descriptors = orb.detectAndCompute(gray, None) + + # Draw keypoints on the frame + display_frame = cv2.drawKeypoints(frame, keypoints, None, + color=(0, 255, 0), + flags=cv2.DRAW_MATCHES_FLAGS_DEFAULT) + + # Display the number of keypoints + cv2.putText(display_frame, f'Keypoints: {len(keypoints)}', (10, 30), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) + + # Display the resulting frame + cv2.imshow('ORB Features - Camera', display_frame) + + # Press 'q' to exit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# When everything done, release the capture and close windows + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +## 人脸识别 + +基于 Haar Cascade 分类器实现的人脸检测功能,其核心原理是通过机器学习训练的级联分类器在图像中快速定位人脸区域。 + +### 图片识别 + +读取图片并进行人脸识别。 + +运行案例步骤: + +1. 新建 `face_recognition_image.py` 文件 +2. 将代码复制到 `face_recognition_image.py` 文件 +3. 使用 `python3 face_recognition_image.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +
+face_recognition_image.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 +import os + +# Load the pre-trained Haar Cascade classifier for face detection + +face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') + +# Read the image + +image_path = 'people.png' # Replace with your image path +image = cv2.imread(image_path) + +# Check if the image is loaded successfully + +if image is None: +print(f"Error: Could not read image at {image_path}") +exit() + +# Convert to grayscale (face detection works on grayscale images) + +gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + +# Detect faces in the image + +faces = face_cascade.detectMultiScale( +gray, +scaleFactor=1.1, # Scale factor for image pyramid +minNeighbors=5, # How many neighbors each candidate rectangle should have +minSize=(30, 30) # Minimum possible object size +) + +# Draw rectangles around the faces + +for (x, y, w, h) in faces: +cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2) + +# Display the number of faces detected + +print(f"Number of faces detected: {len(faces)}") + +# Display the result + +while True: +cv2.imshow('Face Detection', image) # Wait for 'q' key to quit +if cv2.waitKey(1) & 0xFF == ord('q'): +break + +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
+ +### 实时检测 + +读取摄像头画面并进行人脸识别。 + +运行案例步骤: + +1. 新建 `face_recognition_camera.py` 文件 +2. 将代码复制到 `face_recognition_camera.py` 文件 +3. 使用 `python3 face_recognition_camera.py` 运行案例 +4. 鼠标点击预览窗口,按 `q` 键终止程序 + +:::tip +其中代码中的 `cv2.VideoCapture(0)` 表示打开 `/dev/video0` 摄像头,若你有多个摄像头或者摄像头设备文件不为 `/dev/video0`,请根据实际情况修改代码。 +::: + +
+face_recognition_camera.py + +``` +#!/usr/bin/env python3 + +# -_- encoding: utf-8 -_- + +import cv2 + +# Load the pre-trained Haar Cascade classifier for face detection + +face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') + +# Initialize the camera + +cap = cv2.VideoCapture(0) + +# Check if the camera is opened successfully + +if not cap.isOpened(): +print("Error: Could not open camera.") +exit() + +while True: # Capture frame-by-frame +ret, frame = cap.read() + + # If frame is read correctly, ret is True + if not ret: + print("Error: Failed to capture frame.") + break + + # Convert to grayscale (face detection works on grayscale images) + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + # Detect faces in the frame + faces = face_cascade.detectMultiScale( + gray, + scaleFactor=1.1, # Scale factor for image pyramid + minNeighbors=5, # How many neighbors each candidate rectangle should have + minSize=(30, 30) # Minimum possible object size + ) + + # Draw rectangles around the faces + for (x, y, w, h) in faces: + cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) + + # Display the number of faces detected + cv2.putText(frame, f'Faces: {len(faces)}', (10, 30), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) + + # Display the resulting frame + cv2.imshow('Face Detection - Camera', frame) + + # Press 'q' to exit + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# When everything done, release the capture and close windows + +cap.release() +cv2.destroyAllWindows() +``` + +
+ +预览效果: + +
+ +
diff --git a/docs/common/radxa-os/application-dev/opencv-dev/_install.mdx b/docs/common/radxa-os/application-dev/opencv-dev/_install.mdx new file mode 100644 index 000000000..c31fbeaff --- /dev/null +++ b/docs/common/radxa-os/application-dev/opencv-dev/_install.mdx @@ -0,0 +1,180 @@ +OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。 + +## OpenCV 特点 + +- 高性能 + +底层采用 C++ 优化,提供 Python、Java 等接口,兼顾速度和易用性,支持 GPU 加速(CUDA、OpenCL)。 + +- 跨平台 + +支持 Windows、Linux、macOS、Android 和 iOS,可在 x86、ARM 等多种硬件架构上运行。 + +- 多语言 + +提供 C++、Python、Java 等接口,适合不同开发需求,并兼容 TensorFlow、PyTorch 等深度学习框架。 + +- 丰富的功能 + +OpenCV 提供了丰富的计算机视觉算法,包括图像处理、特征检测、目标检测、机器学习等。 + +## 安装 OpenCV + +主要介绍二进制和源码两种不同方式安装 OpenCV,您可以根据自己的需求选择其中一种方式安装即可。 + +| 安装方式 | 优点 | 缺点 | 适合人群 | +| ---------- | --------------------------------------------------------------------------- | -------------------------------------------------- | ------------------------------- | +| 二进制安装 | - 安装简单快捷
- 不需要编译源码
- 易于维护和升级 | - 功能可能不全
- 定制性较差 | 初学者、日常开发、Python用户 | +| 源码安装 | - 可自定义编译参数、功能模块
- 可以获得最新/指定版本
- 支持多语言 | - 步骤复杂
- 需要编译环境
- 编译耗时较长 | 有特殊需求、C++开发者、高级用户 | + +### 二进制安装 + +我们可以使用 `pip` 命令来安装 Python 版本的 OpenCV,使用 `apt` 命令来安装 C++ 版本的 OpenCV。 + + + + + + + +``` +pip3 install opencv-python opencv-contrib-python +``` + + + +- 验证 OpenCV + +打开终端,在命令行输入 `python3` 进入 Python 交互模式。 + + + +``` +python3 +``` + + + +进入 Python 交互模式后,分别输入下面命令来验证 OpenCV 是否安装成功。 + + + +``` +import cv2 +print(cv2.__version__) +``` + + + +如果成功输出 OpenCV 的版本号,说明 OpenCV 安装成功。 + + + + + + + +``` +sudo apt update +sudo apt install libopencv-dev +``` + + + +- 验证 OpenCV + +打开终端,在终端输入 `pkg-config --modversion opencv4` 来验证 OpenCV 是否安装成功。 + + + +``` +pkg-config --modversion opencv4 +``` + + + +如果成功输出 OpenCV 的版本号,说明 OpenCV 安装成功。 + + + + + +### 源码安装 + +我们通过编译 OpenCV 源码来安装 OpenCV。 + +#### 安装编译依赖 + + + +``` +sudo apt update +sudo apt install cmake gcc g++ python3-dev python3-numpy libavcodec-dev libavformat-dev libswscale-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgtk-3-dev -y +``` + + + +#### 安装可选依赖 + + + +``` +sudo apt install libpng-dev libjpeg-dev libopenexr-dev libtiff-dev libwebp-dev -y +``` + + + +#### 下载 OpenCV 源码 + +使用 `git` 下载 OpenCV 源码。 + + + +``` +sudo apt install git -y +git clone https://github.com/opencv/opencv.git +``` + + + +#### 编译 OpenCV + +进入 OpenCV 源码目录,然后输入以下命令来编译 OpenCV。 + + + +``` +cd opencv +mkdir build +cd build +cmake ../ +make -j4 +sudo make install +``` + + + +#### 验证 OpenCV + +打开终端,在命令行输入 `python3` 进入 Python 交互模式。 + + + +``` +python3 +``` + + + +进入 Python 交互模式后,分别输入下面命令来验证 OpenCV 是否安装成功。 + + + +``` +import cv2 +print(cv2.__version__) +``` + + + +如果成功输出 OpenCV 的版本号,说明 OpenCV 安装成功。 diff --git a/docs/common/radxa-os/application-dev/ros-dev/ros1-dev/_example.mdx b/docs/common/radxa-os/application-dev/ros-dev/ros1-dev/_example.mdx new file mode 100644 index 000000000..98389d2a2 --- /dev/null +++ b/docs/common/radxa-os/application-dev/ros-dev/ros1-dev/_example.mdx @@ -0,0 +1,248 @@ +使用小海龟 (Turtlesim) 案例快速体验 ROS1 常见基础概念和功能。 + +:::tip +该教程基于 ROS1 Noetic 的 Docker 镜像操作,但不局限于 Docker 环境,任何 ROS1 环境都可以操作。 + +若您是基于 Docker 环境操作,建议您先学习 Docker 的使用。 +::: + +## 启动 Docker 脚本 + +使用以下命令启动 Docker 脚本:`ros_noetic.sh` 是在ROS1 环境搭建中创建的脚本。 + + + +``` +bash ros_noetic.sh +``` + + + +建议使用多个终端进入同一个 Docker 容器中,方便后续操作。 + +
+ +
+ +## 启动 Master 节点 + +ROS1 需要先启动 Master 节点,再启动 Turtlesim 节点。 + + +``` +roscore +``` + + + +
+ +
+ +## 启动 Turtlesim + +使用以下命令启动 Turtlesim: + + + +``` +rosrun turtlesim turtlesim_node +``` + + + +该命令会创建 `/turtlesim` 节点和显示一个包含小海龟的窗口。 + +
+ +
+ +## 控制 Turtlesim + +使用以下命令控制小海龟移动: + + + +``` +rosrun turtlesim turtle_teleop_key +``` + + + +该命令会创建 `/teleop_turtle` 节点。 + +
+ +
+ +:::tip +鼠标点击并停留在这个键盘控制的终端窗口,我们可以通过键盘上的方向键控制小海龟移动。 +::: + +## ROS1 基础概念 + +通过 Turtlesim 案例,我们可以进一步了解和使用 ROS1 的基础概念和命令。 + +:::tip +关闭正在运行的 ROS1 命令,可以使用 `Ctrl + C` 组合键。 +::: + +### ROS1 节点 + +节点是 ROS1 中的基本通信单元,通过发布者(Publisher)和订阅者(Subscriber)与其他节点交互。 + +:::tip +**关键组成**: + +- **发布者**:向话题(Topic)发布消息的接口 +- **订阅者**:从话题接收消息的接口 + ::: + +#### 查看节点 + +使用 `rosnode list` 命令查看节点:目前只运行启动 Turtlesim 的命令。 + + + +``` +rosnode list +``` + + + +
+ +
+ +### ROS1 话题 + +话题是 ROS1 中的发布/订阅通信机制,实现节点间的异步数据传输。 + +:::tip +**通信角色**: + +- **发布者**:将消息发送到指定话题 +- **订阅者**:订阅话题并接收消息 + ::: + +#### 查看话题 + +使用 `rostopic list` 命令查看话题: + + + +``` +rostopic list +``` + + + +
+ +
+ +#### 发布话题 + +使用 `rostopic pub` 命令发布速度控制消息,让小乌龟移动: + +``` +rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist "{linear: {x: 0.5, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.5}}" +``` + +该命令会以 10 Hz 的频率让小海龟以线速度 0.5 和角速度 0.5 移动。 + +
+ +
+ +#### 订阅话题 + +使用 `rostopic echo` 命令订阅话题,查看话题消息: + + + +``` +rostopic echo -n 1 /turtle1/pose +``` + + +该命令会在终端打印一次小海龟的位置。 + +
+ +
+ +### ROS1 服务 + +服务是 ROS1 中的请求/响应通信机制,用于节点间的同步调用(如远程函数)。 + +:::tip +**交互流程**: + +- **客户端**:发送请求(Request) +- **服务端**:处理请求并返回响应(Response) + ::: + +#### 查看服务 + +使用 `rosservice list` 命令查看服务: + + + +``` +rosservice list +``` + + + +
+ +
+ +#### 调用服务 + +使用 `rosservice call` 命令调用服务,让小乌龟清屏: + + + +``` +rosservice call /clear +``` + + + +该命令会清除Turtlesim窗口中的背景。 + +
+ +
diff --git a/docs/common/radxa-os/application-dev/ros-dev/ros1-dev/_install.mdx b/docs/common/radxa-os/application-dev/ros-dev/ros1-dev/_install.mdx new file mode 100644 index 000000000..02c0f3f99 --- /dev/null +++ b/docs/common/radxa-os/application-dev/ros-dev/ros1-dev/_install.mdx @@ -0,0 +1,305 @@ +主要介绍搭建 ROS1 Noetic 版本的环境。 + +:::tip + +- 建议以下操作基于 VNC 远程桌面或者连接显示器进行操作。 +- ROS 环境是搭建在 Docker 容器中的,建议先安装和学习 Docker 的使用。 +- Ubuntu 是 ROS 官方首选和主要支持的发行版,我们会基于 Docker 的 Ubuntu 镜像来搭建 ROS 环境。 + ::: + +## 拉取 Docker 镜像 + +使用 `docker pull` 命令拉取 Ubuntu20.04 的 Docker 镜像。 + + + +``` +docker pull ubuntu:20.04 +``` + + + +## 编写 Docker 脚本 + +使用脚本启动 Ubuntu20.04 的 Docker 容器。 + +您需要编写一个启动脚本 `ros_noetic.sh`: + + + +``` +vi ros_noetic.sh +``` + + + +添加以下内容到 `ros_noetic.sh` 脚本内: + +``` +#!/bin/bash +xhost + + +docker run -it \ +--net=host \ +--env="DISPLAY" \ +--env="QT_X11_NO_MITSHM=1" \ +-v /tmp/.X11-unix:/tmp/.X11-unix \ +ubuntu:20.04 /bin/bash +``` + +参数说明: + +- `xhost +`: 允许 Docker 容器访问 X11 服务器 +- `-it`: 以交互模式运行容器 +- `--net=host`: 使用主机的网络栈 +- `--env="DISPLAY"`: 设置环境变量,用于显示 X11 图形界面 +- `--env="QT_X11_NO_MITSHM=1"`: 设置环境变量,用于 Qt 应用程序的显示 +- `-v /tmp/.X11-unix:/tmp/.X11-unix`: 挂载 X11 Unix 域套接字,用于显示 X11 图形界面 +- `ubuntu:20.04`: 使用 Ubuntu 20.04 镜像 +- `/bin/bash`: 在容器内启动 Bash shell + +## 启动 Docker 容器 + +使用 `bash` 命令启动脚本。 + + + +``` +bash ros_noetic.sh +``` + + + +## 安装 Noetic + +### 编码环境检查 + +确保安装 Noetic 的环境支持 UTF-8 编码。 + + + +``` +locale +``` + + + +若系统编码格式是 UTF-8,你可以在终端看到类似以下信息输出: + +``` +LANG=en_US.UTF-8 +LANGUAGE= +LC_CTYPE="en_US.UTF-8" +LC_NUMERIC="en_US.UTF-8" +LC_TIME="en_US.UTF-8" +LC_COLLATE="en_US.UTF-8" +LC_MONETARY="en_US.UTF-8" +LC_MESSAGES="en_US.UTF-8" +LC_PAPER="en_US.UTF-8" +LC_NAME="en_US.UTF-8" +LC_ADDRESS="en_US.UTF-8" +LC_TELEPHONE="en_US.UTF-8" +LC_MEASUREMENT="en_US.UTF-8" +LC_IDENTIFICATION="en_US.UTF-8" +LC_ALL= +``` + +若终端输出的信息不是 UTF-8 编码,你可以在终端输入以下命令来安装和修改编码环境: + + + +``` +apt update && apt install locales +locale-gen en_US en_US.UTF-8 +echo "export LANG=en_US.UTF-8" >> ~/.bashrc +source ~/.bashrc +``` + + + +### 设置软件源和密钥 + +确保系统处于最新的环境,然后添加清华软件源和密钥。 + + + +``` +apt update && apt upgrade +apt install lsb-core +sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' +apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 +``` + + + +### 安装 Noetic + +使用以下命令安装 Noetic 完整桌面版。 + + + +``` +apt update && apt upgrade +apt install ros-noetic-desktop-full -y +``` + + + +### 安装依赖 + +使用以下命令安装 Noetic 的依赖包。 + + + +``` +apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential -y +``` + + + +### 初始化 rosdep + +使用以下命令初始化 rosdep。 + + + +``` +rosdep init +rosdep update +``` + + + +若 rosdep init 出现 `ERROR: cannot download default sources list from: https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/sources.list.d/20-default.list Website may be down.` 错误提示,访问 `https://www.ipaddress.com/` 搜索 `raw.githubusercontent.com` 域名,并将搜索得到的 IP 地址填写进 /etc/hosts 文件。 + + + +``` +vi /etc/hosts +``` + + +添加以下内容: + +``` +185.199.110.133 raw.githubusercontent.com +``` + +然后重新运行初始化 rosdep 命令。 + +## 设置环境变量 + +使用以下命令设置环境变量: + + + +``` +echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc +source ~/.bashrc +``` + + + +## 验证 ROS 环境 + +在终端输入以下命令验证 ROS 环境是否安装成功。 + + + +``` +roscore +``` + + + +若安装成功,你会看到类似以下信息输出: + +``` +... logging to /root/.ros/log/a9473172-5731-11f0-9a87-5acb6b3cedae/roslaunch-rock-4d-spi-27211.log +Checking log directory for disk usage. This may take a while. +Press Ctrl-C to interrupt +Done checking log file disk usage. Usage is <1GB. + +started roslaunch server http://rock-4d-spi:34861/ +ros_comm version 1.17.4 + +# SUMMARY + +PARAMETERS + +- /rosdistro: noetic +- /rosversion: 1.17.4 + +NODES + +auto-starting new master +process[master]: started with pid [27219] +ROS_MASTER_URI=http://rock-4d-spi:11311/ + +setting /run_id to a9473172-5731-11f0-9a87-5acb6b3cedae +process[rosout-1]: started with pid [27229] +started core service [/rosout] +``` + +使用 `Ctrl + C` 可以停止 roscore。 + +## 保存 Docker 镜像 + +目前我们的修改都是基于 Ubuntu20.04 的 Docker 容器,我们需要把这个修改的容器保存为镜像,以便下次直接使用。 + +注意:若没有保存为镜像,下次启动容器时需要重新安装 ROS 环境。 + +### 查看正在运行的容器 + +在 Cubie A7A 的另一个没有进入 Docker 容器的终端输入以下命令查看正在运行的容器。 + + + +``` +docker ps +``` + + + +### 提交容器为镜像 + +在 Cubie A7A 的另一个没有进入 Docker 容器的终端输入以下命令提交容器为镜像。 + +:::tip +需要根据 `docker ps` 命令输出的容器 ID进行命令的修改。 +::: + + + +``` +docker commit [CONTAINER ID] [NEW NAME] + +# 示例 + +docker commit e5c795d8ca66 ros_noetic:1.0 +``` + + + +等待提交完成,完成后会输出类似以下信息输出: + +``` +sha256:43b559a4d879c83477764730e0af90e8904e8fb8aeeeb9b653967e665bb7a7ca +``` + +### 修改启动脚本 + +将启动脚本 `ros_noetic.sh` 内的启动镜像修改为刚才保存的镜像名称: + +``` +#!/bin/bash + +xhost + + +docker run -it \ +--net=host \ +--env="DISPLAY" \ +--env="QT_X11_NO_MITSHM=1" \ +-v /tmp/.X11-unix:/tmp/.X11-unix \ +ros_noetic:1.0 /bin/bash +``` diff --git a/docs/common/radxa-os/application-dev/ros-dev/ros2-dev/_example.mdx b/docs/common/radxa-os/application-dev/ros-dev/ros2-dev/_example.mdx new file mode 100644 index 000000000..9ced5882c --- /dev/null +++ b/docs/common/radxa-os/application-dev/ros-dev/ros2-dev/_example.mdx @@ -0,0 +1,282 @@ +使用小海龟 (Turtlesim) 案例快速体验 ROS2 常见基础概念和功能。 + +:::tip +该教程基于 ROS2 Humble 的 Docker 镜像操作,但不局限于 Docker 环境,任何 ROS2 环境都可以操作。 + +若您是基于 Docker 环境操作,建议您先学习 Docker 的使用。 +::: + +## 启动 Docker 脚本 + +使用以下命令启动 Docker 脚本:`ros_humble.sh` 是在 ROS2 环境搭建中创建的脚本。 + + + +``` +bash ros_humble.sh +``` + + + +建议使用多个终端进入同一个 Docker 容器中,方便后续操作。 + +
+ +
+ +## 启动 Turtlesim + +使用以下命令启动 Turtlesim: + + + +``` +ros2 run turtlesim turtlesim_node +``` + + + +
+ +
+ +该命令会创建 `/turtlesim` 节点和显示一个包含小海龟的窗口。 + +## 控制 Turtlesim + +使用以下命令控制小海龟移动: + + + +``` +ros2 run turtlesim turtle_teleop_key +``` + + + +该命令会创建 `/teleop_turtle` 节点。 + +:::tip +鼠标点击并停留在这个键盘控制的终端窗口,我们可以通过键盘上的方向键控制小海龟移动。 +::: + +
+ +
+ +## ROS2 基础概念 + +通过 Turtlesim 案例,我们可以进一步了解和使用 ROS2 的基础概念和命令。 + +:::tip +关闭正在运行的 ROS2 命令,可以使用 `Ctrl + C` 组合键。 +::: + +### ROS2 节点 + +节点是 ROS2 中的基本通信单元,通过发布者(Publisher)和订阅者(Subscriber)与其他节点交互。 + +:::tip +**关键组成**: + +- **发布者**:向话题(Topic)发布消息的接口 +- **订阅者**:从话题接收消息的接口 + ::: + +#### 查看节点 + +使用 `ros2 node list` 命令查看节点:目前只运行启动 Turtlesim 的命令。 + + + +``` +ros2 node list +``` + + + +
+ +
+ +### ROS2 话题 + +话题是 ROS2 中的发布/订阅通信机制,实现节点间的异步数据传输。 + +:::tip +**通信角色**: + +- **发布者**:将消息发送到指定话题 +- **订阅者**:订阅话题并接收消息 + ::: + +#### 查看话题 + +使用 `ros2 topic list` 命令查看话题: + + + +``` +ros2 topic list +``` + + + +
+ +
+ +#### 发布话题 + +使用 `ros2 topic pub` 命令发布速度控制消息,让小乌龟移动: + +``` +ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.5}}" +``` + +该命令会让小海龟以线速度 0.5 和角速度 0.5 移动。 + +
+ +
+ +#### 订阅话题 + +使用 `ros2 topic echo` 命令订阅话题,查看话题消息: + + + +``` +ros2 topic echo /turtle1/pose --once +``` + + +该命令会在终端打印一次小海龟位置,去掉 `--once` 会一直打印小海龟位置。 + +
+ +
+ +### ROS2 服务 + +服务是 ROS2 中的请求/响应通信机制,用于节点间的同步调用(如远程函数)。 + +:::tip +**交互流程**: + +- **客户端**:发送请求(Request) +- **服务端**:处理请求并返回响应(Response) + ::: + +#### 查看服务 + +使用 `ros2 service list` 命令查看服务: + + + +``` +ros2 service list +``` + + + +
+ +
+ +#### 调用服务 + +使用 `ros2 service call` 命令调用服务,让小乌龟清屏: + + + +``` +ros2 service call /clear std_srvs/srv/Empty +``` + + + +该命令会清除Turtlesim窗口中的背景。 + +
+ +
+ +### ROS2 动作 + +动作是 ROS2 中处理长时间任务的通信机制(如导航、机械臂控制),支持实时反馈。 + +:::tip +**三阶段交互**: + +- **目标**(Goal):客户端发起任务请求 +- **反馈**(Feedback):服务端持续推送进度 +- **结果**(Result):任务完成后返回最终结果 + ::: + +#### 查看动作 + +使用 `ros2 action list` 命令查看动作: + + + +``` +ros2 action list +``` + + + +
+ +
+ +#### 发布动作 + +使用 `ros2 action send_goal` 命令发布动作,让小乌龟移动到指定位置: + + + +``` +ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}" +``` + + + +该命令会让小海龟旋转 1.57 弧度(约 90 度)。 + +
+ +
diff --git a/docs/common/radxa-os/application-dev/ros-dev/ros2-dev/_install.mdx b/docs/common/radxa-os/application-dev/ros-dev/ros2-dev/_install.mdx new file mode 100644 index 000000000..f1b5eb7f1 --- /dev/null +++ b/docs/common/radxa-os/application-dev/ros-dev/ros2-dev/_install.mdx @@ -0,0 +1,272 @@ +主要介绍搭建 ROS2 Humble 版本的环境。 + +:::tip + +- 建议以下操作基于 VNC 远程桌面或者连接显示器进行操作。 +- ROS2 环境是搭建在 Docker 容器中的,建议先安装和学习 Docker 的使用。 +- Ubuntu 是 ROS2 官方首选和主要支持的发行版,我们会基于 Docker 的 Ubuntu 镜像来搭建 ROS2 环境。 + ::: + +## 拉取 Docker 镜像 + +使用 `docker pull` 命令拉取 Ubuntu22.04 的 Docker 镜像。 + + + +``` +docker pull ubuntu:22.04 +``` + + + +## 编写 Docker 脚本 + +使用脚本启动 Ubuntu22.04 的 Docker 容器。 + +您需要编写一个启动脚本 `ros_humble.sh`: + + + +``` +vi ros_humble.sh +``` + + + +添加以下内容到脚本内: + +``` +#!/bin/bash +xhost + + +docker run -it \ +--net=host \ +--env="DISPLAY" \ +--env="QT_X11_NO_MITSHM=1" \ +-v /tmp/.X11-unix:/tmp/.X11-unix \ +ubuntu:22.04 /bin/bash +``` + +参数说明: + +- `xhost +`: 允许 Docker 容器访问 X11 服务器 +- `-it`: 以交互模式运行容器 +- `--net=host`: 使用主机的网络栈 +- `--env="DISPLAY"`: 设置环境变量,用于显示 X11 图形界面 +- `--env="QT_X11_NO_MITSHM=1"`: 设置环境变量,用于 Qt 应用程序的显示 +- `-v /tmp/.X11-unix:/tmp/.X11-unix`: 挂载 X11 Unix 域套接字,用于显示 X11 图形界面 +- `ubuntu:22.04`: 使用 Ubuntu 22.04 镜像 +- `/bin/bash`: 在容器内启动 Bash shell + +## 启动 Docker 容器 + +使用 `bash` 命令启动脚本。 + + + +``` +bash ros_humble.sh +``` + + + +## 安装 Humble + +### 编码环境检查 + +确保安装 Humble 的环境支持 UTF-8 编码。 + + + +``` +locale +``` + + + +若系统编码格式是 UTF-8,你可以在终端看到类似以下信息输出: + +``` +LANG=en_US.UTF-8 +LANGUAGE= +LC_CTYPE="en_US.UTF-8" +LC_NUMERIC="en_US.UTF-8" +LC_TIME="en_US.UTF-8" +LC_COLLATE="en_US.UTF-8" +LC_MONETARY="en_US.UTF-8" +LC_MESSAGES="en_US.UTF-8" +LC_PAPER="en_US.UTF-8" +LC_NAME="en_US.UTF-8" +LC_ADDRESS="en_US.UTF-8" +LC_TELEPHONE="en_US.UTF-8" +LC_MEASUREMENT="en_US.UTF-8" +LC_IDENTIFICATION="en_US.UTF-8" +LC_ALL= +``` + +若终端输出的信息不是 UTF-8 编码,你可以在终端输入以下命令来安装和修改编码环境: + + + +``` +apt update && apt install locales +locale-gen en_US en_US.UTF-8 +echo "export LANG=en_US.UTF-8" >> ~/.bashrc +source ~/.bashrc +``` + + + +### 设置软件源和密钥 + +确保系统处于最新的环境,然后启用Ubuntu Universe存储库和添加 ROS2 密钥。 + + + +``` +apt-cache policy | grep universe +apt install software-properties-common curl -y +add-apt-repository universe +curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +``` + + + +若出现错误提示:`curl: (7) Failed to connect to raw.githubusercontent.com port 443 after 43 ms: Connection refused` +解决办法:访问 `https://www.ipaddress.com/搜索raw.githubusercontent.com` 域名,并将搜索得到的IP地址填写进/etc/hosts文件。 + + + +``` +vi /etc/hosts +``` + + +添加以下内容: + +``` +185.199.110.133 raw.githubusercontent.com +``` + +然后重新运行添加 ROS2 密钥的命令。 + + + +``` +curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +``` + + + +将存储库添加到源列表中: + + + +``` +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null +``` + + + +### 安装 Humble + +使用以下命令安装 Humble 完整桌面版。 + + + +``` +apt update && apt upgrade +apt install ros-humble-desktop-full -y +``` + + + +### 安装 ROS2 开发工具 + +使用以下命令安装 ROS2 开发工具。 + + + +``` +apt install ros-dev-tools -y +``` + + + +## 设置环境变量 + +使用以下命令设置环境变量: + + + +``` +echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc +source ~/.bashrc +``` + + + +## 保存 Docker 镜像 + +目前我们的修改都是基于 Ubuntu22.04 的 Docker 容器,我们需要把这个修改的容器保存为镜像,以便下次直接使用。 + +注意:若没有保存为镜像,下次启动容器时需要重新安装 ROS2 环境。 + +### 查看正在运行的容器 + +在 Cubie A7A 的另一个没有进入 Docker 容器的终端输入以下命令查看正在运行的容器。 + + + +``` +docker ps +``` + + + +### 提交容器为镜像 + +在 Cubie A7A 的另一个没有进入 Docker 容器的终端输入以下命令提交容器为镜像。 + +:::tip +需要根据 `docker ps` 命令输出的容器 ID进行命令的修改。 +::: + + + +``` +docker commit [CONTAINER ID] [NEW NAME] + +# 示例 + +docker commit 937a98f8ad9e ros_humble:1.0 +``` + + + +等待提交完成,完成后会输出类似以下信息输出: + +``` +sha256:32288d439ffab73505d0754d4c43d8aad83210441b41553118e81ff6ab2887af +``` + +### 修改启动脚本 + +将启动脚本 `ros_humble.sh` 内的启动镜像修改为刚才保存的镜像名称: + + + +``` +#!/bin/bash + +xhost + + +docker run -it \ +--net=host \ +--env="DISPLAY" \ +--env="QT_X11_NO_MITSHM=1" \ +-v /tmp/.X11-unix:/tmp/.X11-unix \ +ros_humble:1.0 /bin/bash +``` + + diff --git a/docs/common/radxa-os/application-dev/virtual-env/_conda_install.mdx b/docs/common/radxa-os/application-dev/virtual-env/_conda_install.mdx new file mode 100644 index 000000000..525c2db2b --- /dev/null +++ b/docs/common/radxa-os/application-dev/virtual-env/_conda_install.mdx @@ -0,0 +1,197 @@ +Conda 是一个开源的包管理和环境管理系统,主要用于数据科学、科学计算和机器学习领域。 + +:::tip +Conda 有 Anaconda 和 Miniconda 两个版本:教程主要介绍 Anaconda 的安装和使用。 + +- Anaconda 是一个完整的发行版,内置丰富的环境包 +- Miniconda 是一个精简的发行版,只包含 Conda 本身,需要手动安装其它环境包 + ::: + +## Conda 特点 + +- 易管理 + +完全隔离的Python环境,使用 `conda` 命令管理环境,自动解决依赖关系。 + +- 跨平台 + +支持 Windows、macOS 和 Linux 系统。 + +- 可移植性 + +支持导出环境配置,便于在其他机器上复制相同的开发环境。 + +- 多语言支持 + +支持多语言环境,不仅限于 Python。 + +## Conda 安装 + +### 下载安装脚本 + +进入 [Anaconda 官网](https://www.anaconda.com/) 下载 Linux ARM64 的安装脚本。 + +### 运行安装脚本 + +下载完成后,进入下载目录,打开终端运行安装脚本:请将脚本换成实际下载的文件名。 + + + +``` +bash Anaconda3-xxx-Linux-aarch64.sh +``` + + + +安装过程中,需要手动按 `Enter` 进入安装步骤。然后输入 `yes` 接受许可协议。 + +终端会输出类似如下的信息: + +``` +Welcome to Anaconda3 xxx + +In order to continue the installation process, please review the license +agreement. +Please, press ENTER to continue + +> > > By continuing installation, you hereby consent to the Anaconda Terms of Service available at https://anaconda.com/legal. + +Do you accept the license terms? [yes|no] + +> > > yes +``` + +最后会让您确认打开终端是否自动初始化 Conda,输入 `yes` 即可。 + +## 验证安装 + +重新打开终端,终端的用户名信息前面会显示 `(base)`,表示 Conda 已经成功安装和初始化。 + +:::tip +base 环境是 Conda 的默认环境,该环境包括一些常用的数据科学和机器学习工具。 +::: + +### 查看 Conda 版本 + +打开终端,使用 `conda --version` 命令查看 Conda 版本: + + + +``` +conda --version +``` + + + +终端输出类似如下的信息表示安装成功: + +``` +conda 24.9.2 +``` + +### 退出 Conda 环境 + +在 Conda 环境下,使用 `conda deactivate` 命令退出 Conda 环境。 + + + +``` +conda deactivate +``` + + + +退出 Conda 环境后,终端的用户名信息前面的 `(base)` 会消失。 + +## 配置 Conda(可选) + +修改 Conda 的配置,设置添加清华大学的镜像源,加快中国国内的下载速度(可选)。 + +### 生成配置文件 + + + +``` +conda config --set show_channel_urls yes +``` + + + +### 修改配置文件 + + + +``` +vi ~/.condarc +``` + + + +配置文件中添加以下内容: + + + +``` +channels: + +- defaults + show_channel_urls: true + default_channels: +- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main +- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r +- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 + custom_channels: + conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud + pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud +``` + + + +### 清理缓存 + +使用 `conda clean` 命令清理缓存和临时文件。 + + + +``` +conda clean -i +``` + + + +### 验证配置 + +打开终端,使用 `conda config --show-sources` 命令查看所有加载的配置文件内容及其优先级顺序。 + + + +``` +conda config --show-sources +``` + + + +配置成功后,终端会输出类似如下的信息: + +``` +==> /home/radxa/anaconda3/.condarc <== +channels: + +- defaults + +==> /home/radxa/.condarc <== +channels: + +- defaults + custom_channels: + conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud + pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud + default_channels: +- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main +- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r +- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 + show_channel_urls: True + +==> envvars <== +allow_softlinks: False +``` diff --git a/docs/common/radxa-os/application-dev/virtual-env/_conda_use.mdx b/docs/common/radxa-os/application-dev/virtual-env/_conda_use.mdx new file mode 100644 index 000000000..6b67ef862 --- /dev/null +++ b/docs/common/radxa-os/application-dev/virtual-env/_conda_use.mdx @@ -0,0 +1,427 @@ +主要介绍一些常用的 Conda 命令。 + +## 查看帮助 + +打开终端,使用 `conda --help` 命令查看 Conda 所有命令的使用方法。 + + + +``` +conda --help +``` + + + +终端会输出类似如下的信息: + +``` +usage: conda [-h] [-v] [--no-plugins] [-V] COMMAND ... + +conda is a tool for managing and deploying applications, environments and packages. + +options: +-h, --help Show this help message and exit. +-v, --verbose Can be used multiple times. Once for detailed output, twice for INFO logging, thrice for DEBUG logging, four times for TRACE +logging. +--no-plugins Disable all plugins that are not built into conda. +-V, --version Show the conda version number and exit. + +commands: +The following built-in and plugins subcommands are available. + +COMMAND +activate Activate a conda environment. +build Build conda packages from a conda recipe. +clean Remove unused packages and caches. +commands List all available conda subcommands (including those from plugins). Generally only used by tab-completion. +compare Compare packages between conda environments. +config Modify configuration values in .condarc. +content-trust Signing and verification tools for Conda +convert Convert pure Python packages to other platforms (a.k.a., subdirs). +create Create a new conda environment from a list of specified packages. +deactivate Deactivate the current active conda environment. +debug Debug the build or test phases of conda recipes. +develop Install a Python package in 'development mode'. Similar to `pip install --editable`. +doctor Display a health report for your environment. +env Create and manage conda environments. +export Export a given environment +index Update package index metadata files. +info Display information about current conda install. +init Initialize conda for shell interaction. +inspect Tools for inspecting conda packages. +install Install a list of packages into a specified conda environment. +list List installed packages in a conda environment. +metapackage Specialty tool for generating conda metapackage. +notices Retrieve latest channel notifications. +pack See `conda pack --help`. +package Create low-level conda packages. (EXPERIMENTAL) +remove (uninstall) Remove a list of packages from a specified conda environment. +rename Rename an existing environment. +render Expand a conda recipe into a platform-specific recipe. +repo See `conda repo --help`. +repoquery Advanced search for repodata. +run Run an executable in a conda environment. +search Search for packages and display associated information using the MatchSpec format. +server See `conda server --help`. +skeleton Generate boilerplate conda recipes. +token See `conda token --help`. +tos A subcommand for viewing, accepting, rejecting, and otherwise interacting with a channel's Terms of Service (ToS). This plugin +periodically checks for updated Terms of Service for the active/selected channels. Channels with a Terms of Service will need to +be accepted or rejected prior to use. Conda will only allow package installation from channels without a Terms of Service or with +an accepted Terms of Service. Attempting to use a channel with a rejected Terms of Service will result in an error. +update (upgrade) Update conda packages to the latest compatible version. + +``` + +## 查看版本信息 + +打开终端,使用 `conda --version` 命令查看 Conda 版本。 + + + +``` +conda --version +``` + + + +终端会输出类似如下的信息: + +``` +conda 24.9.2 +``` + +## 查看当前环境 + +打开终端,使用 `conda info` 命令查看当前环境信息。 + + + +``` +conda info +``` + + + +终端会输出类似如下的信息: + +``` + active environment : base + active env location : /home/radxa/anaconda3 + shell level : 1 + user config file : /home/radxa/.condarc + +populated config files : /home/radxa/anaconda3/.condarc +/home/radxa/.condarc +conda version : 25.5.1 +conda-build version : 25.5.0 +python version : 3.13.5.final.0 +solver : libmamba (default) +virtual packages : **archspec=1=aarch64 +**conda=25.5.1=0 +**glibc=2.36=0 +**linux=5.15.147=0 +\_\_unix=0=0 +base environment : /home/radxa/anaconda3 (writable) +conda av data dir : /home/radxa/anaconda3/etc/conda +conda av metadata url : None +channel URLs : https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/linux-aarch64 +https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/noarch +https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/linux-aarch64 +https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/noarch +https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/linux-aarch64 +https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/noarch +package cache : /home/radxa/anaconda3/pkgs +/home/radxa/.conda/pkgs +envs directories : /home/radxa/anaconda3/envs +/home/radxa/.conda/envs +platform : linux-aarch64 +user-agent : conda/25.5.1 requests/2.32.3 CPython/3.13.5 Linux/5.15.147 debian/11.11 glibc/2.36 solver/libmamba conda-libmamba-solver/25.4.0 libmambapy/2.0.5 aau/0.7.1 c/. s/. e/. +UID:GID : 1001:1001 +netrc file : None +offline mode : False +``` + +## 查看所有环境 + +打开终端,使用 `conda env list` 命令查看所有环境。 + + + +``` +conda env list +``` + + + +终端会输出类似如下的信息:表示当前系统只有 base 环境。 + +``` +# conda environments: + +# + +base \* /home/radxa/anaconda3 +``` + +## 创建环境 + +### 创建新环境 + + + +``` +conda create --name + +# 示例:创建一个名为 my_env 的环境 + +conda create --name my_env +``` + + + +创建环境后,终端会输出类似如下的信息:创建过程中需要确认是否继续。 + +``` +Channels: + +- defaults + Platform: linux-aarch64 + Collecting package metadata (repodata.json): done + Solving environment: done + +## Package Plan + +environment location: /home/radxa/anaconda3/envs/my_env + +Proceed ([y]/n)? y + +Downloading and Extracting Packages: + +Preparing transaction: done +Verifying transaction: done +Executing transaction: done + +# + +# To activate this environment, use + +# + +# $ conda activate my_env + +# + +# To deactivate an active environment, use + +# + +# $ conda deactivate +``` + +### 创建指定 Python 版本的环境 + + + +``` +conda create --name python= + +# 示例:创建一个名为 my_env_py39 的 Python 3.9 环境 + +conda create --name my_env_py39 python=3.9 +``` + + + +创建环境后,终端会输出类似如下的信息:创建过程中需要输入 `y` 确认是否继续操作。 + +``` +Channels: + +- defaults + Platform: linux-aarch64 + Collecting package metadata (repodata.json): done + Solving environment: done + +## Package Plan + +environment location: /home/radxa/anaconda3/envs/my_env_py39 + +added / updated specs: - python=3.9 + +The following packages will be downloaded: + + package | build + ---------------------------|----------------- + _libgcc_mutex-0.1 | main 2 KB defaults + _openmp_mutex-5.1 | 51_gnu 1.4 MB defaults + bzip2-1.0.8 | h998d150_6 210 KB defaults + ca-certificates-2025.2.25 | hd43f75c_0 129 KB defaults + expat-2.7.1 | h419075a_0 161 KB defaults + libffi-3.4.4 | h419075a_1 140 KB defaults + libgcc-ng-11.2.0 | h1234567_1 1.3 MB defaults + libgomp-11.2.0 | h1234567_1 466 KB defaults + libstdcxx-ng-11.2.0 | h1234567_1 779 KB defaults + libxcb-1.17.0 | hf66535e_0 433 KB defaults + ncurses-6.4 | h419075a_0 1.1 MB defaults + openssl-3.0.16 | h998d150_0 5.2 MB defaults + pip-25.1 | pyhc872135_2 1.3 MB defaults + pthread-stubs-0.3 | hfd63f10_1 7 KB defaults + python-3.9.23 | h89e7a61_0 24.2 MB defaults + readline-8.2 | h998d150_0 381 KB defaults + setuptools-78.1.1 | py39hd43f75c_0 1.6 MB defaults + sqlite-3.45.3 | h998d150_0 1.5 MB defaults + tk-8.6.14 | hb5ae6a8_1 3.5 MB defaults + tzdata-2025b | h04d1e81_0 116 KB defaults + wheel-0.45.1 | py39hd43f75c_0 114 KB defaults + xorg-libx11-1.8.12 | hf66535e_1 928 KB defaults + xorg-libxau-1.0.12 | hf66535e_0 14 KB defaults + xorg-libxdmcp-1.1.5 | hf66535e_0 19 KB defaults + xorg-xorgproto-2024.1 | h998d150_1 582 KB defaults + xz-5.6.4 | h998d150_1 573 KB defaults + zlib-1.2.13 | h998d150_1 113 KB defaults + ------------------------------------------------------------ + Total: 47.1 MB + +The following NEW packages will be INSTALLED: + +\_libgcc_mutex anaconda/pkgs/main/linux-aarch64::\_libgcc_mutex-0.1-main +\_openmp_mutex anaconda/pkgs/main/linux-aarch64::\_openmp_mutex-5.1-51_gnu +bzip2 anaconda/pkgs/main/linux-aarch64::bzip2-1.0.8-h998d150_6 +ca-certificates anaconda/pkgs/main/linux-aarch64::ca-certificates-2025.2.25-hd43f75c_0 +expat anaconda/pkgs/main/linux-aarch64::expat-2.7.1-h419075a_0 +libgcc-ng anaconda/pkgs/main/linux-aarch64::libgcc-ng-11.2.0-h1234567_1 +libgomp anaconda/pkgs/main/linux-aarch64::libgomp-11.2.0-h1234567_1 +libstdcxx-ng anaconda/pkgs/main/linux-aarch64::libstdcxx-ng-11.2.0-h1234567_1 +libxcb anaconda/pkgs/main/linux-aarch64::libxcb-1.17.0-hf66535e_0 +ncurses anaconda/pkgs/main/linux-aarch64::ncurses-6.4-h419075a_0 +openssl anaconda/pkgs/main/linux-aarch64::openssl-3.0.16-h998d150_0 +pip anaconda/pkgs/main/noarch::pip-25.1-pyhc872135_2 +pthread-stubs anaconda/pkgs/main/linux-aarch64::pthread-stubs-0.3-hfd63f10_1 +python anaconda/pkgs/main/linux-aarch64::python-3.9.23-h89e7a61_0 +readline anaconda/pkgs/main/linux-aarch64::readline-8.2-h998d150_0 +setuptools anaconda/pkgs/main/linux-aarch64::setuptools-78.1.1-py39hd43f75c_0 +sqlite anaconda/pkgs/main/linux-aarch64::sqlite-3.45.3-h998d150_0 +tk anaconda/pkgs/main/linux-aarch64::tk-8.6.14-hb5ae6a8_1 +tzdata anaconda/pkgs/main/noarch::tzdata-2025b-h04d1e81_0 +wheel anaconda/pkgs/main/linux-aarch64::wheel-0.45.1-py39hd43f75c_0 +xorg-libx11 anaconda/pkgs/main/linux-aarch64::xorg-libx11-1.8.12-hf66535e_1 +xorg-libxau anaconda/pkgs/main/linux-aarch64::xorg-libxau-1.0.12-hf66535e_0 +xorg-libxdmcp anaconda/pkgs/main/linux-aarch64::xorg-libxdmcp-1.1.5-hf66535e_0 +xorg-xorgproto anaconda/pkgs/main/linux-aarch64::xorg-xorgproto-2024.1-h998d150_1 +xz anaconda/pkgs/main/linux-aarch64::xz-5.6.4-h998d150_1 +zlib anaconda/pkgs/main/linux-aarch64::zlib-1.2.13-h998d150_1 + +Proceed ([y]/n)? y + +Downloading and Extracting Packages: + +Preparing transaction: done +Verifying transaction: done +Executing transaction: done + +# + +# To activate this environment, use + +# + +# $ conda activate my_env_py39 + +# + +# To deactivate an active environment, use + +# + +# $ conda deactivate +``` + +## 激活环境 + + + +``` +conda activate + +# 示例:激活 my_env_py39 环境 + +conda activate my_env_py39 +``` + + + +激活环境后,终端用户名前会提示当前的 conda 环境名称。 + +## 退出环境 + + + +``` +conda deactivate +``` + + + +## 删除环境 + + + +``` +conda remove --name --all + +# 示例:删除 my_env_py39 环境 + +conda remove --name my_env_py39 --all +``` + + + +删除环境后,终端会输出类似如下的信息:中间需要您输入 `y` 确认删除操作。 + +``` +Remove all packages in environment /home/radxa/anaconda3/envs/my_env_py39: + +## Package Plan + +environment location: /home/radxa/anaconda3/envs/my_env_py39 + +The following packages will be REMOVED: + +\_libgcc_mutex-0.1-main +\_openmp_mutex-5.1-51_gnu +bzip2-1.0.8-h998d150_6 +ca-certificates-2025.2.25-hd43f75c_0 +expat-2.7.1-h419075a_0 +libffi-3.4.4-h419075a_1 +libgcc-ng-11.2.0-h1234567_1 +libstdcxx-ng-11.2.0-h1234567_1 +libxcb-1.17.0-hf66535e_0 +ncurses-6.4-h419075a_0 +openssl-3.0.16-h998d150_0 +pip-25.1-pyhc872135_2 +pthread-stubs-0.3-hfd63f10_1 +python-3.9.23-h89e7a61_0 +readline-8.2-h998d150_0 +setuptools-78.1.1-py39hd43f75c_0 +sqlite-3.45.3-h998d150_0 +tk-8.6.14-hb5ae6a8_1 +tzdata-2025b-h04d1e81_0 +wheel-0.45.1-py39hd43f75c_0 +xorg-libx11-1.8.12-hf66535e_1 +xorg-libxau-1.0.12-hf66535e_0 +xorg-libxdmcp-1.1.5-hf66535e_0 +xorg-xorgproto-2024.1-h998d150_1 +xz-5.6.4-h998d150_1 +zlib-1.2.13-h998d150_1 + +Proceed ([y]/n)? y + +Downloading and Extracting Packages: + +Preparing transaction: done +Verifying transaction: done +Executing transaction: done +Everything found within the environment (/home/radxa/anaconda3/envs/my_env_py39), including any conda environment configurations and any non-conda files, will be deleted. Do you wish to continue? +(y/[n])? y +``` diff --git a/docs/common/radxa-os/application-dev/virtual-env/_docker_install.mdx b/docs/common/radxa-os/application-dev/virtual-env/_docker_install.mdx new file mode 100644 index 000000000..61eb5d6b4 --- /dev/null +++ b/docs/common/radxa-os/application-dev/virtual-env/_docker_install.mdx @@ -0,0 +1,79 @@ +瑞莎 Debian 系统在内核已经开启 Docker 相关的配置,只需安装 Docker 应用即可开始使用。 + +:::tip +目前国内(中国)用户无法访问 Docker Hub,需要自行配置 Docker 镜像源或使用代理访问 +::: + +## Docker 特点 + +- 易管理 + +轻量级容器化技术,使用 Docker 命令管理容器和镜像,依赖隔离,简化部署流程。 + +- 跨平台 + +支持 Windows、macOS 和 Linux 系统,可在多种平台上运行和部署容器。 + +- 可移植性 + +通过 Dockerfile 和镜像实现环境一致性,便于在不同机器或云平台上快速迁移和部署。 + +- 高效资源利用 + +基于容器化技术,共享主机内核,资源占用低,启动速度快,适合微服务架构。 + +## 安装 Docker + +终端输入以下命令安装 Docker: + + + +``` +sudo apt update +sudo apt install docker.io +``` + + + +## 配置 iptables + + + +``` +sudo update-alternatives --set iptables /usr/sbin/iptables-legacy +sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy +``` + + + +重启系统后,Docker 配置生效。 + +## 验证安装 + + + +``` +docker --version +``` + + + +终端输出类似如下的信息表示安装成功: + +``` +Docker version 20.10.24+dfsg1, build 297e128 +``` + +## 添加访问权限 + +终端输入以下命令添加系统当前用户对 Docker 守护程序的访问权限:不需要使用 sudo 命令就可以使用 Docker 命令。 + + + +``` +sudo usermod -aG docker $USER +``` + + + +重启系统后,Docker 配置生效。 diff --git a/docs/common/radxa-os/application-dev/virtual-env/_docker_use.mdx b/docs/common/radxa-os/application-dev/virtual-env/_docker_use.mdx new file mode 100644 index 000000000..47aee016c --- /dev/null +++ b/docs/common/radxa-os/application-dev/virtual-env/_docker_use.mdx @@ -0,0 +1,423 @@ +主要通过 Docker 常用命令来演示 Docker 的使用方法,以下命令均是在 Radxa Cubie A7A 的终端命令行运行。 + +:::tip +镜像(Image):镜像包含了应用程序及其运行环境(包括依赖、库、配置文件等)的只读模板。 + +容器(Container):容器是镜像的运行实例,在镜像的基础上创建的一个可执行环境,包含应用程序和所有依赖,但与主机系统隔离。 +::: + +## 查看帮助 + +可以通过 Docker 内置的帮助命令查看 Docker 所有命令的使用方法。 + + + +``` +docker --help +``` + + + +终端会输出类似如下信息: + +``` +Usage: docker [OPTIONS] COMMAND + +A self-sufficient runtime for containers + +Options: +--config string Location of client config files (default "/home/radxa/.docker") +-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context +set with "docker context use") +-D, --debug Enable debug mode +-H, --host list Daemon socket(s) to connect to +-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") +--tls Use TLS; implied by --tlsverify +--tlscacert string Trust certs signed only by this CA (default "/home/radxa/.docker/ca.pem") +--tlscert string Path to TLS certificate file (default "/home/radxa/.docker/cert.pem") +--tlskey string Path to TLS key file (default "/home/radxa/.docker/key.pem") +--tlsverify Use TLS and verify the remote +-v, --version Print version information and quit + +Management Commands: +builder Manage builds +completion Generate the autocompletion script for the specified shell +config Manage Docker configs +container Manage containers +context Manage contexts +image Manage images +manifest Manage Docker image manifests and manifest lists +network Manage networks +node Manage Swarm nodes +plugin Manage plugins +secret Manage Docker secrets +service Manage services +stack Manage Docker stacks +swarm Manage Swarm +system Manage Docker +trust Manage trust on Docker images +volume Manage volumes + +Commands: +attach Attach local standard input, output, and error streams to a running container +build Build an image from a Dockerfile +commit Create a new image from a container's changes +cp Copy files/folders between a container and the local filesystem +create Create a new container +diff Inspect changes to files or directories on a container's filesystem +events Get real time events from the server +exec Run a command in a running container +export Export a container's filesystem as a tar archive +history Show the history of an image +images List images +import Import the contents from a tarball to create a filesystem image +info Display system-wide information +inspect Return low-level information on Docker objects +kill Kill one or more running containers +load Load an image from a tar archive or STDIN +login Log in to a Docker registry +logout Log out from a Docker registry +logs Fetch the logs of a container +pause Pause all processes within one or more containers +port List port mappings or a specific mapping for the container +ps List containers +pull Pull an image or a repository from a registry +push Push an image or a repository to a registry +rename Rename a container +restart Restart one or more containers +rm Remove one or more containers +rmi Remove one or more images +run Run a command in a new container +save Save one or more images to a tar archive (streamed to STDOUT by default) +search Search the Docker Hub for images +start Start one or more stopped containers +stats Display a live stream of container(s) resource usage statistics +stop Stop one or more running containers +tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE +top Display the running processes of a container +unpause Unpause all processes within one or more containers +update Update configuration of one or more containers +version Show the Docker version information +wait Block until one or more containers stop, then print their exit codes + +Run 'docker COMMAND --help' for more information on a command. + +To get more help with docker, check out our guides at https://docs.docker.com/go/guides/ +``` + +## 查看 Docker 系统信息 + +使用 `docker info` 命令可以查看 Docker 系统信息,包括 Docker 版本、系统配置、存储驱动、网络配置等。 + + + +``` +docker info +``` + + + +终端会输出类似如下的信息: + +``` +Client: +Context: default +Debug Mode: false + +Server: +Containers: 0 +Running: 0 +Paused: 0 +Stopped: 0 +Images: 1 +Server Version: 20.10.24+dfsg1 +Storage Driver: overlay2 +Backing Filesystem: extfs +Supports d_type: true +Native Overlay Diff: true +userxattr: false +Logging Driver: json-file +Cgroup Driver: systemd +Cgroup Version: 2 +Plugins: +Volume: local +Network: bridge host ipvlan macvlan null overlay +Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog +Swarm: inactive +Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc +Default Runtime: runc +Init Binary: docker-init +containerd version: 1.6.20~ds1-1+deb12u1 +runc version: 1.1.5+ds1-1+deb12u1 +init version: +Security Options: +seccomp +Profile: default +cgroupns +Kernel Version: 6.1.84-7-rk2410-nocsf +Operating System: Debian GNU/Linux 12 (bookworm) +OSType: linux +Architecture: aarch64 +CPUs: 8 +Total Memory: 3.829GiB +Name: rock-4d-spi +ID: NOPY:K5AM:5IDH:CS7I:VUGO:2U4I:YCZZ:MHNC:SV3D:4GEE:X55W:YQZU +Docker Root Dir: /var/lib/docker +Debug Mode: false +Labels: +Experimental: false +Insecure Registries: +127.0.0.0/8 +Live Restore Enabled: false +``` + +## 查看版本信息 + +只看 Docker 版本信息,可以使用 `docker --version` 命令。 + + + +``` +docker --version +``` + + + +终端会输出类似如下的信息: + +``` +Docker version 20.10.24+dfsg1, build 297e128 +``` + +## 拉取镜像 + +使用 `docker pull` 命令可以从云端(默认是 Docker Hub)拉取镜像。 + + + +``` +docker pull + +# 示例:拉取 hello-world 最新镜像 + +docker pull hello-world +``` + + +拉取镜像成功后,终端会输出类似如下的信息: + +``` +Using default tag: latest +latest: Pulling from library/hello-world +c9c5fd25a1bd: Pull complete +Digest: sha256:0b6a027b5cf322f09f6706c754e086a232ec1ddba835c8a15c6cb74ef0d43c29 +Status: Downloaded newer image for hello-world:latest +docker.io/library/hello-world:latest +``` + +## 运行容器 + +若本地没有运行的镜像,Docker 会自动从云端拉取镜像,然后运行容器。 + + + +``` +docker run + +# 示例:运行 hello-world 最新镜像 + +docker run hello-world +``` + + + +运行容器成功后,终端会输出类似如下的信息: + +``` +Hello from Docker! +This message shows that your installation appears to be working correctly. + +To generate this message, Docker took the following steps: + +1. The Docker client contacted the Docker daemon. +2. The Docker daemon pulled the "hello-world" image from the Docker Hub. + (arm64v8) +3. The Docker daemon created a new container from that image which runs the + executable that produces the output you are currently reading. +4. The Docker daemon streamed that output to the Docker client, which sent it + to your terminal. + +To try something more ambitious, you can run an Ubuntu container with: +$ docker run -it ubuntu bash + +Share images, automate workflows, and more with a free Docker ID: +https://hub.docker.com/ + +For more examples and ideas, visit: +https://docs.docker.com/get-started/ +``` + +### 以交互模式运行容器 + +在交互模式下,容器会保持运行状态,你可以直接在终端命令行操作容器,直到你输入 `exit` 退出容器。 + + + +``` +docker run -it /bin/bash + +# 示例:以交互模式运行 ubuntu:24.04 镜像 + +docker run -it ubuntu:24.04 /bin/bash +``` + + + +运行容器成功后,终端会输出类似如下的信息:其中 `8a18a7ee0838` 为容器 ID。 + +``` +root@8a18a7ee0838:/# +``` + +容器内输入 `exit` 可以退出容器。 + +### 多终端进入同一个容器 + + +``` +docker exec -it /bin/bash +# 示例:根据正在运行的容器 ID 进入容器 +docker exec -it 8a18a7ee0838 /bin/bash +``` + + + +## 查看镜像 + + + +``` +docker images +``` + + + +终端会输出类似如下的信息: + +``` +REPOSITORY TAG IMAGE ID CREATED SIZE +ubuntu 24.04 9d45648b4030 11 days ago 101MB +hello-world latest f1f77a0f96b7 4 months ago 5.2kB +``` + +## 查看容器 + + + +``` +docker ps -a +``` + + + +终端会输出类似如下的信息:我们可以通过 `status` 来判断容器是否正在运行。 + +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +8a18a7ee0838 ubuntu:24.04 "/bin/bash" 2 minutes ago Up About a minute frosty_beaver +d1799e93de85 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago epic_gagarin +``` + +## 保存容器 + +若你对正在运行的容器做了修改,可以使用 `docker commit` 命令保存容器为镜像,以后可以基于该镜像快速创建容器。 + + + +``` +docker commit + +# 示例:将 id 为 8a18a7ee0838 的容器保存为 ubuntu_24_v1 镜像 + +docker commit 8a18a7ee0838 ubuntu_24_v1 +``` + + + +保存成功后,终端会输出类似如下的信息: + +``` +sha256:be234207cfb6841bbef6bb4639ac2cc035a4bbebdcf5e74a08a8db327a57d569 +``` + +## 停止容器 + +若你终端正处于正在运行的容器内,可以输入 `exit` 退出容器。 + +若你不在正在运行的容器内,可以使用 `docker stop` 命令停止容器。 + + + +``` +docker stop + +# 示例:停止 id 为 8a18a7ee0838 的容器 + +docker stop 8a18a7ee0838 +``` + + + +停止容器成功后,终端会输出类似如下的信息: + +``` +8a18a7ee0838 +``` + +## 清理容器 + +该命令只会清理停止的容器,不会影响正在运行的容器。 + + + +``` +docker container prune +``` + + + +终端会输出类似如下的信息:输入命令后需要输入 `y` 确认执行。 + +``` +WARNING! This will remove all stopped containers. +Are you sure you want to continue? [y/N] y +Deleted Containers:yun3 +cbb96ce305f30647e03012f979ca604ec31b93f4b1cead64b48d2db85d139171 + +Total reclaimed space: 5B +``` + +## 删除镜像 + +使用 `docker rmi` 命令可以删除镜像。 + + + +``` +docker rmi + +# 示例:删除 ubuntu:24.04 镜像 + +docker rmi ubuntu:24.04 +``` + + + +删除镜像成功后,终端会输出类似如下的信息: + +``` +Untagged: ubuntu:24.04 +Untagged: ubuntu@sha256:b59d21599a2b151e23eea5f6602f4af4d7d31c4e236d22bf0b62b86d2e386b8f +Deleted: sha256:9d45648b40307b523984e200d90f737b39a705c335fbf484113d4ad0660d97a6 +Deleted: sha256:c2f2f00da4ebbfa69fd966cc712f4d400283f6ade9fcd8ebb4801dfae55f86f1 +``` diff --git a/docs/common/radxa-os/system-config/_app_usage.mdx b/docs/common/radxa-os/system-config/_app_usage.mdx new file mode 100644 index 000000000..05278ad81 --- /dev/null +++ b/docs/common/radxa-os/system-config/_app_usage.mdx @@ -0,0 +1,88 @@ +import { Image } from "@site/src/utils/docs"; + +介绍如何在瑞莎主板上使用 dpkg 和 apt 命令安装和使用应用。 + +- dpkg 命令 + +主要用于安装本地 deb 包。 + +- apt 命令 + +主要用于从软件源安装软件包。 + +## 社交应用 + +### QQ + +#### QQ 介绍 + +QQ 是一款由腾讯开发的即时通讯软件,支持文字、图片、语音、视频等多种沟通方式。 + +#### QQ 安装 + +通过[腾讯 QQ 官网](https://im.qq.com/linuxqq/index.shtml)下载 arm64 架构的 deb 包,然后通过 dpkg 安装。 + +:::caution +您可以通过 `uname -a` 命令查看当前系统的架构。 +::: + +将实际下载的 deb 包名称替换到命令中。 + + + +``` +sudo dpkg -i QQ_xxx_arm64.deb +``` + + + +#### QQ 使用 + +双击 QQ 图标或者终端命令行运行下面命令启动。 + + + +``` +qq +``` + + + + + +## 办公应用 + +### LibreOffice + +#### LibreOffice 介绍 + +LibreOffice 是一款由文档基金会(The Document Foundation)开发的免费开源跨平台办公软件,支持文字处理、电子表格、演示文稿、矢量绘图、数据库管理、公式编辑等多种办公需求,兼容 Microsoft Office 格式。 + +#### LibreOffice 安装 + +通过 apt 安装 LibreOffice。 + + + +``` +sudo apt update +sudo apt install libreoffice -y +``` + + + +#### LibreOffice 使用 + +在应用搜索栏输入 `LibreOffice`,然后选择对应软件启动。 + + diff --git a/docs/common/radxa-os/system-config/_audio_usage.mdx b/docs/common/radxa-os/system-config/_audio_usage.mdx new file mode 100644 index 000000000..d01f814f7 --- /dev/null +++ b/docs/common/radxa-os/system-config/_audio_usage.mdx @@ -0,0 +1,59 @@ +import { Image } from "@site/src/utils/docs"; + +主要介绍如何在瑞莎主板上使用音频设备。 + +## 音频设备 + +系统默认声音输出优先级为:蓝牙音频 > 耳机 > HDMI 音频。 + +手动选择音频输出设备后,则该音频设备为最高优先级。 + +## 音频设置 + +通过图形界面和命令行两种方式来对音频设备进行设置。 + + + + + +点击桌面右下角的音频图标,选择需要的音频输出设备,滑动音频设备的音量条来调整音量。 + +① : 点击音频图标 + +② : 选择音频输出设备 + +③ : 滑动音频设备的音量条来调整音量 + + + + + + + +通过 `alsamixer` 命令行工具来设置音频设备,终端输入下面命令即可打开 `alsamixer` UI 界面。 + + + +``` +alsamixer +``` + + + +通过方向键 `up` 和 `down` 来调整音量。 + + + + + + diff --git a/docs/common/radxa-os/system-config/_auto_login.mdx b/docs/common/radxa-os/system-config/_auto_login.mdx new file mode 100644 index 000000000..063b6795d --- /dev/null +++ b/docs/common/radxa-os/system-config/_auto_login.mdx @@ -0,0 +1,61 @@ +import { Image } from "@site/src/utils/docs"; + +主要介绍如何使用瑞莎主板上使用 `Rsetup` 工具来设置桌面自动登录。 + +:::tip +设置桌面自动登录可以避免每次启动系统都需要输入用户名和密码。 + +对于 `Rsetup` 工具的使用,可以参考: + +- [Rsetup 工具](./rsetup) + ::: + +## Rsetup 工具 + +打开终端,输入 `sudo rsetup` 命令打开 `Rsetup` 工具: + + + +``` +sudo rsetup +``` + + + +
+ +
+ +## 设置自动登录 + +进入 `Rsetup` 工具后,选择 `User Settings` -> `Configure auto login`选项,使能 `sddm.service`,然后按照 `Rsetup` 工具提示完成剩下操作。 + +- User Settings + +
+ +
+ +- Configure auto login + +
+ +
+ +- SDDM + +
+ +
diff --git a/docs/common/radxa-os/system-config/_blue_usage.mdx b/docs/common/radxa-os/system-config/_blue_usage.mdx new file mode 100644 index 000000000..dfe91d67c --- /dev/null +++ b/docs/common/radxa-os/system-config/_blue_usage.mdx @@ -0,0 +1,251 @@ +import { Image } from "@site/src/utils/docs"; + +主要介绍如何在瑞莎主板上使用蓝牙进行设备的连接、配对和使用。 + + + +通过系统自带的蓝牙管理工具来管理蓝牙设备。 + +- 开启蓝牙功能 + +① : 点击 `System Settings` 图标 + +② : 点击 `Bluetooth` 选项 + +③ : 点击 `Enable` 选项开启蓝牙功能 + + + +- 连接蓝牙设备 + +① : 点击 `Add ...` 选项会自动扫描周围的蓝牙设备 + +② : 在周围的蓝牙设备列表中找到你需要连接的蓝牙设备 + +③ : 点击 `Next` 选项连接蓝牙设备 + + + +- 配对蓝牙设备 + +连接蓝牙设备的过程中,需要进行蓝牙设备的配对,按照系统提示完成配对操作。 + + + +- 连接成功 + +蓝牙设备连接成功后,系统会出现提示信息。 + + + + + + +通过命令行来管理蓝牙设备。 + +- 启动蓝牙服务 + + + +``` +sudo systemctl start bluetooth +``` + + + +- 设置开机自启 + + + +``` +sudo systemctl enable bluetooth +``` + + + +- 检查服务状态 + + + +``` +sudo systemctl status bluetooth +``` + + + +- 连接和配对蓝牙设备 + +使用 `bluetoothctl` 命令行工具来管理蓝牙设备。 + +:::tip +终端输入 `bluetoothctl` 会进入交互式命令行界面。 + +退出 `bluetoothctl` 命令行界面,输入 `exit`。 +::: + + + +``` +bluetoothctl +``` + + + +- 打开蓝牙适配器 + +在 `bluetoothctl` 交互命令行界面输入 `power on` 打开蓝牙。 + + + +``` +power on +``` + + + +- 启用代理 + +在 `bluetoothctl` 交互命令行界面输入 `agent on` 启用代理。 + + + +``` +agent on +``` + + + +- 扫描蓝牙设备 + +在 `bluetoothctl` 交互命令行界面输入 `scan on` 扫描蓝牙设备。 + + + +``` +scan on +``` + + + +扫描到的蓝牙设备会在终端出现蓝牙设备的物理地址和名称,类似输出以下信息:其中 `EC:30:B3:40:0A:20` 为蓝牙设备的物理地址,`Redmi K50 Ultra` 为蓝牙设备的名称。 + +``` +[NEW] Device EC:30:B3:40:0A:20 Redmi K50 Ultra +``` + +- 停止扫描 + +如果不停止扫描,`bluetoothctl` 交互命令行界面会一直处于扫描状态,建议自动扫描几次后停止扫描,然后查找自己需要连接的蓝牙设备物理地址。 + + + +``` +scan off +``` + + + +- 配对设备 + +在 `bluetoothctl` 交互命令行界面输入 `pair ` 配对蓝牙设备:配对过程需要自己手动确认,根据蓝牙设备的提示进行操作。 + + + +``` +pair + +# 示例 +pair EC:30:B3:40:0A:20 +``` + + + +- 信任设备 + + + +``` +trust + +# 示例 +trust EC:30:B3:40:0A:20 +``` + + + +- 连接设备 + +在 `bluetoothctl` 交互命令行界面输入 `connect ` 连接蓝牙设备。 + + + +``` +connect + +# 示例 +connect EC:30:B3:40:0A:20 +``` + + + +- 断开设备 + +在 `bluetoothctl` 交互命令行界面输入 `disconnect ` 断开蓝牙设备。 + + + +``` +disconnect + +# 示例 +disconnect EC:30:B3:40:0A:20 +``` + + + +- 取消配对 + + + +``` +remove + +# 示例 +remove EC:30:B3:40:0A:20 +``` + + + +- 关闭蓝牙适配器 + + + +``` +power off +``` + + + + + + diff --git a/docs/common/radxa-os/system-config/_rsetup.mdx b/docs/common/radxa-os/system-config/_rsetup.mdx new file mode 100644 index 000000000..4e8c2d3b8 --- /dev/null +++ b/docs/common/radxa-os/system-config/_rsetup.mdx @@ -0,0 +1,392 @@ +Rsetup 是一个适用于 Radxa OS 的系统配置工具,它可以帮助用户轻松地进行系统配置,包括系统设置、硬件设置、软件设置、网络设置、用户设置、语言设置等。 + +## Rsetup 说明 + +在终端命令行运行 `rsetup` 命令启动 Rsetup 工具。 + +:::tip 使用指南 + +- 选中选项 : 对应选项会高亮显示 +- 确认选择 : 按 `Enter` +- 取消选择 : 按 `ESC` +- 切换选项 : 按 `Up` 、 `Down` 、 `Left` 、 `Right` 控制 +- 多选界面 : 按 `Space` 选择,按 `Enter` 确认选择;选择对应功能后,对应选项框会出现一个 `*` ,表示该选项已启用 + ::: + + + +``` +sudo rsetup +``` + + + +## Rsetup 界面 + +启动 Rsetup 工具后,会出现对应的选项列表:可能会因为版本差异,界面 / 选项可能会有所不同,请以实际情况为准! + +
+ +
+ +## Rsetup 选项 + +### System + +System 选项主要用于系统更新、默认启动目标、引导加载程序管理等。 + +
+ +
+ +#### System Update + +`System Update` 选项用于更新系统,相比于 `apt update && apt upgrade` 命令来更新系统更加安全。 + +说明:`apt update && apt upgrade` 命令来更新系统可能会导致更新不完全或者系统异常。 + +
+ +
+ +#### Change default Boot target + +`Change default Boot target` 选项用于修改启动方式,可选图形化或命令行。 + +
+ +
+ +#### Bootloader Management + +`Bootloader Management` 选项用于管理引导加载程序,可以用于更新和擦除 Bootloader。 + +
+ +
+ +### Hardware + +Hardware 选项主要用于管理板载硬件,包括视频捕获设备、LED 控制、GPIO 控制等。 + +
+ +
+ +#### Video capture devices + +`Video capture devices` 选项用于管理视频捕获设备,可以测试摄像头是否正常工作。 + +
+ +
+ +#### GPIO LEDs + +`GPIO LEDs` 选项用于管理板载 LED 的触发方式,可以修改指示灯闪烁模式。 + +
+ +
+ +#### RGB LEDs + +`RGB LEDs` 选项用于管理板载 RGB LED 的触发方式,可以修改指示灯颜色和闪烁模式。 + +
+ +
+ +#### Thermal governor + +`Thermal governor` 选项用于管理外接散热器的散热策略,如控制风扇接口的外接散热风扇的转速。 + +
+ +
+ +#### Configure DSI display mirroring + +`Configure DSI display mirroring` 选项用于配置 DSI 显示镜像,可以修改显示镜像模式。 + +
+ +
+ +#### 40-pin GPIO + +`40-pin GPIO` 选项用于管理 40-pin GPIO 的状态,可以修改 / 读取 GPIO 的引脚高低电平状态。 + +
+ +
+ +#### USB OTG services + +`USB OTG services` 选项用于管理 USB OTG 服务,可以修改 OTG 服务的配置。 + +
+ +
+ +### Overlays + +Overlays 选项主要用于管理设备树覆盖(Device Tree Overlays)。 + +
+ +
+ +#### Manage overlays + +`Manage overlays` 选项可以启用或禁用特定的硬件功能。 + +
+ +
+ +#### View overlays info + +`View overlays info` 选项可以查看设备树覆盖(Device Tree Overlays)的详细信息。 + +
+ +
+ +#### Install 3rd party overlays + +`Install 3rd party overlays` 选项可以安装第三方设备树覆盖(Device Tree Overlays)。 + +
+ +
+ +#### Rebuild overlays + +`Rebuild overlays` 选项可以重新构建设备树覆盖(Device Tree Overlays)。 + +
+ +
+ +### Connectivity + +Connectivity 选项主要用于管理网络连接,包括有线网络和无线网络的设置。 + +
+ +
+ +#### Edit a connection + +`Edit a connection` 选项可以编辑网络连接的配置。 + +
+ +
+ +#### Activate a connection + +`Activate a connection` 选项可以激活网络连接。 + +
+ +
+ +#### Set system hostname + +`Set system hostname` 选项可以设置系统的主机名。 + +
+ +
+ +### User Settings + +User Settings 选项用于管理系统当前用户名、密码以及设置自动登录。 + +
+ +
+ +#### Change Password + +`Change Password` 选项用于修改当前用户的密码。 + +
+ +
+ +#### Change Hostname + +`Change Hostname` 选项用于修改当前系统的主机名。 + +
+ +
+ +#### Configure auto login + +`Configure auto login` 选项用于设置自动登录。 + +
+ +
+ +### Localization + +Localization 选项用于设置系统时区、区域以及 WiFi 国家。 + +
+ +
+ +#### Change Timezone + +`Change Timezone` 选项用于修改当前系统的时区。 + +
+ +
+ +#### Change Locale + +`Change Locale` 选项用于修改当前系统的区域。 + +
+ +
+ +#### Change Wi-Fi Country + +`Change Wi-Fi Country` 选项用于修改当前系统的 WiFi 国家。 + +
+ +
+ +### Common Tasks + +Common Tasks 选项用于执行一些常见的任务,如安装宝塔面板等。 + +
+ +
+ +
+ +
+ +### About + +About 选项用于查看 Rsetup 工具的信息。 + +
+ +
+ +
+ +
diff --git a/docs/common/radxa-os/system-config/_ssh_remote.mdx b/docs/common/radxa-os/system-config/_ssh_remote.mdx new file mode 100644 index 000000000..b7011a029 --- /dev/null +++ b/docs/common/radxa-os/system-config/_ssh_remote.mdx @@ -0,0 +1,224 @@ +## 使用前提 + +SSH 远程需要双方设备处于同一局域网下,且目标设备需要开启 SSH 服务。 + +:::tip +我们提供的系统镜像默认开启 SSH 服务,如果未安装或者开启 SSH 服务,你可以按照教程进行操作! +::: + +## 安装 OpenSSH + +SSH 远程控制需要安装 OpenSSH, 在主板的终端运行以下命令安装: + + + +``` +sudo apt update && sudo apt install openssh-server -y +``` + + + +### 启动 SSH 服务 + +在主板的终端运行以下命令启动 SSH 服务: + + + +``` +sudo systemctl start ssh +``` + + + +### 设置 SSH 服务开机自启 + +在主板的终端运行以下命令设置 SSH 服务开机自启: + + + +``` +sudo systemctl enable ssh +``` + + + +### 检查 SSH 服务状态 + +在主板的终端运行以下命令检查 SSH 服务状态: + + + +``` +sudo systemctl status ssh +``` + + + +终端会输出类似信息: 提示您 SSH 服务是否自启动和当前运行状态。 + +``` +● ssh.service - OpenBSD Secure Shell server +Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) +Active: active (running) since Sat 2000-01-01 00:14:50 UTC; 25 years 5 months ago +Docs: man:sshd(8) +man:sshd_config(5) +Main PID: 518 (sshd) +CPU: 284ms +CGroup: /system.slice/ssh.service +└─518 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups +``` + +## SSH 远程控制 + +您可以通过终端命令行或者使用 Tabby 软件进行 SSH 远程登录。 + + + + + +在另一台设备上打开终端,输入以下命令进行远程登录: + + + +``` +ssh @ +# 示例 + +ssh radxa@192.168.2.186 +``` + + + +其中,`` 和 `` 分别是目标设备的实际用户名和 IP 地址。 + +连接过程中需要你输入 `yes` 确认连接。 + +
+ +
+
+ + + +Tabby 是一款功能强大的跨平台串口调试工具,支持串口、SSH 等多种协议; 我们推荐使用 Tabby 软件进行 SSH 远程登录。 + +#### Tabby 下载 + +访问 [Tabby 官网](https://tabby.sh/) 下载并安装 Tabby 软件。 + +#### Tabby 安装 + +- Windows + +根据自己的系统架构选择 `.exe` 文件进行安装。 + +- Linux + +根据自己的系统架构选择 `.deb` 文件进行安装。 + +- MacOS + +根据自己的系统架构选择 `.dmg` 文件进行安装。 + +#### Tabby 使用 + +双击 Tabby 软件图标打开 Tabby 软件。 + +
+ +
+ +#### SSH 配置 + +① --> `Settings` : 点击设置选项 + +② --> `Profiles & connections` : 点击配置连接选项 + +③ --> `New profile` : 点击添加新的配置选项 + +
+ +
+ +#### 选择 SSH 模板 + +选择一个基础配置作为模板:选择 `SSH connection` 模板,我们可以在后续配置界面修改设备名称、IP 地址、端口等参数。 + +
+ +
+ +选择 `SSH connection` 模板后,修改以下参数: + +① --> `Name` : 设置连接名称 + +② --> `Host` : 设置 IP 地址,根据目标设备的实际 IP 地址填写 + +③ --> `User` : 设置用户名,默认出厂用户名为 `radxa` + +④ --> `Save` : 保存配置 + +端口号默认为 `22`,不用修改。 + +
+ +
+ +#### 运行 SSH 连接 + +点击运行按钮远程连接 SSH 设备。 + +
+ +
+ +点击运行按钮后,Tabby 软件会弹出密钥验证和输入密码的界面。 + +
+ +
+ +① --> password : 输入目标设备的密码 + +② --> OK : 确认连接 + +推荐勾选 `Remember` 选项,这样下次连接时就不需要输入密码了。 + +
+ +
+ +连接成功后,会出现远程的界面。 + +
+ +
+ +
+
+ +SSH 远程登录成功后,你就可以通过 SSH 运行命令控制系统。 diff --git a/docs/common/radxa-os/system-config/_system_update.mdx b/docs/common/radxa-os/system-config/_system_update.mdx new file mode 100644 index 000000000..c2c8bf244 --- /dev/null +++ b/docs/common/radxa-os/system-config/_system_update.mdx @@ -0,0 +1,41 @@ +我们使用 `Rsetup` 工具来更新系统。 + +:::tip +使用 `Rsetup` 工具可以更加安全地更新系统。 + +使用 `sudo apt update && sudo apt upgrade` 命令来升级系统可能会导致更新不完全或者系统异常。 + +对于 `Rsetup` 工具的使用,可以参考: + +- [Rsetup 工具](./rsetup) + ::: + +## Rsetup 工具 + +打开终端,输入 `sudo rsetup` 命令打开 `Rsetup` 工具: + + + +``` +sudo rsetup +``` + + + +
+ +
+ +## 更新系统 + +进入 `Rsetup` 工具后,选择 `System` -> `System Update`选项,然后根据 `Rsetup` 工具提示完成系统更新。 + +
+ +
diff --git a/docs/common/radxa-os/system-config/_uart_debug.mdx b/docs/common/radxa-os/system-config/_uart_debug.mdx new file mode 100644 index 000000000..d97e81e7a --- /dev/null +++ b/docs/common/radxa-os/system-config/_uart_debug.mdx @@ -0,0 +1,107 @@ +import { Image } from "@site/src/utils/docs"; + +### Tabby 使用 + +我们推荐使用 Tabby 软件进行串口登录,Tabby 是一款功能强大、界面友好的串口调试软件,支持串口、SSH 等多种协议,适配 Windows、macOS、Linux 等主流操作系统。 + +#### Tabby 下载 + +访问 [Tabby 官网](https://tabby.sh/) 下载并安装 Tabby 软件。 + +#### Tabby 安装 + +- Windows + +根据自己的系统架构选择 `.exe` 文件进行安装。 + +- Linux + +根据自己的系统架构选择 `.deb` 文件进行安装。 + +- MacOS + +根据自己的系统架构选择 `.dmg` 文件进行安装。 + +#### Tabby 使用 + +双击 Tabby 软件图标打开 Tabby 软件。 + +
+ +
+ +### 串口配置 + +① --> `Settings` : 点击设置选项 + +② --> `Profiles & connections` : 点击配置连接选项 + +③ --> `New profile` : 点击添加新的配置选项 + +
+ +
+ +#### 选择串口模板 + +选择一个基础配置作为模板:选择任意 `Serial` 模板,我们可以在后续配置界面修改设备名称、串口设备号、波特率等参数。 + +
+ +
+ +#### 修改串口参数 + +选择 `Serial` 模板后,修改以下参数: + +① --> `Name` : 设置连接名称,建议填写产品名称 + +② --> `Device` : 设置串口设备号,若 Linux 系统只连接一个串口设备,默认为 `/dev/ttyUSB0` + +③ --> `Baud rate` : 设置波特率,填写 {props.baud} + +④ --> `Save` : 保存配置 + +:::tip 串口设备号 +对于不同平台的系统或者连接多个串口设备,您可以安全插拔连接主板的 USB 串口数据线,观察设备号的变化来确定对应设备号。 +::: + + + +### 登录串口 + +点击运行按钮登录串口设备。 + +
+ +
+ +连接成功后,按回车会出现登陆信息,然后使用对应系统的用户账号和密码进行登陆(终端输入密码不会显示出来,输入完密码按回车登陆)。 + + + +## 串口调试 + +串口登录系统成功后,就可以通过串口查看系统日志和运行命令测试系统功能。 diff --git a/docs/common/radxa-os/system-config/_vnc_remote.mdx b/docs/common/radxa-os/system-config/_vnc_remote.mdx new file mode 100644 index 000000000..c3fd1d858 --- /dev/null +++ b/docs/common/radxa-os/system-config/_vnc_remote.mdx @@ -0,0 +1,310 @@ +import { Image } from "@site/src/utils/docs"; + +## 使用前提 + +VNC 远程需要双方设备处于同一局域网下,且目标设备需要开启 VNC 服务。 + +:::tip 使用说明 +VNC 远程控制适合带有图形界面的系统,若系统没有图形化桌面,推荐使用 SSH 远程控制。 +::: + +## 使用 VNC(远程设备) + +### 下载 VNC Viewer + +我们需要在远程设备上安装 VNC Viewer 软件控制主板。 + +访问 [RealVNC](https://www.realvnc.com/en/connect/download/viewer) 官网下载 VNC Viewer 安装包。 + +① : 选择远程设备的系统平台 + +② : 下载 VNC Viewer 安装包 + +
+ +
+ +### 安装 VNC Viewer + + + + + +下载 windows 版本的 `*.exe` 安装包后。 + +- 运行安装包 + +以管理员身份运行 `VNC-Viewer-xxx.exe` 安装程序。 + +
+ +
+- 软件语言 + +选择 `English` 语言,点击 `OK` 进入下一步。 + +
+ +
+ +- 进入安装 + +点击 `Next` 进入安装程序。 + +
+ +
+ +- 同意协议 + +勾选 `I accept the terms in the License Agreement` 选项,点击 `Next` 进入下一步。 + +
+ +
+ +- 安装路径 + +建议选择软件默认安装路径,点击 `Next` 进入下一步。 + +
+ +
+ +- 正式安装 + +点击 `Install` 开始正式安装。 + +
+ +
+ +- 完成安装 + +点击 `Finish` 完成安装。 + +
+ +
+ +
+ + + +下载 Linux 版本的 `*.deb` 安装包后,在终端命令行运行以下命令安装 VNC Viewer: + + + +``` +sudo dpkg -i VNC-Viewer-xxx.deb +``` + + + + + +
+ +### 运行 VNC Viewer + +安装完成后,打开 VNC Viewer 软件: 您可以选择不登录账号使用 VNC Viewer 软件。 + +
+ +
+ +
+ VNC Viewer 界面 + +
+ +## 使用 VNC(主板) + +### 安装 VNC 服务器 + +在主板的终端命令行运行以下命令安装 VNC 服务器: + + + +``` +sudo apt update +sudo apt install tigervnc-standalone-server tigervnc-common -y +``` + + + +### 设置 VNC 远程密码 + +在主板的终端命令行运行以下命令设置 VNC 远程密码: + + + +``` +vncpasswd +``` + + + +:::tip +输入密码和确认密码不会显示在屏幕上,系统提示是否创建一个只读密码,选择 `n`(否)。 +::: + +完成密码设置后,系统会提示类似信息: + +``` +Password: +Verify: +Would you like to enter a view-only password (y/n)? n +A view-only password is not used +``` + +### 配置 VNC 启动文件 + +在主板编辑 `~/.vnc/xstartup` 文件: + + + +``` +sudo vi ~/.vnc/xstartup +``` + + + +修改 `~/.vnc/xstartup` 文件内容为: + +``` +#!/bin/sh +unset SESSION_MANAGER +unset DBUS_SESSION_BUS_ADDRESS +export XDG_SESSION_TYPE=x11 +export DESKTOP_SESSION=plasma +exec startplasma-x11 +``` + +编辑 `~/.vnc/xstartup` 文件后,需要赋予该文件可执行权限: + + + ``` sudo chmod +x ~/.vnc/xstartup ``` + + +### 启动 VNC 服务器 + +在主板的终端命令行运行以下命令启动 VNC 服务器:使用 `-localhost no` 参数可以允许远程访问。 + + + +``` +vncserver -localhost no +``` + + + +启动成功后,终端会输出类似信息,提示 VNC 服务器的端口号。 + +``` +New Xtigervnc server \*\*\*:1 (radxa)' on port 5901 for display :1. +Use xtigervncviewer -SecurityTypes VncAuth -passwd /tmp/tigervnc.VQ4DfI/passwd :1 to connect to the VNC server. +``` + +### 查看 VNC 服务器状态 + +在主板的终端命令行运行以下命令查看 VNC 服务器状态: + + + +``` +vncserver -list +``` + + + +终端会输出类似信息: + +``` +TigerVNC server sessions: + +X DISPLAY # RFB PORT # RFB UNIX PATH PROCESS ID # SERVER +1 5901 3283 Xtigervnc +``` + +### 关闭 VNC 服务器 + +在主板的终端命令行运行以下命令可以关闭 VNC 服务器:其中命令中的 `:1` 代表 VNC 服务器的显示编号。 + + + +``` +vncserver -kill :1 +``` + + + +关闭 VNC 服务器后,VNC Viewer 软件会自动断开连接。 + +## VNC 远程登录 + +在另一台设备上打开 VNC Viewer 软件,根据主板的 IP 地址和端口号进行 VNC 连接。 + +① : 填写主板的 IP 地址和端口号 + +② : 点击 `Connect to address ···` 连接主板 + +
+ +
+ +① : 输入 VNC 远程设置的密码 + +② : 勾选 `Remember password` 选项可以保存密码,方便下次登录 + +③ : 点击 `OK` 进行连接 + +
+ +
+ + +:::tip VNC 黑屏 +若 VNC 远程登录黑屏,可以检查系统的自动登录选项是否开启,若开启,需要关闭自动登录选项。 +::: diff --git a/docs/common/radxa-os/system-config/_wifi_usage.mdx b/docs/common/radxa-os/system-config/_wifi_usage.mdx new file mode 100644 index 000000000..95ac24326 --- /dev/null +++ b/docs/common/radxa-os/system-config/_wifi_usage.mdx @@ -0,0 +1,319 @@ +主要介绍如何连接 WiFi 网络、设置 WiFi 热点以及测试网络带宽。 + +- **连接 WiFi 网络** + +主板连接到 WiFi 网络后,通常会通过路由器的 DHCP 服务自动获得 IP 地址。 + +- **设置 WiFi 热点** + +当主板设置为 WiFi 热点(AP 模式)时,系统一般会自动启动 DHCP 服务,为连接的设备分配 IP 地址。如需定制网络参数,可根据需要手动配置 DHCP 服务。 + +## 连接 WiFi 网络 + +我们会使用 `nmcli` 命令行工具来连接 WiFi 网络。 + +:::tip +nmcli(NetworkManager Command Line Interface)是 NetworkManager 的命令行管理工具,用于在 Linux 系统下配置和管理网络连接。 +::: + +### 开启 WiFi 功能 + + + +``` +sudo nmcli radio wifi on +``` + + + +### 搜索 WiFi 网络 + +若开启 WiFi 功能并没有搜索到 WiFi 网络,可以尝试重启系统。 + + + +``` +sudo nmcli device wifi list +``` + + + +### 连接 WiFi 网络 + + + +``` +sudo nmcli device wifi connect password +# 示例 +sudo nmcli device wifi connect wifi-demo password 12345678 +``` + + + +连接成功后,终端会输出类似如下信息: + +``` +Device 'wlan0' successfully activated with 'xxxxxx'. +``` + +### 查看网络连接的详细信息 + + + +``` +ip a +``` + + + +终端会输出类似如下信息:其中 `192.168.31.53` 就是路由器分配的 IP 地址。 + +``` +1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +2: sit0@NONE: mtu 1480 qdisc noop state DOWN group default qlen 1000 + link/sit 0.0.0.0 brd 0.0.0.0 +3: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether 00:e8:ec:f4:6f:8b brd ff:ff:ff:ff:ff:ff + inet 192.168.2.186/24 brd 192.168.2.255 scope global dynamic noprefixroute eth0 + valid_lft 3432sec preferred_lft 3432sec + inet6 240e:3b7:3246:1e0::b09/128 scope global dynamic noprefixroute + valid_lft 3383sec preferred_lft 3383sec + inet6 fdaa::b09/128 scope global dynamic noprefixroute + valid_lft 3383sec preferred_lft 3383sec + inet6 fdaa::7ebe:84a2:306f:4271/64 scope global noprefixroute + valid_lft forever preferred_lft forever + inet6 240e:3b7:3246:1e0:e07d:77fb:4aa5:ace/64 scope global dynamic noprefixroute + valid_lft 201116sec preferred_lft 114716sec + inet6 fe80::f69d:bf6f:3d68:cef1/64 scope link noprefixroute + valid_lft forever preferred_lft forever +4: wlan0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether 2c:c6:82:85:8d:fe brd ff:ff:ff:ff:ff:ff + inet 192.168.31.104/24 brd 192.168.31.255 scope global dynamic noprefixroute wlan0 + valid_lft 1978sec preferred_lft 1978sec + inet6 240e:3b7:3246:1e2::b09/128 scope global dynamic noprefixroute + valid_lft 1978sec preferred_lft 1978sec + inet6 fdaa:0:0:30::b09/128 scope global dynamic noprefixroute + valid_lft 1978sec preferred_lft 1978sec + inet6 fdaa::30:ca7:7952:73cf:aa06/64 scope global noprefixroute + valid_lft forever preferred_lft forever + inet6 240e:3b7:3246:1e2:7498:9c5:1d2a:f90e/64 scope global dynamic noprefixroute + valid_lft 201117sec preferred_lft 114717sec + inet6 fe80::3dfc:b4f1:ffe4:6c50/64 scope link noprefixroute + valid_lft forever preferred_lft forever +``` + +:::tip +拓展命令: + +- `sudo nmcli radio wifi off`:关闭 WiFi 功能。 +- `sudo nmcli connection delete ` :删除指定的 WiFi 网络。 + ::: + +## 设置 WiFi 热点 + +我们会使用 `nmcli` 命令行工具来设置 WiFi 热点。 + +### 查看 WiFi 网卡 + +使用 `ip a` 命令查看无线网卡设备名称。 + + + +``` +ip a +``` + + + +终端会输出类似如下信息:其中 `wlan0` 就是无线网卡设备名称。 + +``` +1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +2: sit0@NONE: mtu 1480 qdisc noop state DOWN group default qlen 1000 + link/sit 0.0.0.0 brd 0.0.0.0 +3: eth0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether 00:e8:ec:f4:6f:8b brd ff:ff:ff:ff:ff:ff + inet 192.168.2.186/24 brd 192.168.2.255 scope global dynamic noprefixroute eth0 + valid_lft 3432sec preferred_lft 3432sec + inet6 240e:3b7:3246:1e0::b09/128 scope global dynamic noprefixroute + valid_lft 3383sec preferred_lft 3383sec + inet6 fdaa::b09/128 scope global dynamic noprefixroute + valid_lft 3383sec preferred_lft 3383sec + inet6 fdaa::7ebe:84a2:306f:4271/64 scope global noprefixroute + valid_lft forever preferred_lft forever + inet6 240e:3b7:3246:1e0:e07d:77fb:4aa5:ace/64 scope global dynamic noprefixroute + valid_lft 201116sec preferred_lft 114716sec + inet6 fe80::f69d:bf6f:3d68:cef1/64 scope link noprefixroute + valid_lft forever preferred_lft forever +4: wlan0: mtu 1500 qdisc mq state UP group default qlen 1000 + link/ether 2c:c6:82:85:8d:fe brd ff:ff:ff:ff:ff:ff + inet 192.168.31.104/24 brd 192.168.31.255 scope global dynamic noprefixroute wlan0 + valid_lft 1978sec preferred_lft 1978sec + inet6 240e:3b7:3246:1e2::b09/128 scope global dynamic noprefixroute + valid_lft 1978sec preferred_lft 1978sec + inet6 fdaa:0:0:30::b09/128 scope global dynamic noprefixroute + valid_lft 1978sec preferred_lft 1978sec + inet6 fdaa::30:ca7:7952:73cf:aa06/64 scope global noprefixroute + valid_lft forever preferred_lft forever + inet6 240e:3b7:3246:1e2:7498:9c5:1d2a:f90e/64 scope global dynamic noprefixroute + valid_lft 201117sec preferred_lft 114717sec + inet6 fe80::3dfc:b4f1:ffe4:6c50/64 scope link noprefixroute + valid_lft forever preferred_lft forever +``` + +### 设置 WiFi 热点 + + +``` +sudo nmcli device wifi hotspot ifname con-name ssid password +# 示例 +sudo nmcli device wifi hotspot ifname wlan0 con-name My-Hotspot ssid My-Hotspot password 12345678 +``` + + +参数说明:用名为 wlan0 的无线网卡创建一个名为 My-Hotspot、密码为 12345678 的WiFi热点,并将该连接保存为 My-Hotspot,方便后续管理。 + +- `ifname`:指定用于创建热点的无线网卡接口名,可以使用 `ip a` 命令查看无线网卡接口名。 +- `con-name`:指定热点连接名称,后续可以通过这个名字管理(开启、关闭、删除该热点)。 +- `ssid`:指定热点的名称,也就是其他设备搜索到的无线网络名称。 +- `password`:指定热点的密码。 + +设置成功后,终端会输出类似如下信息: + +``` +Device 'wlan0' successfully activated with 'xxxxxx'. +Hint: "nmcli dev wifi show-password" shows the Wi-Fi name and password. +``` + +### 关闭 WiFi 热点 + + + +``` +sudo nmcli connection down My-Hotspot +``` + + + +### 开启 WiFi 热点 + + + +``` +sudo nmcli connection up My-Hotspot +``` + + + +### 删除 WiFi 热点 + + + +``` +sudo nmcli connection delete My-Hotspot +``` + + + +## 测试网络带宽性能 + +使用 `iperf` 工具来测试网络带宽(吞吐量)性能,建议多次测试取平均值。 + +### 测试前提 + +- 硬件设备 + +您需要两台设备,其中一台设备作为服务端,另一台设备作为客户端。 + +服务端(Server):PC、服务器等设备。 + +客户端(Client):待测试的设备,如 Cubie A7A。 + +- 同一局域网 + +服务端和客户端需要处于同一局域网,彼此可以 ping 通。 + +### 安装 iperf + +服务端和客户端都需要安装 `iperf`。 + + + +``` +sudo apt update sudo apt install iperf +``` + + + +### 测试步骤 + +#### 服务端 (PC) + +打开命令行终端,输入以下命令启动服务端: + + + +``` +iperf -s +``` + + + +成功启动后,终端会输出类似如下信息: + +``` +----------------------------------------------------------- +Server listening on 5201 (test #1) +----------------------------------------------------------- +``` + +#### 客户端(主板) + +1. 上传测试 + +打开命令行终端,输入以下命令测试客户端上传网络带宽:将 `` 替换为实际的服务端 IP 地址(可以通过 `ip a` 命令查看)。 + + + +``` +iperf -c -t + +参数说明: + +- ``:服务端 IP 地址。 +- `