-
Notifications
You must be signed in to change notification settings - Fork 12
Architecture
当前架构把平台适配、控制框架、动作实现和模型资产分层。BxiExample 只处理 ROS 和硬件边界;RobotControlFramework 拥有 Mod、状态、Transition、Context 和状态机。状态侧的部署单元是 Mod,不再依赖中央状态类文件。
当前 bxi_example_demo.py 是 ELF3 的一个平台适配实现,不是框架本体。需要接入其他
机器人消息、SDK 或硬件总线时,请按机器人平台适配指南
实现新的 ControlPlatformAdapter,不要把硬件差异写进状态机或策略公共运行时。
手柄 / 键盘 / CRSF / 自定义设备
-> InputDeviceManager
-> InputDriver
-> sources -> controls -> outputs
-> communication/msg/MotionCommands
-> BxiExample 的 ROS subscription
-> BxiExample 采集 RobotObservation 并排队 raw events
-> RobotControlRuntime 的独立控制线程
-> BxiExample.snapshot_control_inputs()
-> RobotControlFramework 内的 RemoteEventAdapter / RobotStateMachine
-> Transition / RobotControlState
-> MotorFrame
-> BxiExample.publish_motor_frame()
-> BxiExample 将 MotorFrame 转换为 ActuatorCmds
-> 机器人硬件
这条边界的核心约定很简单:平台每周期给框架一份完整观测和事件,框架返回最终电机帧。框架不创建硬件消息,不发布电机话题,也不负责机器人 reset。因此更换消息类型、总线或硬件平台时,状态图和 Mod 不需要跟着改。
当 route 要求切换状态时,RobotStateMachine 会在源状态和目标状态之间执行 Transition。它负责切换期间的电机帧,避免两边 qpos/kp/kd 不连续时直接换帧产生突跳;完成后目标 RobotControlState 才接管正常更新。
配置和代码的加载流:
elf3_state_machine.yaml(系统配置)
+ 内置 mods/
+ mod_paths 中的客户 Mod
-> 发现 mod.yaml
-> 校验依赖并排序
-> 加载 entrypoint
-> 注册 eager/lazy 资源、状态工厂和 Python 节点
-> 合成 states/events/routes/actions/nodes/profiles
-> 构建 RobotStateMachine
-> 按 Mod/State 生命周期管理节点
src/remote_controller/
config/xbox_default.yaml
include/remote_controller/
src/
src/bxi_example_py_elf3/
config/elf3_state_machine.yaml # 系统级配置
mods/
com.bxi.basic_actions/
mod.yaml # 状态图贡献
plugin.py # 工厂和资源注册
*_state.py # 状态实现
assets/ # 该 Mod 私有资产
com.bxi.back_flip/
com.bxi.forward_flip/
com.bxi.ballet/
bxi_example_py_elf3/
bxi_example_demo.py # ROS/硬件适配层
mod_api/ # 面向 Mod 作者的稳定公共 API
context.py
frame.py
state.py
states.py
resource.py
mod.py
transition.py
geometry.py
_runtime/
control_runtime.py # 平台接口、调度和运行时生命周期
controller.py # Mod、状态机和每周期控制计算
... # 加载、合成、状态机和注册表
inference/ # 后端无关的策略、模型运行时与性能工具
transitions/ # 内置过渡类型
| 对象 | 责任 |
|---|---|
RobotControlRuntime |
持有控制调度器、Framework、维护线程和平台适配边界 |
RobotControlFramework |
接收 RobotObservation/events,推进状态机并返回 MotorFrame
|
ModRuntime |
保存合成配置、状态工厂、资源管理器、已加载 Mod 和动态模块 |
ResourceManager |
注册、按 eager/lazy 策略创建、缓存和关闭资源 |
StateBuildContext |
为状态工厂提供名称、稳定 state id 和强类型参数读取 |
RobotStateMachine |
处理事件、延迟、过渡、状态生命周期和图导出 |
RemoteEventAdapter |
把 MotionCommands 槽位变化转成 Mod 事件 |
Mod 只能依赖 mod_api;BxiExample 通过一个 RobotControlRuntime 使用 _runtime,
不再自己组装调度器、loader、状态和状态机。项目不再提供旧 utils 扩展入口,错误的
依赖会在开发阶段直接暴露。
Mod 清单中的本地名称会自动限定:
Mod id: com.example.wave
state: wave
event: activate
resource: com.example.wave/policy
运行时状态: com.example.wave/wave
运行时事件: com.example.wave/activate
同一 Mod 内的 from: wave、to: wave 和 event: activate 会自动限定。跨 Mod 引用必须写完整名称,并通过 requires 声明依赖。
新增动作:
- 新建或扩展一个 Mod。
- 在
mod.yaml声明状态、事件、路由和 action。 - 简单状态用
factory: module:Class;需要资源和扩展注册时再由plugin.py返回工厂。 - 模型放进该 Mod 的
assets/并注册资源。 - 在遥控器 YAML 中输出清单所使用的
btn_N=value。
新增过渡:
- 框架通用过渡放入包内
transitions/。 - 业务专用过渡放在对应 Mod 中,并由
ModDefinition.transition_plugins显式注册。 - profile 可放系统 YAML;Mod 私有 profile 放
mod.yaml,会自动加命名空间。
新增输入协议:
- 先判断是否仅靠遥控器 YAML 能完成。
- 必须读新设备时再实现
InputDriverBase和工厂。 - Driver 只产生 raw signal,不直接写状态名。
公开发布:
- 在要整体移除的 Mod 清单中设置
visibility: protected。 -
tools/sanitize_release.py删除整个目录并验证保留 Mod 的依赖闭包。