跳转到内容

使用 GenManip 简单生成数据

GenManip 的使用非常简单 —— 让我们快速上手,在一个预定义的场景中生成数据。 你只需要做两件事:

  1. 了解 GenManip 的场景文件结构
  2. 了解 GenManip 使用的 Config 配置

快速开始 部分,我们通过 Miniconda 安装了 Isaac Sim,这样我们就可以直接用 python 命令运行依赖 Isaac Sim 库的程序。 另一种常用方法是使用 Isaac Sim 的二进制安装包。 你可以在这里找到并下载 4.1.0 版本。使用二进制包可以直接启动带有 GUI 的 Isaac Sim 应用程序,这在编辑场景时非常有用。

当然,如果你的目标只是用已有配置生成数据,只需要确保 assetsConfig 已准备好,然后运行:

Terminal window
python demogen.py -cfg configs/tasks/xxx.yml
python render.py -cfg configs/tasks/xxx.yml

一个典型的工作流程如下:

  • 本地使用 GUI 编辑场景,或验证任务是否可行
  • 使用 rsync 将本地配置文件和资产同步到远程服务器
  • 在服务器上运行大规模数据生成任务

下载 Isaac Sim 包后,运行 isaac-sim.selector.sh 并选择默认选项启动 Isaac Sim。 如果你已经下载了一些 GenManip 的资产,进入 GenManip-Sim/saved/assets/scene_usds/debug_scenes/banana_plate_scenes/,双击 base.usda 查看场景。 点击左侧的 Play 按钮开始仿真。你可以通过 Shift + 左键单击 对物体施加力。 ⚠️ 退出时请不要保存

GenManip 的 Minimal Config 在一个名为 Banana Plate Scene 的简单场景中运行。该场景包括一张桌子、一根香蕉、一个盘子和一台 Franka 机械臂,任务是将香蕉放入盘子中。 打开 .usd(注意不是 .usda)文件可以查看场景的基本结构:

查看右侧的层级结构,你会注意到一个两层结构。最外层是一个 场景 UUID,它的命名可以是任意的。 在该 UUID 下包括多个对象:桌子、香蕉、盘子和 Franka 机械臂。 除了机械臂之外的所有对象命名格式均为 obj_<uid>obj_ 前缀表示这些对象会被加入 GenManip 的 Object List,并可在 Config 中引用。

如果你使用自己的项目生成了一个场景,且希望用 GenManip 生成数据,请确保将场景重构为这种结构。 如果你是手动搭建场景(我们会在 生成自定义数据 / Benchmark 章节中详细介绍),请务必按照命名规则重命名对象

GenManip 的 Config 还支持(高级用户常用的方式)基于文件夹或文件名将对象添加到一个空的 .usd 文件中,并根据 Scene Graph 或随机化规则进行布局。这些功能会在 高级数据生成 章节中详细介绍。

下面是 GenManip 的 Minimal Config 示例。它看起来有点长,但不用担心 —— 几分钟就能完全搞懂:

demonstration_configs:
- domain_randomization:
cameras:
config_path: configs/cameras/fixed_camera.yml
type: fixed
random_environment:
has_wall: false
hdr: false
robot_base_position: false
robot_eepose: false
table_texture: false
table_type: false
wall_texture: false
rewrite_instruction: false
generation_config:
action_path:
mode: auto
robot: 0
articulation: []
goal:
- - obj1_uid:
- '0'
obj2_uid:
- '1'
position:
- top
fixed_position: true
allow_fixed_grasp: true
force_fixed_grasp: true
mode: manual
planner: curobo
instruction: put the banana on the top of the vintage rusty frying pan.
layout_config:
ignored_objects: []
type: None
mode: manual
num_episode: 10
object_config:
'0':
type: existed_object
uid_list:
- fb1b6fc41f7e49adbf467e5e5988d190
'1':
type: existed_object
uid_list:
- 1fdc84a7be2c4348b281490c89d76062
preprocess_config:
- config:
config: default
type: convexDecomposition
type: collider
- type: ccd
robots:
- config:
gripper_type: panda_hand
type: franka
table_uid: aa49db8a801d402dac6cf1579536502c
task_name: Banana/banana_plate_4035_none-wow-wot-woh-now
usd_name: scene_usds/debug_scenes/banana_plate_scenes/base
evaluation_configs:
- domain_randomization:
cameras:
config_path: configs/cameras/fixed_camera.yml
type: fixed
random_environment:
has_wall: false
hdr: false
robot_base_position: false
robot_eepose: false
table_texture: false
table_type: false
wall_texture: false
rewrite_instruction: false
generation_config:
action_path:
mode: auto
robot: 0
articulation: []
goal:
- - obj1_uid:
- '0'
obj2_uid:
- '1'
position:
- top
fixed_position: true
allow_fixed_grasp: true
force_fixed_grasp: true
mode: manual
planner: curobo
instruction: put the banana on the top of the vintage rusty frying pan.
layout_config:
ignored_objects: []
type: None
mode: manual
num_test: 10
object_config:
'0':
type: existed_object
uid_list:
- fb1b6fc41f7e49adbf467e5e5988d190
'1':
type: existed_object
uid_list:
- 1fdc84a7be2c4348b281490c89d76062
preprocess_config:
- config:
config: default
type: convexDecomposition
type: collider
robots:
- config:
gripper_type: panda_hand
type: franka
table_uid: aa49db8a801d402dac6cf1579536502c
task_name: Banana/banana_plate_4035_none-wow-wot-woh-now
usd_name: scene_usds/debug_scenes/banana_plate_scenes/base

