Skip to content

Debugging

konodoki edited this page Jul 25, 2026 · 26 revisions

调试、验证与常见问题

先定位故障层,再查看具体章节。 不要同时修改输入 YAML、Mod route、Transition 和状态代码。

快速定位

现象 首先检查
节点启动时 Mod 加载失败 Mod 清单、factory、依赖和参数
按键没有消息 sources -> controls -> outputs
/motion_commands 但不切状态 Mod events 和当前状态的 route
状态已切换但没有正确输出 on_enter/on_update 和 MotorFrame
切换过程跳变或报 capability 错误 Transition 与 Entry/RunningFrameProvider
修改后没有生效 是否重新构建并重启了对应节点
模型文件报错 Resource asset 路径、loader 和预热阶段

构建

colcon build --packages-select remote_controller bxi_example_py_elf3 \
  --symlink-install --merge-install
source install/setup.bash

若提示 install layout 不一致,使用匹配的 --merge-install,或换一组全新的 build/install/log 目录。旧构建缓存仍引用已删除模型目录时,只清理对应包缓存。

查看输入和状态

ros2 topic echo /motion_commands
ros2 topic echo /simulation/state_machine_info

硬件前缀时将 simulation/ 换成 hardware/。状态信息 JSON 包含 current、pending、active transition、事件和图快照。

Mod 没有被发现

  • mod.yaml 是否位于内置 mods/mod_paths 子树。
  • 安装后的 share/bxi_example_py_elf3/mods/ 是否包含文件。
  • schema/api 若显式填写是否为 1,id 和版本是否合法。
  • 是否出现重复 id。
  • 日志是否打印 Mod <id>@<version>: <root>

Mod 加载失败

  • needs factory: module:Class:无 entrypoint/plugin.py 的状态漏写约定 factory。
  • factory ... must name a RobotControlState class:模块、类名或继承关系错误。
  • entrypoint module does not exist:entrypoint 与文件名不一致。
  • entrypoint is not callable:冒号后的工厂不存在。
  • state manifest/factory mismatchstatesstate_factories 键不同。
  • requires missing/version:依赖缺失或版本不匹配。
  • dependency cycle:Mod 依赖形成环。
  • unknown params:清单参数未被 StateBuildContext 消费。
  • missing required param / must be ...:dataclass 参数缺失或 YAML 类型错误。

模型找不到或没有加载

  • 资产必须在当前 Mod 的 assets/
  • context.asset() 路径应写 assets/file.onnx
  • 模型是惰性资源;仅加载 Mod 不会打开文件,首次 ResourceHandle.get() 才加载。
  • on_prepare() 预热,不要在插件 import 时创建推理 Session。
  • 替换模型后需要重启控制节点;启动失败时查看具体资源加载异常。

按键有输出但状态不切换

  1. /motion_commands 的槽位和值是否与 mod.yaml events 一致。
  2. 当前完整状态名是否存在对应 route。
  3. 跨 Mod名称是否含 / 且依赖存在。
  4. 是否正在等待 delay 或处于活动过渡。
  5. 同一状态是否存在可同时触发的输入;加载器会提前拒绝。

priority 与 index

正常状态只写 manifest.priority。数值越大越靠前,相同 priority 按完整状态名升序排列,框架会自动生成 index。

ValueError: duplicate explicit state manifest index N: 'state-a' and 'state-b'

只有确实需要固定绝对位置时才显式写 manifest.index。两个显式 index 重复会直接终止启动;负数、布尔值和字符串同样是配置错误。

过渡错误

Transition 负责状态切换期间的电机帧,用来避免源、目标状态的 qpos/kp/kd 不连续时直接产生突跳。因此这类错误要同时检查 route 选用的过渡以及两端状态提供的帧能力。

  • must implement EntryFrameProvider:目标没有进入帧。
  • must implement RunningFrameProvider:动态采样侧没有运行帧能力。
  • unknown transition type:业务过渡模块未被 Mod entrypoint 导入。
  • unknown fieldsConfigReader.finish() 发现字段拼写错误。
  • 发生突跳:检查进入帧与 on_enter() 后第一帧是否一致。

修改后没有生效

  • Mod、系统 YAML、模型资产和遥控器 YAML 都只在对应节点启动时读取。
  • 修改源码后先重新构建工作区,再重启控制节点或 remote_controller
  • 使用 --symlink-install 时 Python 源码可能直接生效,但仍然必须重启进程。
  • 启动失败不会进入控制循环;根据首个加载异常修正清单、依赖、模块或资源路径。

发布树失败

python3 tools/sanitize_release.py --out /tmp/public_release --self-check

若报告公开 Mod 依赖 protected Mod,检查显式 requires 和跨 Mod route。共享资源应移到 public 资源 Mod。

离线加载检查

模型是惰性的,因此可以只验证 Mod 和状态图:

from pathlib import Path
import yaml
from bxi_example_py_elf3.utils.mod_system import load_mod_runtime

package = Path("src/bxi_example_py_elf3")
base = yaml.safe_load((package / "config/elf3_state_machine.yaml").read_text())
runtime = load_mod_runtime(base, built_in_root=package / "mods")
print([mod.id for mod in runtime.mods])
print(sorted(runtime.state_factories))
runtime.close()

当前默认树应发现 5 个 Mod 和 15 个状态。

Clone this wiki locally