-
Notifications
You must be signed in to change notification settings - Fork 12
Model And Launch
konodoki edited this page May 21, 2026
·
15 revisions
本页解释模型文件、动作数据、launch 参数和 BxiExample 之间的关系。它补足一个常见缺口:状态类写好了,但模型路径、数据文件、发布保护没有接完整。
模型和动作数据放在:
src/bxi_example_py_elf3/data/
setup.py 中:
def get_data_files():
source_dir = 'data'
target_dir = os.path.join('share', package_name, 'data')这会把 data/ 下所有文件安装到:
install/bxi_example_py_elf3/share/bxi_example_py_elf3/data/
因此新增 .npz / .onnx 后需要重新:
colcon build --symlink-install --packages-select bxi_example_py_elf3仿真 launch:
src/bxi_example_py_elf3/launch/example_demo.launch.py
硬件 launch:
src/bxi_example_py_elf3/launch/example_demo_hw.launch.py
两个文件都有:
npz_file_dict = {
"recover": "data/recover.npz",
"dance": "data/dance.npz",
}
onnx_file_dict = {
"normal": "data/amp_terrain.onnx",
"dance": "data/dance.onnx",
}然后转成绝对路径:
for key, value in npz_file_dict.items():
npz_file_dict[key] = os.path.join(get_package_share_path("bxi_example_py_elf3"), value)再作为 ROS 参数传给节点:
{"/npz_file_dict": json.dumps(npz_file_dict)}
{"/onnx_file_dict": json.dumps(onnx_file_dict)}在:
src/bxi_example_py_elf3/bxi_example_py_elf3/bxi_example_demo.py
load_files() 中:
self.declare_parameter('/npz_file_dict', json.dumps({}))
npz_file_json = self.get_parameter('/npz_file_dict').value
self.npz_file_dict = json.loads(npz_file_json)
self.declare_parameter('/onnx_file_dict', json.dumps({}))
onnx_file_json = self.get_parameter('/onnx_file_dict').value
self.onnx_file_dict = json.loads(onnx_file_json)所以模型 key 必须在 launch 字典里存在。
如果代码写:
self.wave_motion = DanceMotionPolicyGravityIsaaclab(
self.npz_file_dict["wave_motion"],
self.onnx_file_dict["wave_motion"],
)而 launch 没有 "wave_motion",启动就会 KeyError。
改 launch:
- 新增
.npz/.onnx模型文件。 - 新增
BxiExample中要加载的模型对象。 - 仿真和硬件都要能用这个模型。
改状态机 YAML:
- 新增状态。
- 新增状态切换。
- 调整 transition。
- 调整状态构造参数。
改遥控器 YAML:
- 绑定按键。
- 改组合键。
- 改输出到哪个
btn_N=value。
推荐三处使用同一个 key:
launch dict key: wave_motion
BxiExample member: self.wave_motion
state params policy_attr: wave_motion
好处:
- 状态类可以通过
getattr(ctx, policy_attr)找到模型。 - 发布保护的
model_keys可以直接写同一个名字。 - 脚本能删除
self.wave_motion = ...初始化块。
推荐:
class WaveMotionState(RobotControlState):
def __init__(self, name: str, state_id: int, policy_attr: str = "wave_motion"):
super().__init__(name, state_id)
self.policy_attr = policy_attr
def _policy(self, ctx: BxiExample):
return getattr(ctx, self.policy_attr)YAML:
wave_motion:
behavior: WaveMotionState
params:
policy_attr: wave_motion这样同一个状态类可以复用到多个模型:
wave_left:
behavior: WaveMotionState
params:
policy_attr: wave_left
wave_right:
behavior: WaveMotionState
params:
policy_attr: wave_right进入模型状态前推荐:
def on_prepare_enter(self, ctx, from_state, transition):
super().on_prepare_enter(ctx, from_state, transition)
policy = self._policy(ctx)
policy.timestep = policy.start_frame
if hasattr(policy, "timeinit"):
policy.timeinit = 0.0
ctx.preheat_model(policy)预热作用:
- 用当前观测先推理一次。
- 填充模型历史观测。
- 让
get_first_frame()能拿到更合理的target_dof_pos。
如果模型预热也需要速度命令,使用状态自己的 get_cmd_vel(ctx):
ctx.preheat_model(
policy,
with_cmd_vel=True,
cmd_vel=self.get_cmd_vel(ctx),
)这样会使用当前状态 YAML 中配置的 speed_profile。没有 speed_profile 时得到零速度,避免未声明速度能力的状态被遥控速度影响。
模型状态应该实现:
def get_first_frame(self, ctx):
policy = self._policy(ctx)
qpos = getattr(policy, "target_dof_pos", None)
if qpos is None:
qpos = getattr(policy, "default_dof_pos", None)
if qpos is None:
return None
return self._motor_frame(qpos, policy.kps, policy.kds)这样 first_frame_switch 或自定义进入过渡可以平滑进入模型状态。
如果动作是高危内部动作,写:
protected_states:
wave_motion:
behavior: WaveMotionState
events: [wave_motion]
model_keys: [wave_motion]
files:
- ../data/wave_motion.npz
- ../data/wave_motion.onnxmodel_keys 会影响:
- launch 中的
npz_file_dict。 - launch 中的
onnx_file_dict。 - demo node 中的
self.<model_key> = ...初始化块。
KeyError: '<model_key>':
- launch 字典没加 key。
- 只改了仿真 launch,没改硬件 launch。
- 没重新 build。
模型文件找不到:
- 文件不在
data/。 - 文件名和 launch 字典不一致。
- 没重新 build。
状态进入时第一帧为空:
- 没调用
ctx.preheat_model(policy)。 - 模型预热需要速度输入,但没传
cmd_vel=self.get_cmd_vel(ctx)。 - policy 没有
target_dof_pos或default_dof_pos。
发布版还残留模型:
-
release_protection.yaml没写model_keys。 -
files没写对应.npz/.onnx。 -
self.<model_key>名字和 model key 不一致,脚本无法匹配。