-
Notifications
You must be signed in to change notification settings - Fork 12
Debugging
konodoki edited this page Jul 23, 2026
·
26 revisions
本页按症状排查遥控器、状态机、过渡、driver 和发布保护问题。
常用编译:
colcon build --packages-select remote_controller bxi_example_py_elf3加载环境:
source install/setup.bash如果只改 wiki,不需要编译。
如果正在调试热重载,不建议使用 --symlink-install。普通 build 会在代码修改完成后更新 install/ 目录并触发一次热重载;--symlink-install 可能因为编辑器自动保存而频繁触发热重载。
手柄:
ros2 launch remote_controller remote_controller.launch.py键盘:
ros2 launch remote_controller remote_controller_keyboard.launch.py观察:
ros2 topic echo /motion_commandspublish_on_change: true 时,只有 payload 变化才会发布。调试时可以临时改:
outputs:
publish_on_change: falseros2 topic echo /simulation/state_machine_info会看到:
- 当前状态名和 id。
- 是否正在 transition。
- transition 的 from / to / progress。
- pending transition。
- 本周期收到的 events。
- 当前速度命令。
- 状态图快照。
如果用了不同 topic_prefix,话题是:
<topic_prefix>state_machine_info
默认配置会导出:
/tmp/elf3_state_machine.dot
/tmp/elf3_state_machine.mmd
Mermaid 文件可以贴到支持 Mermaid 的 Markdown 查看器。
按顺序查:
-
sources.*.signals是否声明 source。 -
controls是否引用这个 source。 -
outputs.edge/outputs.level的when是否引用 control 名。 -
/motion_commands中对应btn_N是否变化。 -
elf3_state_machine.yaml的remote_events是否匹配slot/value。 - 当前状态的
transitions.on_event是否监听该 event。 -
/simulation/state_machine_info的events是否出现目标 event。
检查:
- 类是否继承
RobotControlState。 - 类是否直接写在
robot_states.py里,或者已被robot_states.py导入。 - YAML 里的
behavior是否和类名完全一致。
检查:
-
on_update()是否调用ctx.set_motor_target()。 -
timer_callback()中是否有motor_target。 - 状态是否处于 transition 中。活动过渡期间不调用当前状态
on_update();过渡输出由TransitionSession负责。 - 是否刚进入状态就被安全逻辑切到其他状态。
检查:
- transition profile 的
type是否正确。 -
entry_gain_ramp的目标状态是否实现EntryFrameProvider.get_entry_frame()。 -
kp_from/kd_from是否是预期的current、zero或target。 -
kp/kd数组 shape 是否和 dof 数一致。
检查:
- 按
sample_from/sample_to配置,相关状态是否实现RunningFrameProvider。 - 目标状态是否实现
EntryFrameProvider。 -
sample_running_frame()是否返回MotorFrame,且没有直接调用ctx.set_motor_target()。 -
advance_from/advance_to是否符合预期。 - 源侧返回
None时会保持开始前最后电机帧;目标侧返回None时会使用目标进入帧。
正常设计里,publish_on_change: true 只是减少重复发布,不应该导致机器人因为输入没变而停下。
排查:
-
BxiExample是否保持上一次收到的原始速度到raw_cmd_vel/current_raw_cmd_vel。 - 当前状态是否调用了
self.get_cmd_vel(ctx);基类会把处理后的速度写入current_cmd_vel。 - 当前状态是否配置了
speed_profile;没有 profile 时默认返回零速度。 - driver 的
is_available()是否错误返回 false,导致设备切换。 - 当前活动设备是否还在
ready_timeout_ms内等待is_ready()。 - 流式协议的字段
timeout_ms是否过小。
Linux joystick 默认不配置 timeout_ms;摇杆静止没有事件是正常的,不应被判定为断连。
如果 UDP/TCP 的某个字段被写成 failsafe,检查该字段是否确实需要独立过期保护:
字段可能独立停止更新
-> 可以配置 timeout_ms / failsafe
设备或协议整体断连
-> 由 driver is_available() + loss_timeout_ms 处理
CRSF 应按最近一次 CRC 正确完整帧判断 is_available(),而不是靠每通道 timeout_ms。
driver 不能永久阻塞在 read()。
检查:
- fd 是否非阻塞。
- 是否用
select()/poll()带超时等待。 - 循环里是否定期检查
stop_flag_。 -
stop()是否能关闭 fd 或打断阻塞。
检查:
outputs:
conflict_policy: first_wins可选值:
-
first_wins:先匹配的生效。 -
last_wins:后匹配的生效。 -
error:冲突时报错。
调试阶段可以用 error 尽早发现配置冲突。
检查:
-
release_protection.yaml的protected_states.<state>是否和状态名一致。 -
behavior是否包含所有需要删除的类。 - 要删除的模型文件是否都显式写在
files中。 -
model_keys是否和self.<model_key>一致。 -
files相对路径是否按 manifest 所在目录解析。
运行:
python3 tools/sanitize_release.py \
--manifest src/bxi_example_py_elf3/config/release_protection.yaml \
--out dist/public_release \
--self-check手动扫残留:
rg "BackFlipState|ForwardFlipState|back_flip|forward_flip" dist/public_release先确认热重载是否开启:
- 仿真
example_demo.launch.py默认"/hot_reload": True。 - 硬件
example_demo_hw.launch.py支持热重载,但默认"/hot_reload": False。 - 真机上临时开启前先在仿真验证,并确认机器人处于安全姿态。
检查改动位置:
- 换模型路径:改
bxi_example_demo.py的load_models()。 - 覆盖模型文件:确认
.onnx/.npz是当前load_models()正在引用的文件。 - 改状态类:改
robot_states.py。 - 改状态机结构:改
elf3_state_machine.yaml。 - 改遥控器映射:改
remote_controller/config/xbox_default.yaml。 - 改 launch 参数:需要重启 launch,不能靠热重载。
推荐触发方式:
- 不使用
--symlink-install。 - 修改
src/下代码或模型。 - 修改完成后执行对应 package 的
colcon build --packages-select ...。 - build 更新
install/目录后,运行中的 demo 节点或remote_controller会看到文件变化并触发热重载。
如果使用了 --symlink-install:
- 编辑器自动保存可能导致还没改完就触发热重载。
- 保存多次会触发多次重载。
- 真机上尤其不建议这样调试。
如果看到 actuator delay:
- 模型加载已放到后台线程,正常情况下控制循环只做最终替换。
-
robot_states.py和elf3_state_machine.yaml的结构热重载仍是同步提交,真机上不要在高风险动作中修改。 - 新模型很大时可能仍有 CPU/内存带宽竞争,先在仿真观察日志和控制周期。
更多说明看 热重载。
新增状态后:
1. colcon build 通过。
2. /motion_commands 能看到目标 btn_N/value。
3. /simulation/state_machine_info 的 events 出现目标 event。
4. current.name 切到新状态。
5. transition 信息符合预期。
6. 新状态 on_update 输出电机目标。
新增 driver 后:
1. driver factory 已在 InputDeviceManager 创建前注册。
2. 候选设备可用、启动、ready、断连和切换都有明确日志。
3. Ctrl+C 能退出。
4. 高优先级设备稳定后会抢占;切换前会发布一次零运动命令。
5. 设备断联会在 loss_timeout_ms 后安全回退。
6. 切换后 edge 命令必须释放再按,不会误触发。
7. /motion_commands 输出符合 YAML 配置。