Skip to content

Hands On High Ceiling

konodoki edited this page Jul 24, 2026 · 19 revisions

手把手 7:工程化组合示例

本课把前几课的单状态示例升级成可独立部署的客户动作包。

推荐目录

/opt/bxi/mods/com.customer.motion_pack/
  mod.yaml
  plugin.py
  walk_state.py
  gesture_state.py
  transitions.py
  assets/
    locomotion.onnx
    gesture.npz
    gesture.onnx

系统 YAML 只追加根:

mod_paths:
  - /opt/bxi/mods

清单规划

schema: 1
id: com.customer.motion_pack
version: 1.2.0
api: 1
entrypoint: plugin:create_mod
requires:
  - {id: com.bxi.basic_actions, version: ">=1,<2"}

events:
  customer_walk: {slot: btn_10, value: 8}
  customer_gesture: {slot: btn_10, value: 9}
  toggle_pause: {slot: btn_9, value: 1}

speed_profiles:
  customer_walk:
    vx_scale: 0.5
    vx_min: -0.3
    vx_max: 0.5
    vy_scale: 0.3
    yaw_scale: 0.5

transition_profiles:
  safe_entry:
    type: sequence
    steps:
      - {type: hold, duration: 0.02}
      - type: entry_gain_ramp
        duration: 0.8
        kp_from: zero
        kd_from: target

states:
  customer_walk:
    manifest: {label: 客户步态, index: 30, group: Customer}
    speed_profile: customer_walk
  customer_gesture:
    manifest:
      label: 客户动作
      index: 31
      group: Customer
      confirm: true
      confirm_message: 请确保周围安全

routes:
  - {from: com.bxi.basic_actions/normal, event: customer_walk, to: customer_walk, transition: safe_entry}
  - {from: com.bxi.basic_actions/normal, event: customer_gesture, to: customer_gesture, transition: safe_entry}
  - {from: customer_walk, event: com.bxi.basic_actions/normal, to: com.bxi.basic_actions/normal, transition: dual_running_blend}
  - {from: customer_gesture, event: com.bxi.basic_actions/normal, to: com.bxi.basic_actions/normal, transition: dual_running_blend}
  - {from: customer_gesture, event: toggle_pause, action: toggle_pause}
  - {from: customer_gesture, event: com.bxi.basic_actions/zero_torque, to: com.bxi.basic_actions/zero_torque}

这里把 route 和 Transition 分开规划:route 决定事件触发后的目标状态,Transition 负责切换期间的电机帧。模型之间的 qpos/kp/kd 可能不连续,所以进入时逐步建立目标控制力,返回行走时混合两边的运行输出,避免直接换帧产生突跳。

插件边界

  • 资源 factory 只解析 Mod 内资产。
  • 两个状态共享的模型只注册一次。
  • 所有清单参数由 StateBuildContext 消费。
  • 业务过渡模块由 plugin.py 顶层导入。
  • 状态的 ROS 资源在 on_bind/on_unbind 对称管理。

安全策略

  • 高风险入口使用 manifest.confirm
  • 姿态异常时主动请求 com.bxi.basic_actions/zero_torque
  • 模型完成时明确返回基础 normal 或 pd_brake。
  • 进入模型前预热,过渡取消时撤销临时状态。
  • 真机默认速度 profile 从保守范围开始。

热重载验证

分别测试:

  1. 修改清单参数成功重载。
  2. 替换模型成功重载。
  3. 故意制造工厂/状态键不匹配,确认旧运行时继续工作。
  4. 删除当前状态所在 Mod,确认按系统 initial state 回退。
  5. 过渡中修改文件,确认重载延后。

发布策略

整个客户包需要从公开版删除时添加:

visibility: protected

随后运行 sanitizer 自检。若只保护其中一个动作,应先把它拆成独立 Mod;发布工具不会裁剪包内单个状态。

工程化检查

  1. Mod id、资源 key、过渡 type 全局唯一。
  2. 跨 Mod route 均有依赖。
  3. index 使用团队预留区间;自动重分配只作兜底。
  4. 输入输出槽位已与遥控器配置对齐。
  5. 所有状态能力满足实际 transition profile。
  6. 仿真、热重载失败回滚和公开树都已验证。

Clone this wiki locally