feat: 初始化

This commit is contained in:
Horldsence
2026-09-22 20:05:16 +08:00
commit 7d87987e41
54 changed files with 6446 additions and 0 deletions
@@ -0,0 +1,75 @@
# 麦轮底盘仓库基础搭建方案(Linux ARM 主控 + 4×GM3508/C620)
## 已确认决策
- **主控**:Linux ARM 板,CAN 经 **SocketCAN (can0)** 接入(USB转CAN / CAN HAT)
- **并发模型**:tokio 异步
- **架构**:5 crate 分层,通用职能命名(不含仓库名 sentry-chassis,无 rm- 前缀;五个名字已在 crates.io 确认全部未占用)
## 关键协议事实(编码实现依据,来自 C620 官方手册调研)
- 控制:ID **0x200** 携带电调 1–4 的电流命令,**0x1FF** 携带 5–8;每电机 i16 **大端**,±16384 ↔ ±20A(C620)
- 反馈:ID **0x200+电调ID**(0x201–0x208),8 字节 = 机械角(0..8191, u16) + 转速 rpm(i16) + 转矩电流(i16) + 温度℃(i8)
- C620 **只闭电流环**,速度环/位置环须在主控侧用 PID 实现;GM3508 减速比 3591/187 ≈ 19.2
## 仓库结构(Cargo workspace,虚拟清单,删除现有 src/main.rs)
```
sentry-chassis/
├── Cargo.toml # [workspace] resolver="3" + workspace.package/dependencies/lints
├── rust-toolchain.toml # stable + rustfmt/clippy 组件
├── rustfmt.toml / clippy.toml
├── justfile # lint / test / vcan-test / run-mock
├── .github/workflows/ci.yml
├── README.md / LICENSE(MIT) / docs/architecture.md / deploy/chassisd.service
└── crates/
├── motor-core/ # 电机抽象层(纯逻辑,无 IO)
├── dji-esc/ # C620/C610 协议层(帧编解码 + 异步驱动,纯逻辑可全平台测)
├── dji-esc-socketcan/ # SocketCAN 后端(Linux only,非 Linux 编译为空壳)
├── mecanum/ # 麦轮正逆运动学(纯数学)
└── chassisd/ # 守护进程二进制(组装一切,支持 --mock 无硬件运行)
```
## 各 crate 设计
### 1. `motor-core` — 抽象与控制(依赖:仅 tokio/thiserror)
- `MotorState`:转子原始角、连续累计角(多圈)、转子 rpm、电流、温度、减速比换算的轮端速度
- `Motor` trait:`id() / state() / set_velocity(rpm) / set_current_raw(i16) / disable()`,句柄可克隆、内部共享状态,供 chassisd 与测试用 mock 泛化
- `Pid`(f32,显式 dt):输出限幅、积分抗饱和(clamping)、测量值微分 + 一阶低通滤波
- `VelocityController`:速度环封装(由驱动层按反馈节拍调用)
### 2. `dji-esc` — DJI 电调协议(依赖 motor-core + tokio)
- 自带最小 `CanFrame{ id, data:[u8;8] }` 与异步 `CanPort` trait(send/recv)——不依赖 socketcan,测试用 channel 实现
- 纯函数编解码:`encode_current_frame`(0x200/0x1FF 分组、大端、饱和 ±16384)、`decode_feedback`(0x201–0x208),C620/C610 双型号量程
- `TurnTracker`:0..8191 → 连续多圈角(正反向回绕处理)
- `EscBus<P: CanPort>`:spawn 收发任务;rx 分发反馈到各 `C620Motor` 句柄(含方向翻转、速度 PID tick),tx 每 1kHz 汇装两帧控制报文;`EscConfig{ esc_id, 型号, 减速比, 方向, 电流限幅 }`
- 反馈超时检测(离线 → 电流清零)
### 3. `dji-esc-socketcan` — SocketCAN 后端(依赖 dji-esc + socketcan v4 "tokio" feature)
- `SocketCanPort::open("can0")` 实现 `CanPort`;socketcan Frame ↔ CanFrame 转换
- crate 主体 `#[cfg(target_os="linux")]`,macOS 上编译为空壳 → 全 workspace 可在 mac 开发机直接 build/test
### 4. `mecanum` — 麦轮运动学(纯数学,零依赖)
- `Mecanum{ lx, ly, wheel_radius }`,ISO 约定(x前 y左 ω逆正,45°辊子)
- `inverse(Twist) -> [4] 轮角速度`(FL/FR/RL/RR)、`forward([4]) -> Twist`(伪逆)、rpm↔rad/s 换算
### 5. `chassisd` — 守护进程(依赖以上全部 + clap/serde/toml/tracing)
- CLI:`--interface can0 --config chassis.toml --mock`
- `--mock`:进程内 CanPort + 一阶电机模型,**无硬件/macOS 可跑通全链路**
- 1kHz 控制循环:Twist → mecanum 逆解 → 4 路 `set_velocity`;`TwistSource` trait(当前 Zero/Mock 实现,遥控器后续接入)
- 安全:命令超时清零、反馈离线清零、上电等首帧反馈后才使能;tracing 日志、ctrl-c 优雅退出、systemd 部署样例
## 底层库配置(workspace.dependencies 统一管理)
tokio(rt-multi-thread,macros,sync,time) / socketcan v4+tokio(仅 Linux target 依赖;若 4.0 有问题回退 3.6.2)/ thiserror / tracing + tracing-subscriber / serde+toml(配置) / clap(bin) / proptest+approx(dev)。`[workspace.lints]`:clippy pedantic 子集 + 库 crate 禁 unwrap/expect。
## 充分测试策略
1. **单元(全平台)**:编解码官方字节级样例与边界值(±16384 饱和、负值、全部 ID 路由)、多圈回绕序列、PID(阶跃/限幅/抗饱和恢复/微分滤波)、运动学(纯平移/纯旋转/对角线/零点 + proptest 往返一致性)、配置解析
2. **闭环仿真(全平台)**:mock CanPort + 一阶电机模型(电流→rpm 增益与限速),4 电机速度环收敛、群帧组装、离线安全、`--mock` 守护进程全链路(tokio::time::pause 控时)
3. **vcan 集成(Linux 专属,#[ignore] + CI 显式跑)**:vcan0 上双 socket 收发,真实内核 CAN 栈回环验证
4. **CI(GitHub Actions)**:fmt --check / clippy -D warnings / test / doc / vcan job(modprobe vcan)/ **aarch64-unknown-linux-gnu 交叉 check**(目标板架构)/ llvm-cov 覆盖率
## 实施步骤
1. 工作区脚手架:根 Cargo.toml(虚拟清单)、toolchain/lint/fmt 配置、删 src/main.rs、README、docs、justfile、CI、LICENSE
2. `motor-core`:类型 + Motor trait + PID + 单测
3. `dji-esc`:CanFrame/CanPort、编解码、TurnTracker、EscBus 异步驱动、闭环仿真测试
4. `dji-esc-socketcan`:CanPort 实现 + vcan 集成测试
5. `mecanum`:正逆解 + proptest
6. `chassisd`:配置/CLI/mock 模式/控制循环/安全逻辑 + 测试、deploy 样例
7. 本机验证:cargo fmt / clippy / test 全绿(macOS 上 Linux 专属测试自动跳过)