-
Notifications
You must be signed in to change notification settings - Fork 12
Model And Launch
模型和动作数据属于使用它们的 Mod,放在该 Mod 的 assets/。运行时通过资源管理器按声明的 eager/lazy 策略加载,不再把模型对象动态挂到 BxiExample。
mods/com.example.motion/
mod.yaml
plugin.py
state.py
assets/
motion.npz
policy.onnx
setup.py 会递归安装整个 mods/,同时跳过 __pycache__、.pyc 和 .pyo。
from bxi_example_py_elf3.framework.mod_api import (
ModDefinition,
ModLoadContext,
ResourceKey,
ResourceLoadContext,
)
POLICY = ResourceKey[MotionPolicy]("com.example.motion/policy")
def _load(context: ResourceLoadContext) -> MotionPolicy:
return MotionPolicy(
str(context.asset("assets/motion.npz")),
str(context.asset("assets/policy.onnx")),
)
def create_mod(context: ModLoadContext) -> ModDefinition:
context.register_resource(POLICY, _load, loading="eager")
policy = context.resource(POLICY)
return ModDefinition(
state_factories={
"motion": lambda state: MotionState(
state.name, state.state_id, policy
)
}
)ResourceKey 必须全局命名。context.asset() 会拒绝逃出当前 Mod assets/ 的路径,并确认文件存在。
context.resource(POLICY) 只返回 ResourceHandle。loading="lazy" 在状态
第一次调用 handle.get() 时创建模型,适合不常进入的动作;loading="eager"
在框架启动、控制定时器开始前创建模型,适合加载时间较长且切换时不能阻塞的
策略。之后都返回相同实例。加载策略硬编码在资源注册代码中,不写入
mod.yaml。
节点关闭时,资源管理器会按逆序调用已加载实例的 close()(若存在),然后清空缓存。
多个状态共享模型时,让它们持有同一个 handle。多个 Mod 共享模型时,优先拆出一个无状态资源 Mod,并用 requires 声明依赖。
class MotionState(RobotControlState, EntryFrameProvider):
def __init__(self, name, state_id, policy):
super().__init__(name, state_id)
self._policy = policy
@property
def policy(self):
return self._policy.get()
def on_prepare(self, ctx, from_state):
self.policy.timestep = self.policy.start_frame
ctx.preheat_model(self.policy)模型预热放 on_prepare(),不要在插件加载或状态构造阶段执行推理。进入失败时可在 on_prepare_cancel() 撤销临时状态。
基础动作模型位于 mods/com.bxi.basic_actions/assets/。后空翻、前空翻、芭蕾舞和深度感知行走资产分别位于各自独立 Mod 的 assets/。
深度感知行走的模型和策略都属于 com.bxi.normal_depth Mod;策略实现位于
mods/com.bxi.normal_depth/depth.py,只依赖通用 framework/inference,公共 policies 不会
反向导入它。可替换的相机或感知节点通过标准 ROS 话题接入,不属于模型 Resource。
量化校准必须使用模型真正收到的输入分布。不要拿随机数组或原始相机帧直接 校准:深度策略的输入还包含 observation history、深度裁剪、归一化和多帧选择。
框架提供 CalibrationDatasetRecorder。它在最终 _policy_inputs 构造完成后做
连续 float32 快照,并把磁盘 IO 放到后台线程。启动时显式打开:
BXI_RKNN_CALIBRATION_DIR=/tmp/bxi_rknn_calibration \
BXI_RKNN_CALIBRATION_EVERY=5 \
BXI_RKNN_CALIBRATION_MAX=500 \
ros2 launch bxi_example_py_elf3 example_demo_hw.launch.py变量含义:
-
BXI_RKNN_CALIBRATION_DIR:校准集根目录;不设置就完全关闭采集。 -
BXI_RKNN_CALIBRATION_EVERY:每多少次真实推进的策略调用采一组,默认 5。 -
BXI_RKNN_CALIBRATION_MAX:每个模型最多保留多少组,默认 500。
每个模型独立生成 <root>/<model>/dataset.txt、capture.json 和每个输入对应的
.npy。一行严格对应一次推理,文件顺序就是 ONNX 输入顺序,因此同样支持未来
的 N 输入模型。预览过渡使用的 advance=False 不会污染校准集。
只有实际运行的策略才会产生样本。当前默认 mode: origin_camera 对应
dagger2.onnx;要采集 normal_depth.onnx,需切换为 mode: depth_walk 另跑一次。
把校准目录复制到安装了 RKNN Toolkit2 2.3.2 的 x86_64 转换机后执行:
PYTHONNOUSERSITE=1 python3 tools/benchmark/quantize_rknn.py \
src/bxi_example_py_elf3/mods/com.bxi.normal_depth/assets/dagger2.onnx \
src/bxi_example_py_elf3/mods/com.bxi.normal_depth/assets/normal_depth.onnx \
--calibration-root /path/to/bxi_rknn_calibration \
--install工具会在转换前校验输入数量与顺序、shape、float32、NaN/Inf 和最少样本数,
然后强制重建 W8A8 缓存并原子安装到 ONNX 旁边。量化模型仍必须在 RK3588 上
重新做后端延迟测试和真实输入/闭环动作验证;校准成功不等于控制策略精度自动
合格。
example_walk.launch.py 和硬件版本中给独立 MJLab 节点使用的模型路径是:
mods/com.bxi.basic_actions/assets/model_normal.onnx
launch 负责启动仿真或硬件、设置 /topic_prefix、覆盖 /state_machine_config 和状态信息参数。Mod 自己使用的模型路径不应硬编码进 launch;由资源加载函数相对 Mod 根解析。
colcon build --packages-select bxi_example_py_elf3 --symlink-install --merge-install
find install/share/bxi_example_py_elf3/mods -name mod.yaml -o -path '*/assets/*'若工作区此前使用过不同 install layout 或旧资产目录,请使用新的 build/install 路径,或只清理该包的旧构建缓存。