Skip to content

Work: 评估面向场景和任务 API 的 entity abstraction #586

Description

@TATP-233

Work type

feature / research

Area

other

Problem

我们是否计划给 UniLab 增加 entity abstraction?

目前 UniLab 的访问方式仍然偏 data-oriented:任务、reset 和 domain randomization 代码会直接处理 backend 级别的数组、qpos/qvel 切片、body ID、joint ID,以及 backend 解析出来的名称。这在当前 contract 下是可工作的,但当场景和任务变复杂时,任务代码会越来越多地关心“机器人、物体、地形、接触 body、某组关节”这些实体语义之外的索引和布局细节。

外部参考设计:

  • Isaac Lab 使用 AssetBase 加 typed assets 的方式,例如 ArticulationRigidObjectRigidObjectCollectionDeformableObject。这些 asset 暴露 datareset()write_data_to_sim()update()、实体局部的 find_joints() / find_bodies(),以及 root/joint 写入 API。InteractiveScene 按类型组织实体,并支持 scene["robot"]scene.articulations["robot"] 这样的命名访问。SceneEntityCfg 会把 manager term 中的 name/regex selector 在初始化阶段解析成 ID。
  • mjlab 使用单一 Entity 抽象,而不是拆成 Isaac Lab 那样的 Articulation / RigidObject 多个类。它用 fixed/floating base 和 articulated/non-articulated 两个维度描述实体,通过 per-entity indexing 和 EntityData 暴露 root/joint/control 的读写,并通过 SceneCfg.entities 组织场景,运行时支持 env.scene["robot"] 这样的命名访问。

相关来源:

UniLab 当前仓库内证据:

  • SimBackend 当前暴露的是 backend-global model 访问,以及 name-to-ID 和 qpos/qvel 风格的 contract,例如 get_keyframe_qpos()get_body_ids()get_geom_id()get_joint_dof_indices() 等:src/unilab/base/backend/base.py
  • locomotion reset provider 会直接构造完整 qpos / qvel 数组,并写入 root 相关切片,例如 qpos[:, 0:2]qpos[:, 3:7]qvel[:, 0:6]src/unilab/envs/locomotion/common/dr_provider.py
  • manipulation env 会在 env 层缓存 object/body ID 和 object qpos slice,例如 _obj_pos_slice_obj_quat_slice_object_body_ids_fingertip_body_idssrc/unilab/envs/manipulation/sharpa_inhand/base.py
  • manipulation reset 代码会手动填充 hand/object 的 qpos slice,再返回 ResetPlansrc/unilab/envs/manipulation/sharpa_inhand/rotation.py

需要明确的问题是:UniLab 是否应该引入一层一等 entity abstraction;如果要引入,这一层的 owner boundary 应该放在哪里,才能避免 backend-specific 细节泄漏到 env/task 代码里。

Deliverable

  • 一份短设计 proposal 或 ADR,明确 UniLab 是否要增加 entity abstraction。
  • 如果接受该方向,给出最小、contract-compatible 的 API sketch,例如面向 robot/object/terrain 的命名 scene/entity handle,以及 body/joint/geom/site subset 的冷路径 selector 解析。
  • 明确 owner boundary:该层应属于 backend、env adapter、scene composition,还是新的 base abstraction。
  • 给出一个代表性 locomotion task 和一个代表性 manipulation task 的迁移计划。

Definition of done

  • 决策文档中显式对比 Isaac Lab 和 mjlab 的设计。
  • 新抽象不能绕过 SimBackend;env 层只能使用 backend contract 中声明的方法。
  • name/regex selector 解析只发生在 init/materialization/cache 等冷路径,不进入 step/reset 热路径。
  • 热路径不能解析 XML/asset,也不能在 env 层通过 getattr / hasattr 探测 backend 私有能力。
  • API sketch 至少覆盖 root state、joint state、body/site/geom selector、control 和 per-entity data view。
  • 保持 NpEnvState.obs 必须是 dict,以及现有 reset() 返回 (obs_dict, info_dict) 的 env contract。
  • 如果设计被接受,需要拆出后续实现 issue。

Dependencies and blockers

  • 需要和 backend capability boundary、task-owner/config contract 对齐:
    • ADR-0002 backend capability boundary
    • ADR-0003 task owner and config compose contract
  • 在暴露稳定 API 前,需要考虑 Motrix 和 MuJoCo 的能力对齐。

Proposed owner

Unassigned.

Validation plan

  • 设计实现后,在 entity/scene/backend boundary 附近补 focused unit tests。
  • 验证 name/regex selector 只在初始化阶段解析一次,并复用已解析 ID/view。
  • 如果 API 同时跨 MuJoCo 和 Motrix,需要至少为一个 MuJoCo-backed task 和一个 Motrix-backed task 增加 parity tests。
  • 实现阶段先跑相关 focused tests;任何改 runtime/backend/config contract 的 PR,在创建或更新 PR 前必须跑 make test-all

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions