-
Notifications
You must be signed in to change notification settings - Fork 12
Hands On Model State
konodoki edited this page Jul 27, 2026
·
22 revisions
本课在独立 Mod 中放置 .npz 和 .onnx,通过可配置加载策略的资源交给状态使用。
mods/com.example.motion/
mod.yaml
plugin.py
state.py
assets/
motion.npz
motion.onnx
复用框架的 MotionReplayState:
from bxi_example_py_elf3.inference.beyondmimic import (
DanceMotionPolicyGravityIsaaclab,
)
from bxi_example_py_elf3.mod_api import ResourceHandle
from bxi_example_py_elf3.mod_api import MotionReplayState
class ExampleMotionState(
MotionReplayState[DanceMotionPolicyGravityIsaaclab]
):
def __init__(self, name, state_id, policy):
super().__init__(
name,
state_id,
policy,
finish_trigger="example_motion_finished",
end_frame_trim=20,
end_transition={
"profile": "dual_running_blend",
"duration": 0.6,
"sample_from": True,
},
)基类负责重置 timestep、预热、进入帧、运行采样、播放结束返回基础 normal 和暂停 action。
plugin.py:
from bxi_example_py_elf3.inference.beyondmimic import (
DanceMotionPolicyGravityIsaaclab,
)
from bxi_example_py_elf3.mod_api import (
ModDefinition,
ModLoadContext,
ResourceKey,
ResourceLoadContext,
)
from .state import ExampleMotionState
POLICY = ResourceKey[DanceMotionPolicyGravityIsaaclab](
"com.example.motion/policy"
)
def _load(context: ResourceLoadContext):
return DanceMotionPolicyGravityIsaaclab(
str(context.asset("assets/motion.npz")),
str(context.asset("assets/motion.onnx")),
start_frame=0,
)
def create_mod(context: ModLoadContext) -> ModDefinition:
context.register_resource(POLICY, _load, loading="lazy")
policy = context.resource(POLICY)
return ModDefinition(
state_factories={
"motion": lambda state: ExampleMotionState(
state.name, state.state_id, policy
)
}
)这里选择 lazy,所以加载 Mod 不会创建推理器;状态首次访问 handle 时才加载
文件。如果模型初始化时间可能超过控制周期,改为 loading="eager",框架会在
控制循环启动前完成加载,失败则直接终止启动。
schema: 1
id: com.example.motion
name: 模型动作
version: 1.0.0
api: ">=1,<2"
enable: true
entrypoint: plugin:create_mod
visibility: public
requires:
- {id: com.bxi.basic_actions, version: ">=1,<2"}
conflicts: []
python_exports: []
runtime_requirements:
python: []
ros: []
system: []
events:
activate: {slot: btn_10, value: 8}
toggle_pause: {slot: btn_9, value: 1}
states:
motion:
manifest:
label: 模型动作
priority: 100
group: Customer
icon: animation
confirm: true
confirm_message: 请确保周围安全
routes:
- {from: com.bxi.basic_actions/normal, event: activate, to: motion, transition: soft_switch}
- {from: motion, event: com.bxi.basic_actions/normal, to: com.bxi.basic_actions/normal, transition: dual_running_blend}
- {from: motion, event: com.bxi.basic_actions/zero_torque, to: com.bxi.basic_actions/zero_torque}
actions:
- {from: motion, event: toggle_pause, action: toggle_pause, manifest: {label: 暂停/继续}}Transition 是两个状态之间的临时控制过程:状态图已经决定要从哪里切到哪里,Transition 再决定切换期间怎样生成 qpos/kp/kd。模型第一帧和当前电机帧可能差异很大,因此通常需要保持、增益渐变或双状态混合,避免直接换帧造成突跳。上例进入前使用短暂保持,返回 normal 时混合动作模型与行走模型的运行帧。
- 先离线加载 Mod,确认资源仍是未加载状态。
- 仿真进入动作,确认
on_prepare()预热成功。 - 检查第一帧、结束帧和
end_frame_trim。 - 检查安全退出与 normal 返回。
- 最后再进入真机低增益验证。
下一课:绑定按键。