-
Notifications
You must be signed in to change notification settings - Fork 12
Model And Launch
本页解释模型文件、动作数据、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 --packages-select bxi_example_py_elf3如果正在使用热重载,不建议用 --symlink-install。普通 build 会在修改完成后更新 install/ 目录,从而触发一次热重载;--symlink-install 会让编辑器自动保存直接触发重载。
仿真 launch:
src/bxi_example_py_elf3/launch/example_demo.launch.py
硬件 launch:
src/bxi_example_py_elf3/launch/example_demo_hw.launch.py
launch 只负责启动环境和节点参数,例如:
{"/topic_prefix": "simulation/"}
{"/state_machine_config": state_machine_config}
{"/hot_reload": True}模型路径不再通过 launch 的 npz_file_dict / onnx_file_dict 传入。
模型在:
src/bxi_example_py_elf3/bxi_example_py_elf3/bxi_example_demo.py
load_models() 中直接声明:
self.withoutarm: HumanoidGaitPolicyLiteIsaaclab = HumanoidGaitPolicyLiteIsaaclab(
model_file("isaaclab_model/withoutarm.onnx")
)model_file() 会从包的 data/ 目录解析文件路径,并记录当前模型文件。记录到的 .onnx / .npz 会参与热重载监控。热重载调试时推荐普通 build,不使用 --symlink-install,避免自动保存导致频繁重载。
如果要换模型,直接改这里:
self.withoutarm: HumanoidGaitPolicyLiteIsaaclab = HumanoidGaitPolicyLiteIsaaclab(
model_file("isaaclab_model/new_withoutarm.onnx")
)热重载细节看 热重载。
改 launch:
- 切换仿真或硬件入口。
- 调整
topic_prefix。 - 调整
state_machine_config。 - 调整
/hot_reload默认值。 - 调整硬件启动时需要附带的底层节点或辅助节点。
改 bxi_example_demo.py:
- 新增或替换
.npz/.onnx模型文件。 - 新增
BxiExample中要加载的模型对象。 - 调整模型构造参数,例如
start_frame。
改状态机 YAML:
- 新增状态。
- 新增状态切换。
- 调整 transition。
- 调整状态构造参数。
改遥控器 YAML:
- 绑定按键。
- 改组合键。
- 改输出到哪个
btn_N=value。 - 调整
system.*动作,让遥控器触发启动、停止或其他运维命令。
硬件入口通常还会包含单实例保护,避免同一个硬件控制链被重复启动。如果启动时报已有实例在运行,先通过停止动作或手动清理已有进程,再重新启动。
遥控器的 system action 可以同时编排主控制节点和辅助节点。文档不要依赖某条具体命令;实际部署以 src/remote_controller/config/xbox_default.yaml 中的 system、system_mutexes 和 system_reset_motion_after 为准。
推荐两处使用同一个 key:
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
model_keys: [wave_motion]
files:
- ../data/wave_motion.npz
- ../data/wave_motion.onnxmodel_keys 会影响:
- demo node 中的
self.<model_key> = ...或self.<model_key>: Type = ...初始化块。
要删除的 .npz / .onnx 必须显式写在 files 中。model_keys 不会隐式删除模型文件。
模型成员不存在:
-
bxi_example_demo.py没声明self.<model_key>。 - YAML 的
policy_attr和BxiExample成员名不一致。 - 热重载失败后仍在使用旧代码,查看日志中的
hot reload failed。
模型文件找不到:
- 文件不在
data/。 -
model_file("...")里的文件名写错。 - 当前运行环境没有看到新增文件;普通 build 场景下需要重新
colcon build --packages-select bxi_example_py_elf3。
状态进入时第一帧为空:
- 没调用
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 不一致,脚本无法匹配。