Files
linux_sentry_chassis/README.md
T

172 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# sentry-chassis
机甲大师哨兵机器人麦轮底盘固件:Linux ARM 主控 + 4 × GM3508(C620 电调),CAN 接入(SocketCAN 或串口 slcan),tokio 异步架构。
## 架构一览
| crate | 职责 | 平台 |
| --- | --- | --- |
| [`motor-core`](crates/motor-core) | 电机抽象:能力 trait、`MotorState`、PID / 速度环 / 位置环 | 纯逻辑,全平台 |
| [`can-link`](crates/can-link) | CAN 传输抽象:`CanFrame` + `CanLink` 通道对(无协议知识) | 纯逻辑,全平台 |
| [`dji-esc`](crates/dji-esc) | C620/C610 CAN 协议:帧编解码、多圈累计、`EscBus` 异步驱动 | 纯逻辑,全平台 |
| [`dji-esc-sim`](crates/dji-esc-sim) | 被控对象仿真:摩擦 / 延迟 / 负载模型、场景与**离线评估 harness**、异步假电调 | 纯逻辑,全平台 |
| [`dji-esc-socketcan`](crates/dji-esc-socketcan) | SocketCAN 后端:真实 CAN 接口 ↔ 内存通道桥接 | Linux |
| [`dji-esc-slcan`](crates/dji-esc-slcan) | slcan 串口后端:CANable 等 USB 适配器 ↔ 内存通道桥接 | 全平台 |
| [`mecanum`](crates/mecanum) | 麦轮正 / 逆运动学(纯数学) | 全平台 |
| [`chassis-config`](crates/chassis-config) | `chassis.toml` schema:解析、校验、写回(守护进程与整定工具共用) | 全平台 |
| [`chassis-bench`](crates/chassis-bench) | 台架:激励场景、安全包络、真机试验采样 + `chassis-spin` / `socketcan-spin` | 全平台(SocketCAN 工具需 Linux) |
| [`chassis-tune`](crates/chassis-tune) | **速度环 PID 自动整定**:参数空间搜索 + 指标 / 成本 + 报告(仿真 / 真机)+ 版本化**超参数预设** | 全平台 |
| [`chassisd`](crates/chassisd) | 底盘守护进程:配置、1kHz 控制循环、安全逻辑、`--mock` 模式 | 全平台(实车需 Linux) |
分层原则:`motor-core`、`dji-esc`、`dji-esc-sim` 不做任何真实 I/O——CAN 端口被抽象为一对 tokio 通道
(`CanLink`),因此协议、运动学、控制与整定逻辑可以在 macOS / CI 上完整测试;真实总线只出现在最外层
(`dji-esc-socketcan` / `dji-esc-slcan`,以及组合它们的 `chassis-bench` / `chassisd`)。
> 运输后端 crate(`dji-esc-slcan` / `dji-esc-socketcan`)只做桥接,**不含应用**;
> 台架程序住在 `chassis-bench`,自动整定住在 `chassis-tune`。
> **命令是租约**:`EscMotor::set_velocity` / `set_effort_raw` / `set_position` 每次调用即续租,
> 超过 `BusOptions::command_timeout`(默认 50ms)未刷新,驱动强制 0 电流。
> 控制循环必须**逐拍重发**同一个设定值(`chassisd` 的 1kHz 循环天然满足)。
## 开发
需要 Rust stable(仓库通过 `rust-toolchain.toml` 锁定)。
```sh
cargo test --workspace # 单测 + 闭环仿真测试(无需硬件)
cargo run -p chassisd -- --mock # 无硬件全链路演示
just tune-smoke # 自动整定冒烟(确定性,无需硬件,CI 同款)
just lint # fmt + clippy(与 CI 同标准)
```
### Linux 虚拟 CAN(vcan0)集成测试
```sh
just vcan-test # 或见 justfile 内的 modprobe / ip link 命令
```
## 台架:四轮 500 rpm 旋转测试(slcan)
实车台架验证工具 `chassis-spin`:四轮同时以固定**转子**转速旋转(默认 500 rpm,
轮端 = 转子 ÷ 减速比 ≈ 26 rpm),带缓升、过速保护、上电门控与安全停机。
```sh
# 本机直接跑(CANable2 在 /dev/ttyACM0)
cargo run --release -p chassis-bench --bin chassis-spin -- --device /dev/ttyACM0
# 只验证链路与反馈,不发非零电流(接线排查首选)
cargo run --release -p chassis-bench --bin chassis-spin -- --device /dev/ttyACM0 --dry-run
# 目标板(T153,armv7):交叉编译 → 推送 → 运行
just bench-spin # 默认 root@192.168.2.2 + /dev/ttyACM0 + 500 rpm
just bench-check # 同上,但只做 dry-run
```
安全与使用要点:
- **轮子必须架空或整车固定**;ctrl-c 随时安全停机(先 0 电流再关总线)。
- 上电门控:四个电调都上报新鲜反馈前绝不下发速度;只接了部分电调时用 `--allow-partial` 降级。
- 过速保护:任一电调超过 `--max-rpm`(默认 目标 × 2 + 200)持续 60ms 即立即停机。
- 空载台架的合适整定与带载完全不同:默认 `kp=2 ki=10 ff=0 --current-limit 1500`,
空载**不要**加前馈(会直接把轮子推到最高速度)。
## 自动整定(chassis-tune)
手动试凑 `kp/ki/kd/ff` 既慢又难复现。`chassis-tune` 把这件事变成**参数空间搜索**:
种子化分层粗扫(`rayon` 并行)→ 以 top-k 为起点做多起点 `argmin` 局部精修(Nelder-Mead / PSO),
每次评估都用同一套指标(上升时间、超调、调节时间、稳态误差、IAE、电流)和同一套硬约束
(过速 / 长时间饱和 / 不收敛直接判罚,不参与权重折衷)。
```sh
# 0) 看有哪些超参数预设(只读;预设文件见 config/tune.toml)
cargo run -p chassis-tune -- presets
# 1) 仿真搜索(默认,不碰硬件;同 seed 结果逐位一致)
cargo run --release -p chassis-tune -- sweep --samples 512 --out-dir target/tune
# 1b) 用预设跑:超参数(区间 / 场景 / 权重 / 阈值 / 预算 / 安全包络)进版本管理
# 优先级:内置默认 < 预设文件 < 显式 CLI(逐字段覆盖)
cargo run --release -p chassis-tune -- sweep \
--preset config/tune.toml --preset-name bench_loaded
# 2) 只复算一组给定增益(CI / 回归用,按验收阈值给退出码:0 通过 / 1 未通过 / 2 参数错)
cargo run -p chassis-tune -- validate --gains 2,10,0,0
# 3) 台架复验(**轮子会转**:必须架空或整车固定、急停可及)
cargo run --release -p chassis-tune -- sweep \
--preset config/tune.toml --preset-name bench_noload \
--device /dev/ttyACM0 --esc-id 1 --i-know-the-wheel-spins
```
随仓库提供的预设(`config/tune.toml`):
| 预设 | 后端 | 用途 |
| --- | --- | --- |
| `sim_bench_model`(默认) | 仿真 | 台架量级模型全量搜索:评审 / CI / 代码回归基准 |
| `sim_ideal` | 仿真 | 理想模型秒级回归(结果**不可直接上车**) |
| `bench_noload` | 真机 | 空载台架,小样本局部搜索,前馈固定 0 |
| `bench_loaded` | 真机 | 带载(整车落地),前馈区间上调 |
| `field_updown` | 真机 | 实战验收:升 / 降 / 回零双向,阈值收紧 |
预设**不能**携带 `current_limit` / `direction` / `gear_ratio`(写了直接报错)——
安全与机械约束只来自 `chassis.toml` 或显式 CLI。
产物(`--out-dir`):`trials.csv`(全部候选与判定)、`best.toml`(可粘贴的增益片段)、
`best-trace.csv`、`report.md`、`summary.json`;台架模式另有 `hil-validation.csv`(同一组增益的重复性复验)。
加 `--features plot` 还会输出 `best.svg` 三联图。
整定工具与守护进程**共用同一份配置 schema**(`chassis-config`),因此可以直接拿实车配置当输入:
```sh
# 用 chassis.toml 里的限流 / 电调 ID / 方向 / 减速比(这些**不参与搜索**),
# 打印与现有增益的成本对比,并把结果写回一份新配置
cargo run --release -p chassis-tune -- sweep \
--config config/chassis.toml.example --motor front_left \
--write-config target/chassis.tuned.toml
```
要点:
- **仿真整定只保证在被控对象模型内最优**。模型里的摩擦 / 延迟是量级估计,且不含测量噪声,
因此仿真最优解可能偏激进;交付前必须用同一 `--scenario` 跑一次 `--backend bench` 复验。
- 最优解贴到参数空间边界时报告会明确提示——那是"约束在决定结果",应放宽 `--kp` / `--ki` 再搜。
- 台架搜索串行执行(只有一条总线),每次试验后强制 0 电流并静默 `--between-trials-ms`;
过速 / 过温 / 掉线 / 超时 / ctrl-c 任一命中即停机并收工。
- `current_limit`、`direction`、`gear_ratio` 属于安全与机械约束,**不参与搜索**。
- 换一组工况先加**预设**(`config/tune.toml`)而不是复制一长串命令行:
`chassis-tune presets` 查看、`--preset-name` 选用、CLI 只覆盖本次要变的项。
## 部署到目标板(armv7,实测:创龙 T153 / Ubuntu 22.04)
二进制为 musl 静态链接,不依赖板端 libc,无需交叉工具链:
```sh
just deploy # 编译 + 推送 + mock 试运行(默认 root@192.168.2.2)
# 或手动:
cargo build --release -p chassisd --target armv7-unknown-linux-musleabihf
scp target/armv7-unknown-linux-musleabihf/release/chassisd root@192.168.2.2:/tmp/
```
板端 CAN 有两条互斥路径:
- **SocketCAN**(板载原生 CAN 控制器,走 `can0`/`can1`):
`ip link set can0 up type can bitrate 1000000 restart-ms 100`,配 `--interface can0`。
- **slcan**(USB 适配器,如 CANable2 在 CDC ACM 下枚举为 `/dev/ttyACM0`):
用 [`dji-esc-slcan`](crates/dji-esc-slcan)(`chassisd` / [`chassis-bench`](crates/chassis-bench) 均可),无需 `ip link`。
实车运行:`/tmp/chassisd --config /tmp/chassis.toml --interface can0`。板上运行样例见
[`deploy/chassisd.service`](deploy/chassisd.service),配置样例见
[`config/chassis.toml.example`](config/chassis.toml.example)。
> 注意:电调未上电 / CAN 线未接时,SocketCAN 侧会因无 ACK 进入 bus-off(可用
> `ip -d link show can0` 查看),chassisd 侧表现为四电机反馈离线、强制零电流——
> 这正是安全设计的预期行为。
## 文档
- [**底盘开发文档**](docs/chassis.md)——硬件接线、坐标与单位约定、控制与安全设计、配置参考、
**标定与上车流程**、自动整定与超参数预设、台架工具、故障排查(开发 / 调试 / 上车先看这份)
- [架构设计](docs/architecture.md)——分层、CAN 协议要点、单位与方向约定、被控对象模型、参数空间搜索、测试策略
- [整体架构规划](ARCHITECTURE.md)——全系统(含云台 / 发射 / IMU / 实时性)的 crate 划分与阶段计划