Files
linux_sentry_chassis/README.md
T

10 KiB
Raw Blame History

sentry-chassis

机甲大师哨兵机器人麦轮底盘固件:Linux ARM 主控 + 4 × GM3508(C620 电调),CAN 接入(SocketCAN 或串口 slcan),tokio 异步架构。

架构一览

crate 职责 平台
motor-core 电机抽象:能力 trait、MotorState、PID / 速度环 / 位置环 纯逻辑,全平台
can-link CAN 传输抽象:CanFrame + CanLink 通道对(无协议知识) 纯逻辑,全平台
dji-esc C620/C610 CAN 协议:帧编解码、多圈累计、EscBus 异步驱动 纯逻辑,全平台
dji-esc-sim 被控对象仿真:摩擦 / 延迟 / 负载模型、场景与离线评估 harness、异步假电调 纯逻辑,全平台
dji-esc-socketcan SocketCAN 后端:真实 CAN 接口 ↔ 内存通道桥接 Linux
dji-esc-slcan slcan 串口后端:CANable 等 USB 适配器 ↔ 内存通道桥接 全平台
mecanum 麦轮正 / 逆运动学(纯数学) 全平台
chassis-config chassis.toml schema:解析、校验、写回(守护进程与整定工具共用) 全平台
chassis-bench 台架:激励场景、安全包络、真机试验采样 + chassis-spin / socketcan-spin 全平台(SocketCAN 工具需 Linux)
chassis-tune 速度环 PID 自动整定:参数空间搜索 + 指标 / 成本 + 报告(仿真 / 真机)+ 版本化超参数预设 全平台
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 锁定)。

cargo test --workspace          # 单测 + 闭环仿真测试(无需硬件)
cargo run -p chassisd -- --mock # 无硬件全链路演示
just tune-smoke                 # 自动整定冒烟(确定性,无需硬件,CI 同款)
just lint                       # fmt + clippy(与 CI 同标准)

Linux 虚拟 CAN(vcan0)集成测试

just vcan-test   # 或见 justfile 内的 modprobe / ip link 命令

台架:四轮 500 rpm 旋转测试(slcan)

实车台架验证工具 chassis-spin:四轮同时以固定转子转速旋转(默认 500 rpm, 轮端 = 转子 ÷ 减速比 ≈ 26 rpm),带缓升、过速保护、上电门控与安全停机。

# 本机直接跑(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、电流)和同一套硬约束 (过速 / 长时间饱和 / 不收敛直接判罚,不参与权重折衷)。

# 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),因此可以直接拿实车配置当输入:

# 用 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,无需交叉工具链:

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(chassisd / chassis-bench 均可),无需 ip link。

实车运行:/tmp/chassisd --config /tmp/chassis.toml --interface can0。板上运行样例见 deploy/chassisd.service,配置样例见 config/chassis.toml.example。

注意:电调未上电 / CAN 线未接时,SocketCAN 侧会因无 ACK 进入 bus-off(可用 ip -d link show can0 查看),chassisd 侧表现为四电机反馈离线、强制零电流—— 这正是安全设计的预期行为。

文档

  • 底盘开发文档——硬件接线、坐标与单位约定、控制与安全设计、配置参考、 标定与上车流程、自动整定与超参数预设、台架工具、故障排查(开发 / 调试 / 上车先看这份)
  • 架构设计——分层、CAN 协议要点、单位与方向约定、被控对象模型、参数空间搜索、测试策略
  • 整体架构规划——全系统(含云台 / 发射 / IMU / 实时性)的 crate 划分与阶段计划