-
Notifications
You must be signed in to change notification settings - Fork 12
Mod Public API
Mod 的状态、Resource 和 Transition 集成代码应依赖
bxi_example_py_elf3.framework.mod_api;策略实现还可以依赖公开的
bxi_example_py_elf3.framework.inference。framework.runtime 是控制器内部实现,不保证跨版本兼容。
当前 API 版本为 3.0.0。Mod 清单应声明 api: ">=3,<4"。3.0 直接使用状态
self.logger,已删除 ctx.get_logger();旧 Mod 必须迁移,框架不保留双轨日志入口。
from bxi_example_py_elf3.framework.mod_api import (
ModDefinition,
ModLoadContext,
JointCommandComposer,
JointCommandLayer,
JointTargetBuffer,
MotorFrame,
PoseState,
ProceduralState,
PolicyState,
ResourceHandle,
ResourceKey,
RobotControlState,
)| 模块 | 用途 |
|---|---|
mod_api.state |
StateBehavior、RobotControlState
|
mod_api.states |
Pose、Procedural、Policy、MotionReplay 等渐进式基类 |
mod_api.frame |
MotorFrame 和电机帧数组类型 |
mod_api.composition |
任意具名关节命令来源的合成和所有权检查 |
mod_api.resource |
Resource key、handle 和加载上下文 |
mod_api.mod |
Mod 定义、加载上下文和状态构建参数 |
mod_api.transition |
状态帧能力、Transition 配置和插件接口 |
mod_api.context |
状态与 Transition 使用的控制器 Protocol |
mod_api.geometry |
四元数和重力方向等通用计算 |
公开生命周期使用 RobotControlContext,不再依赖具体的 BxiExample 类。当前由 RobotControlFramework 实现这份能力契约;状态只面向契约编程,因此 ROS/硬件适配层可以改变而不迫使客户 Mod 跟着修改。
| 能力 | 主要成员 |
|---|---|
| 本周期观测 |
robot_joints、current_quat_xyzw/wxyz、current_omega
|
| 速度命令 |
current_raw_cmd_vel、current_cmd_vel、speed_profiles
|
| 机器人结构 |
robot_layout,由首个完整状态快照建立 |
| 最近完整输出 | last_motor_frame |
| 输出与切换 |
set_motor_target()、resolve_motor_frame()、request_state()
|
| 模型与安全 |
preheat_model()、is_orientation_unsafe()
|
| 运行信息 | 生命周期参数 dt,以及上下文中的 loop_count
|
| 日志 | 状态自身的 self.logger
|
| ROS 高级出口 | ctx.ros_node |
关节状态统一从 ctx.robot_joints.position/velocity 读取;推理策略使用
ctx.inference_frame,由策略契约自动选取关节。on_bind() 发生在首个机器人状态之前,
不要在其中读取 robot_layout。普通可切换状态应在 on_prepare() 创建依赖布局的映射和
缓冲,这样名称校验与内存申请不会落入控制周期热路径;没有 prepare 阶段的组件才在首次
on_enter()、on_update() 或 Transition 启动时惰性创建并缓存。
目标姿态和 kp/kd 属于状态输出语义,不属于控制上下文。每个状态按自己的自然
MotorFrame.layout 输出 29、31 或任意 N 个关节;Framework 在 set_motor_target() 中按名称
解析成完整 Robot Layout。需要最近完整命令时读取 ctx.last_motor_frame。
RobotControlState.is_available(ctx) 是进入前的非阻塞健康检查,默认返回 True。状态机只有
在目标可用时才准备 Transition。request_state() 返回请求是否被接受:True 表示已开始或
已排队,不表示 Transition 已完成;False 表示目标当前不可用或目标 Mod 节点启动失败,
且未开始切换。
request_state(..., force=True) 可在明确的维护/诊断场景绕过 is_available(),默认关闭。
它不绕过状态名、Transition、节点启动和状态生命周期错误,不应作为普通切换的默认选项。
一个状态的关节命令来自多个生产者时,使用 JointCommandComposer。生产者可以是模型、
话题快照、IK、轨迹或任何状态逻辑;Composer 只读取其长期复用的 JointTargetView,不参与
生产者生命周期。输出覆盖关系、完整性和名称映射在构造时编译,详见
多来源关节命令合成。
自定义 Transition 若要混合不同布局,必须先为两端分别创建
MotorFrame.empty(ctx.robot_layout),再调用 ctx.resolve_motor_frame(source, output);不能
直接对两个自然帧的数组做插值。
需要创建自定义 ROS subscription、service 或 timer 时,使用高级出口:
def on_bind(self, ctx):
node = ctx.ros_node
self.subscription = node.create_subscription(...)状态日志不能从 ros_node 取主节点 logger,统一使用:
def on_enter(self, ctx):
self.logger.info("动作已启动")框架在 on_bind() 之前注入 logger,名称自动包含 Mod ID 和 State ID。完整
命名、等级配置和子进程输出规则见日志系统。
在 on_unbind() 中销毁自己创建的 ROS 实体。
这是显式的平台扩展点:使用它的 Mod 会依赖 ROS,而只使用观测、事件、Resource 和 MotorFrame 的 Mod 不会与 BxiExample 或具体硬件绑定。
from bxi_example_py_elf3.framework.mod_api.transition import (
EntryFrameProvider,
RunningFrameProvider,
)EntryFrameProvider 提供目标状态的稳定进入帧,供 first_frame_switch 一类过渡使用;RunningFrameProvider 允许过渡采样两端的实时电机帧,供双状态混合使用。普通状态不需要主动实现无关能力。
旧版 bxi_example_py_elf3.utils.* 扩展入口已经移除。Mod 必须从 bxi_example_py_elf3.framework.mod_api 导入公共类型;这样使用了框架内部实现的代码会立即失败,而不会形成难以维护的隐式依赖。
mod_api 导入本身不会创建 ROS 节点、加载 ONNX Runtime 或扫描 Mod,因此可以单独用于 IDE 补全、静态检查和离线单元测试。
资源注册支持代码侧加载策略:
context.register_resource(POLICY, load_policy, loading="eager")
context.register_resource(CLIP, load_clip, loading="lazy")eager 在所有 Mod 注册完成后、控制循环启动前创建资源;lazy 在首次
ResourceHandle.get() 时创建。默认值是 lazy,未知值会在 Mod 加载时直接
报错。策略属于资源工厂的运行语义,因此不写入 mod.yaml。