Skip to content

Hands On Custom State

konodoki edited this page Jul 23, 2026 · 26 revisions

手把手 1:从零添加自定义状态 Mod

本课创建 com.example.sin_wave,从基础走路状态进入正弦摆动,再按正常模式键返回。

1. 建立目录

先使用脚手架:

bxi-mod new com.example.sin_wave \
  --root src/bxi_example_py_elf3/mods \
  --state sin_wave \
  --template procedural \
  --label 正弦摆动 \
  --index 20
src/bxi_example_py_elf3/mods/com.example.sin_wave/
  mod.yaml
  state.py

2. 写状态

state.py

from dataclasses import dataclass
import math

from bxi_example_py_elf3.utils.state_library import ProceduralState


@dataclass(frozen=True)
class SinWaveParams:
    joint: int = 4
    amplitude: float = 0.25
    frequency: float = 0.5


class SinWaveState(ProceduralState[SinWaveParams]):
    Params = SinWaveParams

    def compute_frame(self, ctx, elapsed):
        qpos = ctx.pos_last.copy()
        qpos[self.params.joint] += self.params.amplitude * math.sin(
            2.0 * math.pi * self.params.frequency * elapsed
        )
        return self.frame(ctx, qpos)

ProceduralState 已经实现进入帧、运行帧、时间重置和正常电机输出。advance=False 由基类保证不推进 elapsed

3. 写清单

mod.yaml

id: com.example.sin_wave
version: 1.0.0

requires:
  - id: com.bxi.basic_actions
    version: ">=1,<2"

events:
  activate: {slot: btn_10, value: 8}

states:
  sin_wave:
    factory: state:SinWaveState
    label: 正弦摆动
    index: 20
    group: Customer
    icon: waves
    params:
      joint: 4
      amplitude: 0.25
      frequency: 0.5

routes:
  - from: com.bxi.basic_actions/normal
    event: activate
    to: sin_wave
    transition: first_frame_switch

  - from: sin_wave
    event: com.bxi.basic_actions/normal
    to: com.bxi.basic_actions/normal
    transition: dual_running_blend

schema/api 省略时默认为 1。类上的 Params 让约定 factory 自动构造 dataclass,所以不需要 plugin.py

4. 构建和验证

colcon build --packages-select bxi_example_py_elf3 \
  --symlink-install --merge-install
source install/setup.bash
bxi-mod validate src/bxi_example_py_elf3/mods/com.example.sin_wave
bxi-mod inspect src/bxi_example_py_elf3/mods/com.example.sin_wave

启动日志应包含:

Mod com.example.sin_wave@1.0.0

状态完整名是 com.example.sin_wave/sin_wave。此时还没有遥控器输出 btn_10=8,可先用测试发布或继续第 3 课完成绑定。

检查清单

  1. factory: state:SinWaveState 的模块和类存在。
  2. 跨 Mod 引用有完整名称和 requires
  3. 参数名与 dataclass 字段一致、类型正确。
  4. ProceduralStateadvance=False 不推进 elapsed。
  5. index 与现有状态错开;若冲突会自动调整并告警。

下一课:模型动作状态

要继续把这个状态逐步升级成模型、Resource、自定义 Transition、ROS 和 Driver,进入 渐进式状态实战

Clone this wiki locally