解读 11 · robotd/params.rs + robotd-params:参数系统
解读对象:
robotd/src/params.rs(7 行)、robotd-params/(lib.rs 2977 行、edit.rs 1353 行、registry.rs 614 行)
需要的前置:更新与回滚背景见解读 18;技能如何被消费见解读 09
1. 七行文件讲的原则:别复制 schema
robotd/src/params.rs 全文只有一句 pub use robotd_params::*;,模块注释把动机说满(params.rs:1-7):类型搬出去,是因为 robotctl configure 要用真实的 schema、真实的默认值、真实的校验去编辑配置文件,而不是对着一份会漂移的副本。"复制 schema"是参数系统最常见的死法:库里的默认值和编辑器里的提示各一份,半年后没人知道哪份是真的。
crate 注释接着给出三条地基(lib.rs:1-17):启动读一次,不监视——这条"承重"在于工具链:文件的任何改动都要重启 robotd,所以编辑器永远不必问"哪个键是活的";文件住在 releases/<ver>/ 之外(lib.rs:9-10),更新和回滚都不动它——这是每台机器人自己的配置,不是出厂默认;独立成 crate 只为一个消费者:robotctl configure 的交互式编辑器。
2. 路径即架构
lib.rs 顶部的四个常量浓缩了部署模型:RELEASE_DIR = /opt/robot/daemon/current(lib.rs:27)是发布挂载点;POLICY_DIR = /opt/robot/policies/current(lib.rs:40)故意在发布目录外——注释写明:步态重训不该连着守护进程一起发,守护进程修复也不该重下六 MB 不变的权重,两者独立版本化,current 是个符号链接,"正是更新器已经在原子交换的那个形状";POLICY_LIBRARY = /var/lib/robot/policies(lib.rs:48)放从 Hub 单独取的策略,目录镜像仓库布局 <org>/<name>/<revision>/,路径本身说明来源;DEFAULT_PATH = /etc/robot/robotd.toml(lib.rs:51)。
3. 一个文件管一台鸭子,枚举管可选值
Params(lib.rs:55-68)十个段:bus、control、update_gate、policy、safety、audio、theremin、chorale、media、detect 加 pad。serde 的 deny_unknown_fields 让写错的键名在启动时报错。可选项的语义靠小枚举表达:Quality 把"分辨率、帧率、码率"捆成一个名字(lib.rs:150-178):"1080p 配 720p 的 2 Mb/s 是一团糊",四个独立键让每种错误组合都可表达;Mode::Walk/Roller 一开关切整套策略加调参(lib.rs:588)。
技能是最有味道的一段:SkillDef(lib.rs:695-745)把原型里"三条只差四个数字的硬编码臂"(踢腿×2 和侧滚)泛化成数据——name、duration、command(窗口内喂的 twist)、unwind/unwind_s(给不会自己结束的策略补收尾)、chain(按住连发)。解析顺序在 resolved_skills_with(lib.rs:1273):官方策略集的 SetManifest 优先(lib.rs:806),没有则回退 fallback_skills 的三件套(lib.rs:1085),配置按名字合并覆盖,"文件是决策清单,不是默认值的抄本"。DAEMON_OWNED_SKILLS = ["ground_pick", "sit_toggle"](lib.rs:1026)守住守护进程自己驱动的两个名字不被策略集冒领。
4. registry:让"编辑器知道一切"成为测试
robotd-params/src/registry.rs 是机器可读的键索引:REGISTRY(registry.rs:90)每键一条——说明文字、取值类型 Kind(registry.rs:20,布尔/整数/枚举选择/路径,连"重复表 [[policy.skill]] 不可就地编辑"都是显式的 Kind::Table 变体)。防漂移靠测试(registry.rs:5-9):the_registry_covers_every_key_exactly 把 Params::default() 序列化后走一遍键树——每个叶子必须在场且不许多。加了段而忘教编辑器?构建照样绿,测试会点名列出缺失的键。
你带走的收获
- schema 只留一份:程序消费类型,编辑器消费 registry,两者由测试钉在同一真相上。
- 把"读一次不热载"这类约束写出来,下游工具才能依赖它。
- 相关数值捆成一个命名选项;默认值组合是产品决策,不暴露全部自由度。
- 数据驱动替换硬编码分支时,保留回退默认和"决策清单而非默认抄本"的合并语义;发布件与用户配置分目录,回滚才不会回滚掉用户的选择。