# RoboMaster 底盘职责型架构 **版本**: 2.0 **平台**: Allwinner T153 / Linux **底盘控制频率**: 1 kHz **实现范围**: 四轮麦轮底盘;云台与发射机构尚未实现 本文是架构的唯一规范。`docs/chassis.md` 只记录接线、标定、部署与排障。 ## 1. 架构原则 - **一个 crate 一件事**:协议、传输、设备运行时、算法、仿真、工具和应用入口分别成 crate。 - **依赖必须无环**:允许依赖同层或更低抽象,但禁止反向控制依赖和隐藏的完整链路打包。 - **std,禁止 unsafe**:workspace 使用 `unsafe_code = "forbid"`;允许使用提供安全 API 的第三方依赖。 - **实时调度交给 systemd**:进程不调用 libc FFI,不实现 `SCHED_FIFO` 或 `mlockall`。 - **二级语义分层**:crate 名不变,manifest 按 `crates//` 组织;依赖只能由高层指向低层。 - **crate 内保持扁平**:只允许 Cargo 惯例目录 `src`、`tests`;`src` 内不建立模块子目录。 - **安全边界独立于控制律**:总线负责反馈新鲜度、命令租约和零电流;控制器通过策略接口组合。 ## 2. Workspace ```text 基础 can CAN 帧、CanBus、CanLink、MockBus imu IMU 数据契约 协议 motor-protocol C620/C610、GM6020 编解码、多圈与 ID delta10-protocol DETA10 帧布局与解码 dr16-protocol DJI DR16 D-BUS 帧布局与解码 驱动 socketcan Linux SocketCAN ↔ CanLink slcan Lawicel 串口 CAN ↔ CanLink delta10 DETA10 IMU 驱动 dr16 DR16 D-BUS 串口接收驱动 设备与运行时 motor Motor 能力 trait、状态、命令、减速比、注册表、EffortPolicy esc-bus ESC 帧泵、反馈状态、租约、离线保护、effort 输出 控制 pid 通用 PID motor-control 速度/位置/串级/前馈与 MotorPolicy mecanum 麦轮正逆运动学 实验与仿真 motor-model DC/GM3508 物理模型 experiment Scenario、Trace、Window、StepMetrics sim-harness 同步闭环、总线损伤、域随机化、假电调 tuning Relay/ZN、成本、增益空间、搜索、预设 应用 chassis-config chassis.toml schema 与校验 bench 真机链路门面、安全包络、试验采样 chassisd 底盘守护进程二进制 spin chassis / motor 台架二进制 chassis-tune 自动整定二进制与报告/绘图适配 验证 integration-tests 跨层闭环、语义一致性与 vcan 集成测试 ``` 共 24 个 crate(含顶层 `verification/integration` 集成测试包)。crate 名不使用 `rm-` 等无领域含义的统一前缀。 ## 3. 允许依赖 机器可读规则见 [`config/dependency-policy.toml`](config/dependency-policy.toml) 和 [`docs/dependencies.md`](docs/dependencies.md)。`just audit` 同时检查层 rank、正常/dev 依赖、 外部库职责和 trait 边界;正常与 dev 依赖都必须单向。 主要边如下: ```text motor-protocol -> can delta10-protocol -> can, imu dr16-protocol -> (无内部依赖) socketcan -> can slcan -> can delta10 -> can, imu, delta10-protocol dr16 -> dr16-protocol motor -> can, motor-protocol esc-bus -> can, motor, motor-protocol pid -> (无内部依赖) motor-control -> pid, motor mecanum -> (无内部依赖) motor-model -> motor-protocol sim-harness -> can, motor, motor-control, motor-model, motor-protocol, experiment tuning -> pid, motor-control, motor-model, sim-harness, experiment chassis-config -> esc-bus, motor-control, motor-protocol, mecanum bench -> can, esc-bus, experiment, motor, motor-control, socketcan, slcan chassisd -> chassis-config, dr16, esc-bus, mecanum, motor-control, sim-harness, socketcan spin -> bench, dr16, esc-bus, motor-control, socketcan, slcan chassis-tune -> bench, chassis-config, experiment, sim-harness, tuning ``` 禁止边: - `esc-bus -> motor-control` / `pid`:`esc-bus` 不包含控制律。 - `bench -> tuning`:真机试验只产生 `TrialOutcome`;成本和搜索适配在 `chassis-tune`。 - `sim-harness -> tuning`:仿真只产生模型与轨迹;搜索器不反向渗入仿真。 - 协议或驱动依赖设备、控制、仿真、整定或应用 crate。 `motor::EffortPolicy` 是控制与总线的唯一组合点。`motor-control::MotorPolicy` 实现该 trait,应用负责把它传给 `esc_bus::EscBus::spawn`。 ## 4. 运行模型 - 底盘速度环和 ESC 命令节拍为 **1 kHz**。 - `esc-bus` 每拍读取命令租约和反馈新鲜度,再调用 `EffortPolicy`。 - 反馈超时或命令租约到期时强制零输出;策略状态会被复位。 - 上层必须逐拍重发目标值;一次性命令会在默认 50 ms 后失效。 - `chassisd` 将麦轮逆解得到的轮端速度经 `OutputShaft` 换算到转子速度。 ## 5. std 与实时策略 - Rust 代码只使用 std 与安全第三方 API,workspace 设置 `unsafe_code = "forbid"`。 - 不依赖 `libc`,不包含 FFI、`no_std` 分支或 `realtime` 模块。 - `deploy/chassisd.service` 通过 `CPUSchedulingPolicy=fifo`、 `CPUSchedulingPriority=80`、`LimitRTPRIO=95` 设置调度策略。 - `LimitMEMLOCK=infinity` 只提高锁定额度;std 程序不调用 `mlockall`,本文不承诺主动锁页。 - 不支持的平台由 `socketcan` 返回明确错误;核心算法与仿真可跨平台测试。 ## 6. 目录规则 每个 crate 仅包含: ```text Cargo.toml src/lib.rs # 库 src/main.rs # 二进制 tests/*.rs # 可选集成测试 ``` 不允许 `src//` 子目录。单元测试使用源码文件内的 `#[cfg(test)] mod tests`。 ## 7. 当前实现边界 已实现: - C620/C610 电流协议、GM6020 电压协议骨架、多圈跟踪与 ID 校验。 - SocketCAN、SLCAN、DETA10 驱动骨架、MockBus。 - 四轮 ESC 总线、命令租约、反馈离线保护、外部控制策略。 - PID、速度/位置/串级/前馈、麦轮运动学。 - 电机模型、总线损伤、同步/异步闭环、参数搜索、预设与报告。 - `chassisd --mock`、`spin chassis|motor|rc`、`chassis-tune`。 - DR16/D-BUS 遥控输入、S1 使能、断流失能和 500 ms 速度斜坡。 未实现: - 云台与发射机构任务和控制律。 - DETA10 真实载荷布局(决策点 D1,原手册链接失效)。 - GM6020 实车闭环。 - E907 异构核(决策点 D4)。 - 进程内 `mlockall`。 ## 8. 验收 - `cargo fmt --all -- --check` - `cargo clippy --workspace --all-targets -- -D warnings` - `cargo test --workspace --all-targets` - Linux vcan:`cargo test -p socketcan@0.1.0 --test vcan -- --ignored --test-threads 1` - `find crates/*/src -mindepth 2 -type d` 无输出。 - Rust 源码不得包含 `unsafe`、`libc` 或 `no_std`。 - `cargo tree` 确认禁止边不存在、依赖图无环。