由于 YAML 语法有时不太直观,你也可以将其转换为 JSON 格式来理解。GenManip 同时支持 JSON 作为配置文件格式。

这里我们看到两个主要部分:demonstration_configsevaluation_configs。 它们各自包含一个字典,除了 num_episodenum_test 字段不同(分别控制生成数据的数量和测试集的数量)外,其余几乎完全一致。

GenManip 支持在同一个程序中顺序运行多个数据生成或评估任务。这也是它们被组织为列表的原因。从功能上看,它等价于多次运行不同的 Config,但更为方便。

我们先聚焦 demonstration_configs 中的单个字典,来理解其结构。它包含 domain_randomizationgeneration_configlayout_configobject_config 等部分,下面我们逐一解释。

Domain Randomization 部分用于随机化相机、环境、机械臂、桌子、墙面等元素。 大多数条目在最小配置中都是 false(禁用)。我们会在 高级数据生成 章节中详细讲解这些选项。

其中最重要的是相机配置,它通过相对路径引用一个单独的配置文件。

Generation Config 定义了任务生成的各种参数。

其中最核心的是 Goal,它通过 Scene Graph 定义目标布局,当前主要用于描述 Pick-and-Place 任务。 goal 是一个嵌套列表:

  • 外层列表表示逻辑 OR
  • 内层列表表示逻辑 AND

例如:

  • [[{banana → left of plate}], [{banana → right of plate}]] 表示香蕉可以放在盘子的左边 右边
  • [[{banana → left of plate}, {cup → right of plate}]] 表示香蕉必须在左边并且杯子必须在右边

每个目标项包含 obj1_uidobj2_uidposition,表示 obj1 应相对于 obj2 放在指定位置。

抓取姿态通常由 AnyGrasp 服务器 提供(详见 安装 AnyGrasp)。 但如果启用了 allow_fixed_graspforce_fixed_grasp,GenManip 会直接从物体的网格和位置计算一个俯视抓取姿态。 同样,fixed_position 会将目标位置约束为 obj2 的中心。

最简形式只需要提供 obj1_uidobj2_uidposition,GenManip 会向 AnyGrasp 请求一个随机抓取姿态,并将物体放置在符合目标要求的随机位置。

  • Action Path:通常设为 autorobot: 0。GenManip 会自动根据目标推断动作序列。
  • articulationmodeplanner:建议保持默认。虽然之前支持 mplib,但 curobo 性能更佳,目前已作为默认选项。

此部分定义与布局相关的配置。 在最小配置中,它被设置为 None,表示保留场景文件中的布局,不进行随机化。 更高级的布局选项将在后续介绍。

Object Config 部分将 元对象 映射到实际场景对象。

在上述示例中,有两个对象(01),类型均为 existed_object。 它们对应的路径为:

  • /scene_uid/obj_fb1b6fc41f7e49adbf467e5e5988d190
  • /scene_uid/obj_1fdc84a7be2c4348b281490c89d76062

这些 ID 与 Goal 部分中引用的对象相对应。

这种设计让数据生成的 scaling up(规模扩展) 变得非常容易。 例如,将配置改为:

"0":
filter_rule: []
max_cached_num: 50
option: []
path: object_usds/objects
type: load_object_from_path
"1":
filter_rule: []
max_cached_num: 50
option: []
path: object_usds/containers
type: load_object_from_path

即可从两个文件夹中各加载 50 个对象和 50 个容器。 在每次数据生成时,系统会随机激活一对物体,执行“将物体放入容器”的任务,其他部分的配置保持不变。

详细内容会在 高级数据生成 章节中介绍。

其他常见字段包括:

  • instruction:任务描述
  • num_episode:数据集大小
  • preprocess_config:预处理步骤,默认通常为 None。若手动构建场景,可以借助它自动配置物理属性(见 生成自定义数据 / Benchmark
  • robots:机械臂配置,默认是带 Panda hand 夹爪的 Franka
  • usd_name:场景文件相对于 saved/assets 的路径
  • table_uid:场景中桌子的 UID。GenManip 当前版本主要聚焦于桌面操作,但也支持多桌面或无桌面场景(详见 高级数据生成

生成的数据将保存于:

  • Planning 阶段数据:saved/demonstrations/<task_name>/trajectory
  • Rendering 阶段数据:saved/demonstrations/<task_name>/render

理解了 GenManip 的 Config 结构后,剩下的就非常简单了。 对于基于手动搭建场景的数据生成任务,只需对最小配置进行如下修改即可:

  1. 手动编辑场景,确保对象名称符合 GenManip 的命名规范。

  2. 修改以下配置字段:

    • task_name:任务名称
    • usd_name:场景文件相对路径
    • table_uid:桌子 UID
    • instruction:任务描述
  3. 设置 num_episode 为所需的数据量。

  4. 更新 object_config 以匹配场景中的对象。01 对应任务涉及的两个物体。

    • 你还可以在 Goal 列表中添加更多目标,以创建长时间序列任务或具有多个成功条件的任务(详见 高级数据生成)。
  5. 运行以下命令生成数据:

    Terminal window
    python demogen.py -cfg configs/tasks/xxx.yml
    python render.py -cfg configs/tasks/xxx.yml

在下一章节,我们将提供更详细的说明,并附带一个演示视频,展示如何在 5 分钟内生成一个数据集或测试集