From f214c862d3990a8626659b468e8a6e3fd1b131fb Mon Sep 17 00:00:00 2001 From: qing <1776177662@qq.com> Date: Thu, 30 Jul 2026 11:54:51 +0800 Subject: [PATCH] =?UTF-8?q?docs(bot4cj):=20=E6=96=B0=E5=A2=9E=20README.rob?= =?UTF-8?q?ot.md=20=E5=AE=8C=E6=95=B4=E6=8A=80=E6=9C=AF=E6=89=8B=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 补充 5 层架构分层图(脚本→解析器→结构构建→硬件实现→系统库) - 详解 .mt 脚本语法、块类型、占位符规则 - 补充 PCA9685/Servo/MPU6050/Speaker 各硬件寄存器与校准参数 - 说明执行流程:stdin→FSM 解析→链表→build/play/free - 列出 I2C 总线保护、GC 析构、pthread_cancel 等安全限制 - 补充 11 条已知缺陷清单(D1-D11) - 新增 NN/CNN 测试命令与 DRL 预留接口说明 --- bot4cj/README.robot.md | 384 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 bot4cj/README.robot.md diff --git a/bot4cj/README.robot.md b/bot4cj/README.robot.md new file mode 100644 index 0000000..7ce9f1b --- /dev/null +++ b/bot4cj/README.robot.md @@ -0,0 +1,384 @@ +# bot4cj — 机器人硬件脚本解析器 + +基于**仓颉(Cangjie)** 编程语言和 Linux I2C 接口的机器人动作脚本解析器。用一种矩阵式脚本来描述机器人的硬件构成与动作序列,解析后驱动真实硬件执行。 + +## 架构分层 + +``` +┌──────────────────────────────────────────────────────────────┐ +│ .mt 矩阵脚本(硬件定义 + 动作序列) │ +├──────────────────────────────────────────────────────────────┤ +│ MatrixParser(P.cj) — FSM 逐字符解析 → MatrixObject 链表 │ +├──────────────────────────────────────────────────────────────┤ +│ RobotStruct(r.cj) — 从矩阵对象构建硬件变量(createHardVars) │ +│ MatrixVars_Hardware 基类 + 闭包回调: │ +│ · build() → rise 回调(打开硬件、获取资源) │ +│ · play() → things 回调(执行动作,参数/返回值均为 JsonValue) │ +│ · free() → free 回调(释放资源) │ +├──────────────────────────────────────────────────────────────┤ +│ 硬件实现:hd/*.cj │ +│ PCA9685(I2C 0x40, 50Hz PWM, 角度→脉宽 0.5~2.5ms) │ +│ Servo(舵机:max/min/offset 校准 + 角度翻转) │ +│ MPU6050(陀螺+加速度,±500°/s ±8g,后台 10ms 采样线程+卡尔曼) │ +│ Speaker(正弦波发声,5ms 淡入淡出) │ +│ fb.cj(外部硬件扩展口) │ +├──────────────────────────────────────────────────────────────┤ +│ 系统库:cpp/ + cuda/ │ +│ libi2c4cj.so — I2C glibc 封装 + 20 槽锁数组 │ +│ libmt4cj.so — FP32 矩阵运算(CPU / CUDA 二选一) │ +│ libfft4cj.so — 基-2 Cooley-Tukey FFT │ +│ libcnn4cj.so — Conv/Pool/GA-Pool/Flatten + Adam/Momentum │ +│ libsnd4cj.so — WaveAPI / ALSA 音频播放 │ +├──────────────────────────────────────────────────────────────┤ +│ 数学/NN 库:math/*.cj │ +│ Matrix1(二维矩阵)+ Tensor + 6 种激活函数 + Xavier 初始化 │ +│ Nn1 全连接层(前向/反向/权重更新) │ +│ Af(Sigmoid/Tanh/ReLU/Leaky_ReLU/Swish/Softmax) │ +└──────────────────────────────────────────────────────────────┘ +``` + +## 技术栈 + +| 层 | 技术 | 说明 | +|----|------|------| +| 应用层 | **仓颉 Cangjie** | 主程序、解析器、机器人结构、数学库、HTTP 服务 | +| 系统层 | C / C++ | I2C 驱动、矩阵运算、FFT、CNN、音频 | +| 加速层 | CUDA(可选) | `MODE=cpu/cuda` 切换 | +| 脚本层 | `.mt` 矩阵脚本 | 硬件定义 + 动作序列 | +| 依赖包 | ctype4cj / pthread4cj / spi4cj / lua4cj | 仓颉官方扩展包 | +| 构建 | Makefile(C/C++ 共享库)+ cjpm.toml(仓颉包管理) | — | + +## 目录结构 + +``` +bot4cj/ +├── src/ +│ ├── main.cj # 入口:CLI 参数解析(-i/-o/--test)+ stdin 管道执行 +│ ├── P.cj # 矩阵脚本解析器(FSM 逐字符解析) +│ ├── r.cj # RobotStruct + MatrixVars_Hardware 基类 +│ ├── testCNN.cj # CNN 测试入口 +│ ├── testCNN1.cj # 几何 CNN 测试 +│ ├── hd/ +│ │ ├── I2C.cj # I2C 封装 + 20 槽锁数组 +│ │ ├── PCA9685.cj # PCA9685 舵机控制板(已标记由 Lua 替代) +│ │ ├── Servo.cj # 舵机:校准 + 角度翻转 +│ │ ├── MPU6050.cj # MPU6050 陀螺+加速度+卡尔曼滤波 +│ │ ├── snd.cj # 扬声器 +│ │ ├── fb.cj # 外部硬件扩展 +│ │ └── extern/ +│ │ └── macro_ExternHardware.cj +│ ├── math/ +│ │ ├── Matrix.cj # 二维矩阵(+运算符重载) +│ │ ├── Tensor.cj # 张量 +│ │ ├── Af.cj # 6 种激活函数 +│ │ ├── Ini.cj # Xavier/Kaiming 初始化 +│ │ ├── nn.cj # 全连接层 Nn1 +│ │ ├── nns.cj # 旧版神经网络(XNOR 门测试) +│ │ ├── cnn.cj # CNN 仓颉绑定 +│ │ ├── pooling.cj # 池化 +│ │ ├── flatten.cj # Flatten +│ │ ├── fft.cj # FFT 仓颉绑定 +│ │ ├── kalman.cj # 卡尔曼滤波 +│ │ └── Adam.cj # Adam 优化器 +│ ├── cpp/ # C/C++ 系统库源 +│ │ ├── I2C.c # I2C glibc 封装 +│ │ ├── Matrix.cpp # CPU 矩阵运算 +│ │ ├── fft1.c # FFT 单实序列 +│ │ ├── fft.cpp # FFT 双实序列 + 基-2 Cooley-Tukey +│ │ ├── kalman.c # 卡尔曼滤波 +│ │ ├── snd.cpp # 音频播放(WaveAPI/ALSA) +│ │ └── cnn/ # 纯 C++ CNN(Conv/Pool/GA-Pool/Flatten) +│ └── cuda/ +│ ├── matrix.cu # GPU 矩阵运算 kernel +│ └── error.cuh # CUDA 错误检查宏 +├── modules/ # Lua 硬件模块(ADS1115/ADS1256/PCA9685/SPI) +├── scripts/ # .mt 动作脚本(std/jump/lie-down/tilt-* 等) +├── test/ # C/Lua 测试脚本 +├── docs/Reports/ # 深度分析报告 +├── cjpm.toml # 仓颉包配置 +├── Makefile # C/C++ 共享库构建 +├── _set.sh # 编译(cjpm update + build) +├── _run.sh # 运行(stdin 管道) +├── compile.ps1 # Windows 编译脚本 +├── run.ps1 # Windows 运行脚本 +├── README.md # 旧版说明 +└── README.robot.md # 本文件 +``` + +## 快速开始 + +```bash +# 1. 编译 C/C++ 共享库(一次性) +make MODE=cpu # CPU 模式(默认) +# 或 +make MODE=cuda # GPU 模式(需要 nvcc) + +# 2. 编译仓颉程序 +bash _set.sh + +# 3. 运行动作脚本(stdin 管道) +cat scripts/std.mt | bash _run.sh +``` + +> **硬件要求**:树莓派(aarch64)或其他 Linux I2C 设备。x86_64 开发板需自行验证 I2C 参数。Windows 暂不支持(依赖 glibc)。 + +## CLI 参数 + +``` +./bot # 从 stdin 读取 .mt 脚本执行 +./bot --help # 打印帮助 +./bot --test nn # 运行神经网络与门测试 +./bot --test cnn # 运行 CNN 测试 +./bot --test cnn1 # 运行几何 CNN 测试 +./bot --test matrix_o # 解析 ss/test.mt 并保存为 ss/output.mt +./bot --test matrix_2 # 解析 ss/output.mt → 执行 → 再次保存 +./bot -i model.json -o out.json # 加载/保存神经网络模型(DRL 预留) +``` + +## .mt 脚本语法 + +行列式表格,每列以空格或制表符分隔,每行以分号 `;` 结尾。 + +### 块结构 + +``` +@BlockName +column1 column2 column3; +value1 value2 value3; +@ +``` + +每个 `@` 块由 `@Name` 行开始,`@` 行结束。支持的块类型: + +| 块 | 说明 | +|----|------| +| `@Alias` | 列名别名(如 `A` → `angle`、`F` → `frequency`) | +| `@I2C` | 定义 I2C 设备(name + path) | +| `@PCA9685` | 定义 PCA9685 舵机控制板(name + I2C 引用 + 地址) | +| `@MPU6050` | 定义 MPU6050 传感器(name + I2C 引用 + 地址) | +| `@Speaker` | 定义扬声器(channels + sample_rate + volume + max_f + min_f) | +| `@Servo` | 定义舵机(name + max + min + offset + controller + channel) | +| `@Action` | **动作矩阵**:列头为硬件变量的属性,行为每帧的参数 | + +### 占位符 + +`-` 表示"沿用上一行同列的值",当前行该列不产生调用。 + +### 完整示例 + +```mt +@Alias +name alias; + A angle; + F frequency; +@ + +@I2C + name path; +i2c-0 /dev/i2c-0; +i2c-1 /dev/i2c-1; +@ + +@PCA9685 + name I2C address; +pca9685-0 i2c-1 0x40; +@ + +@Speaker +name channels sample_rate volumn max_f min_f; + spk 2 48000 0.6 5000 -; +@ + +@Servo + name max min offset controller channel; + s1 90 - - pca9685-0 0; + s2 180 - - - 1; + s3 -90 - - - 2; + s4 -180 - - - 3; +@ + +@Action +s1.A s2.A s3.A s4.A spk.F spk.delay; + 45 - 45 - 10 200; # 站立 + 90 - - - - 20; # 左转 +@ +``` + +## 执行流程 + +``` +stdin.read() + ↓ +P.MatrixParser (FSM 逐字符解析) + ↓ +LinkedList 链表 + ↓ +RobotStruct.createHardVars() # 按 @I2C/@PCA9685/@Servo/@Speaker/@MPU6050 构建硬件变量 + ↓ +robot.active() # build():逐个硬件调用 rise 回调(打开 I2C、初始化 PWM 等) + ↓ +robot.run() # 逐行遍历 @Action 矩阵,每列调用对应硬件的 play() 回调 + ↓ +robot.deactive() # free():倒序释放资源 +``` + +`play()` 的输入输出均为 `JsonValue`,实现了硬件与脚本之间的统一通信协议。 + +## 已支持的硬件 + +### PCA9685(I2C 舵机控制板) +- 地址:默认 `0x40` +- PWM 频率:50Hz(舵机标准 20ms 周期) +- 舵机脉宽映射:0°→0.5ms,180°→2.5ms +- 角度映射到 12 位 PWM 值(0-4095) +- **注意**:PCA9685.cj 代码已标记"由 Lua 脚本取代",保留作备用 + +### Servo(舵机) +- 支持 `max` / `min` 角度限制与 `offset` 漂移校准 +- `max < 0` 时自动翻转角度(反向安装的舵机) +- 通过闭包回调与实际硬件(PCA9685/Lua 模块)解耦 + +### MPU6050(6 轴传感器) +- 陀螺仪:±500°/s 量程 +- 加速度计:±8g 量程 +- 后台 10ms 采样线程(pthread_create + pthread_cancel) +- 卡尔曼滤波融合数据 +- **已知问题**:`ADDR_0` 与 `ADDR_1` 常量均为 `0x68`([MPU6050.cj:14-15](src/hd/MPU6050.cj#L14-L15)),第二个地址应改为 `0x69` + +### Speaker(扬声器) +- 支持正弦波发声(指定频率 `F` + 延时 `delay`) +- 5ms 淡入淡出,避免"咔哒"声 +- 通道数/采样率/音量可在 `.mt` 中配置 +- **已知问题**:`play()` 仅 sleep 指定延时,真实发声依赖底层 C++ 实现 + +## 机器人型号适配 + +### Dashun 蜘蛛机器人(默认) +10 舵机 + 2 云台 + 扬声器,建模文件见 [gopsc/Dashun](https://github.com/gopsc/Dashun): + +| 舵机 | 关节 | 舵机 | 关节 | +|------|------|------|------| +| s1 | 左下水平 (rb0) | s6 | 右上垂直 (lf1) | +| s2 | 左下垂直 (rb1) | s7 | 左上水平 (rf0) | +| s3 | 右下水平 (lb0) | s8 | 左上垂直 (rf1) | +| s4 | 右下垂直 (lb1) | s9 | 云台1 (cam0) | +| s5 | 右上水平 (lf0) | s10 | 云台2 (cam1) | + +### 可用脚本 + +`scripts/` 目录下预写了多种动作脚本: +- `std.mt` — 站立姿态 +- `jump.mt` — 跳跃 +- `lie-down.mt` — 趴下 +- `left-hand.mt` / `rght-hand.mt` — 单手动作 +- `left-turn.mt` / `tilt-f.mt` / `tilt-b.mt` / `tilt-l.mt` / `tilt-r.mt` — 转向与倾斜 + +## 构建 + +### 依赖 + +```bash +# 仓颉 1.1.3 +# 仓颉官方扩展包:ctype4cj / pthread4cj / spi4cj / lua4cj +# libc / libpthread +# liblua-5.4(可选,Lua 硬件模块支持) +sudo ln -s /usr/lib/aarch64-linux-gnu/liblua5.4.so /usr/lib/aarch64-linux-gnu/liblua.so +sudo ln -s /usr/lib/x86_64-linux-gnu/liblua5.4.so /usr/lib/x86_64-linux-gnu/liblua.so +``` + +### 构建步骤 + +```bash +# 1. 构建 C/C++ 共享库 +make MODE=cpu +# 产出:libi2c4cj.so libmt4cj.so libfft4cj.so libsnd4cj.so + +# 2. (可选)构建 CNN +make libcnn4cj.so + +# 3. (可选)CUDA 模式需 NVIDIA CUDA Toolkit +make MODE=cuda + +# 4. 仓颉主程序 +bash _set.sh +``` + +[_set.sh](_set.sh) 执行 `cjpm update` + `cjpm build`,自动解析 cjpm.toml 依赖。 + +### 运行 + +```bash +bash _run.sh scripts/std.mt +# 或 +cat scripts/std.mt | bash _run.sh +``` + +[_run.sh](_run.sh) 以 `cjStackSize=64MB` / `cjHeapSize=64MB` 启动。 + +## 神经网络支持 + +项目内置了全连接层 Nn1([math/nn.cj](src/math/nn.cj))与 CNN([math/cnn.cj](src/math/cnn.cj) + [cpp/cnn/](src/cpp/cnn/)): + +- **Nn1**:多层感知机,支持前向传播、反向传播、权重更新 +- **CNN**:Conv → ReLU → Pool → GA-Pool → Flatten → FC +- **优化器**:Adam / Momentum +- **激活函数**:Sigmoid / Tanh / ReLU / Leaky_ReLU / Swish / Softmax +- **初始化**:Xavier / Kaiming + +### 测试 + +```bash +./bot --test nn # 与门训练(2 输入 → 1 输出) +./bot --test cnn # CNN 前向/反向测试 +./bot --test cnn1 # 几何分类 CNN 测试 +``` + +### DRL 预留(未完成) + +main.cj 中预留了 DRL 流程(注释状态):加载预训练权重 → 执行动作 → 保存微调模型。通过 `-i` / `-o` 参数指定输入/输出路径。 + +## 安全与限制 + +### I2C 总线保护 +- [hd/I2C.cj](src/hd/I2C.cj) 内置 **20 槽锁数组**,多硬件共享 I2C 总线时自动互斥 +- 每个 I2C fd 独立加锁,避免并发写入冲突 + +### 硬件关闭时机 +- `MatrixVars_Hardware` 析构依赖仓颉 GC,**不保证**在确定性时机调用 `free()` +- 机器人使用 `try/finally` 在 [main.cj:80-87](src/main.cj#L80) 中显式调用 `deactive()`,确保硬件资源正确释放 + +### 线程安全 +- MPU6050 采样通过 `pthread_create` 启动后台线程 +- `pthread_cancel` 依赖系统定义的取消点(sleep / 系统调用),可能在非安全点中断 + +### 平台支持 +- ✅ Linux aarch64(树莓派)/ x86_64 +- ❌ Windows(依赖 glibc) + +## 已知问题 + +| ID | 描述 | 影响 | +|----|------|------| +| D1 | 仓颉 GC 不保证析构器调用,I2C fd 可能泄漏 | 长时间运行后 I2C 资源耗尽 | +| D2 | Speaker `play()` 仅 sleep,真实发声未接入 C++ | 扬声器无实际声音 | +| D3 | MPU6050 `pthread_cancel` 可能在非安全点中断 | 传感器数据不一致 | +| D4 | PCA9685 初始化被标记为"由 Lua 取代",但仍保留主路径 | 代码存在双实现 | +| D5 | `_set.sh` 会删除 `a.out` | 误删用户产物 | +| D6 | Softmax 雅可比矩阵实现错误(math/Af.cj) | NN 训练收敛异常 | +| D7 | Tensor 乘法仅支持 2D,3D+ 会 panic | 限制模型复杂度 | +| D8 | Tanh 导数实现错误(使用 `1 - y^2` 而非 `1 - tanh^2(x)`) | NN 训练收敛异常 | +| D9 | CNN `testGeometryCNN` 使用随机数据 | 测试无实际意义 | +| D10 | MPU6050 `ADDR_0` 与 `ADDR_1` 均为 `0x68` | 无法同时使用两个 MPU6050 | +| D11 | `@Action` 与 `@Action_Auto` 并存未合并 | 脚本语法冗余 | + +## 相关资源 + +- [Dashun 蜘蛛机器人建模](https://github.com/gopsc/Dashun) +- [深度分析报告](docs/Reports/analysis_20260525_00.md)(28 章节,1280 行) +- [仓颉编程语言](https://cangjie-lang.org/) +- [PCA9685 数据手册](https://www.nxp.com/docs/en/data-sheet/PCA9685.pdf) +- [MPU6050 数据手册](https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf) + +## 许可证 + +MIT License