4.5 KiB
4.5 KiB
架构设计
分层
┌─────────────────────────────────────────────┐
│ chassisd(守护进程) │
│ 配置 / CLI / 1kHz 控制循环 / 安全逻辑 / 日志 │
└──────┬───────────────────────────┬──────────┘
│ mecanum(麦轮正逆解) │
▼ ▼
┌────────────┐ ┌──────────────────┐
│ motor-core │◄─实现 trait──│ dji-esc │
│ Motor trait│ │ C620/C610 协议 │
│ MotorState │ │ EscBus 异步驱动 │
│ Pid │ │ TurnTracker 多圈 │
└────────────┘ └────────┬─────────┘
│ CanLink(tokio mpsc 通道对)
▼
┌──────────────────────────┐
│ dji-esc-socketcan(Linux) │
│ socketcan ↔ CanLink 桥接 │
└──────────────────────────┘
核心解耦点:CanLink 是一对 tokio 通道(发送 / 接收 CanFrame)。dji-esc 的协议状态机
只面向通道工作,因此:
- 测试中用内存通道 + 一阶电机模型(
dji_esc::sim)构成闭环仿真,全平台可跑; dji-esc-socketcan把真实 SocketCAN 接口桥接到通道,只在实车上出现;- 未来更换总线介质(串口转 CAN、MCU 转发)只需新增一个桥接 crate。
DJI 电调 CAN 协议要点(C620 手册)
| 项目 | 值 |
|---|---|
| 控制帧 ID | 0x200(电调 1–4)、0x1FF(电调 5–8) |
| 控制帧格式 | 8 字节 = 4 × i16 大端电流命令,按电调 ID 顺序 |
| C620 电流标度 | ±16384 ↔ ±20 A |
| C610 电流标度 | ±10000 ↔ ±10 A(M2006 组合,接硬件前需核对) |
| 反馈帧 ID | 0x200 + 电调ID(0x201–0x208) |
| 反馈帧格式 | u16 角度(0..8191) + i16 转速rpm + i16 转矩电流 + i8 温度℃,均大端 |
| 反馈频率 | 每电调 1kHz |
C620 内部只闭电流环:转速 / 位置环由主控侧 PID 实现(motor-core::Pid,
挂在 EscBus 的 1kHz 发送节拍上)。GM3508 减速比 3591 / 187 ≈ 19.203。
单位与方向约定
- 机器人坐标系:ISO 约定——x 前、y 左、ω 逆时针为正(见
mecanum)。 Motor接口呈现的是物理量(安装方向修正后):EscConfig::direction = -1时,驱动层在写命令与读反馈时统一翻转符号, 上层永远以"轮子正转 = 底盘前进方向"的正向工作。MotorState::rotor_speed_rpm为电机转子转速;轮端转速 = 转子转速 / 减速比。- 电流一律以协议原始值(raw)为主,安培换算通过
EscModel常量提供。
安全设计
- 上电门控:底盘循环在收到任一电机首帧反馈前不下发速度命令。
- 反馈离线:任一电机反馈超时(默认 100ms)→ 该电机命令强制 0 电流并告警。
- 命令超时:上层 twist 命令超时(默认 200ms)→ 目标速度归零。
- 所有超时可经
chassis.toml配置。
测试策略
| 层级 | 内容 | 平台 |
|---|---|---|
| 单元测试 | 帧编解码字节级样例 / 饱和、多圈回绕、PID(阶跃、抗饱和、滤波)、运动学解析解 + 属性测试 | 全平台 |
| 闭环仿真 | 内存通道 + 一阶电机模型:4 电机速度环收敛、群帧组装、离线安全、守护进程全链路 | 全平台 |
| vcan 集成 | vcan0 双 socket 收发,真实内核 CAN 栈 | Linux(#[ignore],CI 显式跑) |
| 交叉检查 | aarch64-unknown-linux-gnu 全 workspace check |
CI |
部署
chassisd 为单二进制守护进程:--interface can0 --config /etc/chassisd/chassis.toml。
systemd 样例见 deploy/chassisd.service。板端接口就绪依赖:
USB 转 CAN(gs_usb / candleLight)或 SPI CAN HAT(MCP2515)驱动加载后的 can0。