Skip to content

Framework Internals

konodoki edited this page Jul 25, 2026 · 19 revisions

框架底层运行原理

本页按启动和每帧执行顺序描述当前实现。

1. remote_controller

读取 YAML
  -> 校验 sources/controls/outputs
  -> 注册并创建候选 InputDriver
  -> InputDeviceManager 周期探测
  -> 选择唯一活动设备
  -> InputMapper 计算 controls
  -> MotionCommandsAdapter 写消息
  -> 发布 motion_commands

设备选择考虑 priorityready_timeout_msloss_timeout_mscooldown_ms 以及全局扫描/稳定时间。Driver 只生产 raw signal,业务组合留在 YAML。

edge 只在条件由 false 变 true 时触发;level 持续反映条件;analog 每帧写连续值。

2. BxiExample 启动

load_files()
  -> 读取系统状态机 YAML
load_mod_runtime()
  -> 发现和排序 Mod
  -> 准备 python_exports
  -> 加载 entrypoint 或各状态的约定 factory
  -> 注册资源和状态工厂
  -> 合成并校验运行配置
build_robot_states()
  -> 分配稳定 state id
  -> 调用工厂并校验 params
  -> 写入 speed profile 和 manifest
bind_robot_states()
RobotStateMachine(...)
RemoteEventAdapter(...)

3. Mod 动态模块

每个清单先校验 schema、id、版本和 API。依赖拓扑排序后,入口模块或 factory: module:Class 引用以由 Mod id 确定的私有包名导入,使相对 import 可用并隔离不同 Mod 的模块命名空间。

加载失败会关闭新资源、移除动态模块、恢复过渡插件快照,并撤销 Python exports 和对应的 sys.path 修改。

4. 配置合成

系统 YAML 先复制为 base config,mod_paths 不进入最终状态机配置。随后按依赖顺序合成:

  • states
  • remote_events
  • speed_profiles
  • Mod transition_profiles
  • routes 生成的 states.*.transitions.on_event

所有本地名称在这一阶段限定为 mod-id/local-name。输入冲突、未使用事件、未知目标、index、profile 和 initial state 都在返回运行时前校验。

5. 状态构建

构建器不再扫描类。它遍历合成状态:

  1. 使用显式 id,或对完整名称计算 CRC32 int31。
  2. 创建 StateBuildContext
  3. 调用显式 Mod factory,或由类的 dataclass Params 生成约定 factory。
  4. 拒绝未知参数。
  5. 设置 speed profile 和 manifest。

6. ResourceManager

注册时只保存 key、owner、Mod 根和 factory。ResourceHandle.get() 第一次调用才构造实例,并记录 context.asset() 使用的路径。关闭运行时会逆序调用实例的 close()

7. 每个控制周期

复制最新传感器和 raw cmd velocity
RemoteEventAdapter 处理槽位变化
state_machine.update(dt, events)
  -> 活动过渡可中断事件
  -> pending delay
  -> 当前状态 event route
  -> transition session 或 current.on_update()
发布 ActuatorCmds
按频率发布 state_machine_info

8. 状态切换

Transition 是状态机在源状态和目标状态之间创建的一次切换 Session。它在目标状态正式进入前暂时负责每周期的电机输出,用来处理两边 qpos/kp/kd 不连续时的保持、增益渐变或帧混合;instant Session 则立即完成。

plan.validate_states(source, target)
target.on_prepare(ctx, source)
session = plan.create_session(...)

每帧:session.update(ctx, dt)

完成:
source.on_exit(ctx)
current = target
target.on_enter(ctx)

活动过渡被中断或 Session 抛错时调用目标 on_prepare_cancel(),当前状态仍是源状态。

9. action

route 只有 action 时不切状态。状态机先查全局 handler,再调用当前状态的 on_action(ctx, name);都未处理会报错。

10. 图验证和状态信息

状态机验证未知目标、未声明事件、过渡能力、不可达状态和无出边状态。DOT/Mermaid 导出来自同一合成配置。

状态信息话题包含当前状态、pending/active transition、本周期事件以及 states、profiles 和 remote events 快照。

11. 固定运行时

Mod、资源、动态模块和状态图只在节点启动时构建。启动失败会清理已经创建的资源、模块和注册项;启动成功后运行时保持不变。修改系统 YAML、Mod 或资产后必须重启节点,控制循环不扫描文件,也不动态替换状态机。

12. 扩展边界

  • 新动作:Mod 状态 + 工厂 + 清单。
  • 新模型:Mod 资源工厂。
  • 新业务过渡:Mod 内 TransitionPlugin 子类并由 entrypoint 导入。
  • 新通用过渡:核心 transitions/
  • 新设备:InputDriverBase 工厂。
  • 新消息适配:MotionCommandsAdapter

Clone this wiki locally