Grasping Synthetic Data Generation#
This tutorial introduces the isaacsim.replicator.grasping
extension and its associated UI, isaacsim.replicator.grasping.ui
. These tools provide a comprehensive workflow for generating synthetic grasping datasets in Isaac Sim.
Learning Objectives#
After completing this tutorial, you will be able to:
Understand the core components and data flow of the Grasping SDG extension.
Navigate and utilize the Grasping SDG UI to configure and run grasp generation workflows.
Define gripper properties, joint states, and multi-step grasp phases.
Configure object properties and grasp pose sampling parameters.
Execute and interpret the results of physics-based grasp evaluations.
Manage grasping configurations using YAML files for saving, loading, and sharing setups.
The extensions are automatically loaded in Isaac Sim, and the UI window can be opened from the main menu via Tools > Replicator > Grasping.

Getting Started#
Before proceeding, it is recommended to familiarize yourself with:
Simulation Fundamentals: For understanding physics simulation concepts and gripper rigging (e.g., drive joints).
Grasp Editor: This tutorial covers related concepts and provides a foundation for grasp definition.
Note
The grasp sampler requires the libspatialindex
library. If you see related warnings please install it (e.g., on Ubuntu: sudo apt-get install libspatialindex-dev
).
This tutorial utilizes an example stage that includes a pre-configured gripper and objects suitable for grasping exercises. You can find this stage at:
https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.0
/Isaac/Samples/Replicator/Stage/sdg_grasping_xarm.usd
The stage asset can be found in the Content Browser under Isaac Sim > Samples > Replicator > Stage > sdg_grasping_xarm.usd, or can be loaded using by inserting the whole URL in the path field.
The example stage features a gripper with drive joints and three objects equipped with rigid body physics and colliders. Gravity is disabled for these objects to simplify initial interactions. The Grasping UI window typically docks in the Property panel upon opening.

Overview#
The extension is designed to automate the process of finding and evaluating potential grasp poses for a given gripper-object pair. At its core, the workflow revolves around several key components and stages:
Configuration: Defining the specific gripper, the target object, and the parameters that govern how grasps are found and tested.
Grasp Pose Sampling: Algorithms (e.g., antipodal samplers) generate a set of candidate grasp poses around the target object. These poses represent potential ways the gripper might hold the object.
Grasp Execution Phases: For each candidate grasp, a sequence of actions, termed “Grasp Phases” (e.g., move to pre-grasp, close fingers, lift), is simulated. This allows for defining complex, multi-step grasping behaviors analogous to real-world robot actions.
Physics-Based Evaluation: Each phase of the grasp is simulated in the physics engine. The success or failure of the grasp attempt, along with other metrics (like contact forces, object displacement), can be recorded. In its current state the extension saves the gripper state as result from which the grasps can be evaluated.
Data Logging and Management: Successful grasps and their associated parameters are logged. The entire setup can be saved to and loaded from configuration files (YAML format), ensuring reproducibility and facilitating batch processing.
The GraspingManager
class is the central Python API orchestrating these steps, while the UI provides an intuitive way to configure and run this pipeline.
UI Window Overview#
The Grasping UI window provides the interface for setting up and running the grasping simulations workflows. It is organized into several sections, each addressing a specific part of the process. The general workflow involves configuring these sections, typically starting with the gripper and object, then defining the evaluation workflow and simulation parameters, and finally managing the overall configuration.

Gripper Section#
This section is dedicated to defining the properties and behavior of the gripper, which is fundamental for any grasp attempt.

Path: Specify the USD path to the root prim of your gripper (e.g.,
/World/Robot/gripper_base
).Joints: Once a gripper is selected, its articulated joints are listed. Here you can:
Include/Exclude: Select which joints are actively controlled during the grasp phases. These joints have to be drive joints.
Set pre-grasp positions: Define the initial state for each joint, typically an open configuration, before the grasp sequence begins.
Toggle visibility between all joints or of type drive (non-mimic) joints.
Grasp Phases: This powerful feature allows you to define a sequence of discrete actions that constitute a complete grasp attempt. This is analogous to defining a state machine or a sequence of motion primitives for the gripper.
For each phase (e.g., “Open”, “Close”), you specify:
Target joint positions for the active gripper joints.
Simulation step delta time (
dt
) for the physics steps within this phase.Number of simulation steps to execute for this phase.
Phases can be reordered, deleted, or simulated individually for debugging. If pre-grasp joint positions adequately prepare the gripper (e.g., fully open), an explicit “Open” phase might be unnecessary.
Object Section#
This section focuses on specifying the target object and configuring how potential grasp poses are generated for it.

Path: The USD path to the target object prim (e.g.,
/World/MyObject
).Grasp Pose Sampler: This configures the algorithm used to find potential grasp poses. This tutorial primarily uses an antipodal grasp sampler (implemented in
sampler_utils.py
). An antipodal grasp is typically stable for parallel-jaw grippers, involving two contact points on opposite sides of the object. Key parameters include:Number of orientations per grasp axis: How many rotational variations around the primary grasp axis to sample.
Gripper standoff distance: The distance from the gripper’s Tool Center Point (TCP) or fingertips to the object surface during the approach phase, crucial for avoiding premature collision.
Maximum gripper aperture: The widest opening of the gripper jaws, filtering out grasps that are too wide for the object.
Alignment axes for the grasp: Defines local gripper axes to align with object features or the grasp line.
Gripper approach direction: The vector along which the gripper moves towards the object.
Lateral perturbation (sigma): Adds randomness to the grasp point location along the grasp axis, allowing for exploration around nominal contact points.
Random seed: For ensuring reproducible sampling results.
Grasp Poses: Manages the set of candidate grasp poses generated by the sampler.
Specify the desired number of candidate poses.
Clear previously generated poses.
Visualize the poses in the viewport (either in world or object-local frames) and cycle through them to inspect their placement.
The following image shows example grasp poses generated by the antipodal sampler on various objects:
Trimesh: Provides options for debug visualization of the object’s triangle mesh, which is used internally by the sampler for geometric calculations and collision checks.
Note
The Measure Tool can be useful for determining values like gripper aperture or standoff distance.

Workflow Section#
The Workflow section is where you orchestrate the actual grasp evaluation process using the configurations defined in the Gripper and Object sections.

The system first saves the gripper’s initial pose. Then, for each generated grasp pose selected for evaluation, it sequentially executes the defined grasp phases within the physics simulation. After all phases for a given pose are completed, the outcome (e.g., success based on object stability, contact with target) and other relevant metrics are recorded.
Number of Grasps Samples: Specify how many of the generated grasp poses should be evaluated. Use -1 to evaluate all available poses.
Output Path: Define the directory and base file name for saving the evaluation results. The results are typically saved in a structured format like YAML, detailing each evaluated grasp and its outcome.
Overwrite Results: If enabled, existing result files at the output path will be overwritten. Otherwise, new files will be created (e.g., with incremental numbering) to avoid data loss.
Start Workflow: Initiates the grasp evaluation process. The UI will often provide feedback on the progress.
Simulation Section#
This section allows you to fine-tune global parameters that affect how the physics simulation is run during the grasp evaluation.

Render each simulation step: Control whether the viewport updates after each individual physics step within a grasp phase. Disabling this can speed up the evaluation process significantly for large datasets, with rendering potentially only occurring after each full grasp attempt or phase.
Simulate using timeline: Choose between advancing the simulation by stepping the main Isaac Sim timeline or by directly stepping the physics scene. Direct physics steps can offer more precise control for rapid evaluations, while timeline-based simulation might be closer to how a full robot application would run.
Isolated physics scene: Optionally specify a path to a Physics Scene prim. If provided, the grasping simulation can be run within this dedicated physics scene, preventing interference from other dynamic objects or physics settings in the main stage. This is useful for ensuring consistent and repeatable grasp evaluations.
Config Section#
The Config section provides the crucial functionality for saving your entire grasping setup to a YAML file and loading it back later. This is essential for reproducibility, sharing configurations, and running batch experiments.

File Path: Specify the path to the YAML configuration file for saving or loading.
Config Includes: Selectively choose which components of the setup are included in the save/load operation. This allows for modular configurations. Options typically include:
Gripper Path
Joint Pregrasp States
Grasp Phases
Object Path
Sampler Parameters
Generated Grasp Poses (if you wish to save a specific set of poses)
Overwrite Existing File: When saving, this option determines if an existing file at the specified path should be overwritten.
Load/Save Buttons: Execute the respective file operations.
This structured UI and configuration system offers detailed control and flexibility for generating diverse grasping datasets.
Configuration File Example#
Below is a snippet illustrating the structure of a YAML configuration file. It can store settings for the gripper, object, sampler, and defined grasp phases. The specific content will depend on which components were selected for inclusion via the ‘Config Includes’ UI options.
grasp_phases:
- joint_drive_targets:
/World/Grippers/xarm_gripper/joints/drive_joint: 48.0
name: Close
simulation_step_dt: 0.016666666666666666
simulation_steps: 32
gripper_path: /World/Grippers/xarm_gripper
joint_pregrasp_states:
/World/Grippers/xarm_gripper/joints/drive_joint: 0.0
/World/Grippers/xarm_gripper/joints/left_finger_joint: 0.0
# ... (other joints related to the xarm_gripper)
object_path: /World/Objects/_05_tomato_soup_can
sampler_config:
grasp_align_axis: [0, 1, 0]
gripper_approach_direction: [0, 0, 1]
gripper_maximum_aperture: 0.08
gripper_standoff_fingertips: 0.17
lateral_sigma: 0.0
num_candidates: 5
num_orientations: 1
orientation_sample_axis: [0, 1, 0]
random_seed: -1
sampler_type: antipodal
verbose: false
Code Example#
The following scripts demonstrates a complete workflow for generating a grasping dataset using the GraspingManager
API. This script programmatically performs the steps configurable through the UI: opening a stage, setting up the GraspingManager
(potentially by loading a configuration file), generating grasp poses, evaluating these poses via physics simulation, and saving the results. This approach is highly suitable for batch processing or integration into larger robotics workflows. The script can be run directly from the Script Editor or as a Standalone Application.
To run the standalone example from the terminal (on Windows, use python.bat
instead of python.sh
):
./python.sh standalone_examples/api/isaacsim.replicator.grasping/grasping_workflow_sdg.py
Grasping Synthetic Data Generation Workflow
1import asyncio
2import os
3
4import omni.kit.app
5import omni.usd
6from isaacsim.core.utils.extensions import get_extension_path_from_name
7from isaacsim.storage.native import get_assets_root_path_async
8from isaacsim.replicator.grasping.grasping_manager import GraspingManager
9
10
11async def run_example_async(
12 stage_path,
13 config_path=None,
14 sampler_config=None,
15 physics_scene_path=None,
16 output_dir=None,
17 gripper_path=None,
18 object_prim_path=None,
19):
20 assets_root_path = await get_assets_root_path_async()
21 print(f"Assets root path: {assets_root_path}")
22 stage_url = assets_root_path + stage_path
23 print(f"Opening stage: {stage_url}")
24 await omni.usd.get_context().open_stage_async(stage_url)
25 stage = omni.usd.get_context().get_stage()
26
27 grasping_manager = GraspingManager()
28
29 if config_path is not None:
30 load_status = grasping_manager.load_config(config_path)
31 print(f"Config load status: {load_status}")
32
33 # Make sure the object to grasp is set (either from the config file or from the argument)
34 if not grasping_manager.get_object_prim_path() and object_prim_path:
35 grasping_manager.object_path = object_prim_path
36
37 if not grasping_manager.get_object_prim_path():
38 print("Warning: Object to grasp is not set (missing in config and argument). Aborting.")
39 return
40
41 # Make sure the gripper is set (either from the config file or from the argument)
42 if not grasping_manager.gripper_path and gripper_path:
43 grasping_manager.gripper_path = gripper_path
44
45 if not grasping_manager.gripper_path:
46 print("Warning: Gripper path is not set (missing in config and argument). Aborting.")
47 return
48
49 # If there are already grasp poses in the configuration, don't generate new ones
50 if grasping_manager.grasp_locations:
51 print(
52 f"Found {len(grasping_manager.grasp_locations)} grasp poses in the configuration file. No new poses will be generated."
53 )
54 else:
55 print("No grasp poses found in configuration, generating new ones...")
56
57 # Determine Sampler Configuration
58 if not (grasping_manager.sampler_config and grasping_manager.sampler_config.get("sampler_type")):
59 if sampler_config:
60 grasping_manager.sampler_config = sampler_config.copy()
61 else:
62 print(
63 "Warning: Sampler configuration is missing or invalid (not in config file and not provided as argument). Aborting pose generation."
64 )
65 return
66
67 # Generate the grasp poses
68 success_generation = grasping_manager.generate_grasp_poses()
69 if not success_generation or not grasping_manager.grasp_locations:
70 print("Failed to generate grasp poses or no poses were generated.")
71 return
72 print(f"Generated {len(grasping_manager.grasp_locations)} new grasp poses.")
73
74 # Store the initial gripper pose to be able to restore it after the evaluation
75 grasping_manager.store_initial_gripper_pose()
76
77 print("Evaluating grasp poses...")
78 poses_to_evaluate = grasping_manager.get_grasp_poses(in_world_frame=True)
79 if not poses_to_evaluate:
80 print("No poses available to evaluate..")
81 return
82
83 # Determine Output Path
84 if not output_dir:
85 print("Warning: Output path is not defined data will not be saved.")
86
87 # Set the output path and overwrite flag
88 grasping_manager.set_results_output_dir(output_dir)
89 grasping_manager.set_overwrite_results_output(True)
90
91 # Determine Physics Scene Path
92 physics_scene_path_for_eval = None
93 if physics_scene_path and stage.GetPrimAtPath(physics_scene_path):
94 physics_scene_path_for_eval = physics_scene_path
95 print(f"Physics scene path for evaluation: {physics_scene_path_for_eval}")
96
97 await grasping_manager.evaluate_grasp_poses(
98 grasp_poses=poses_to_evaluate,
99 render=True,
100 physics_scene_path=physics_scene_path_for_eval,
101 simulate_using_timeline=False,
102 )
103
104 print("Grasping workflow example finished.")
105 grasping_manager.clear()
106
107
108stage_path = "/Isaac/Samples/Replicator/Stage/sdg_grasping_xarm.usd"
109ext_path = get_extension_path_from_name("isaacsim.replicator.grasping")
110config_path = os.path.join(ext_path, "data/gripper_configs/xarm_antipodal_soup_can.yaml")
111output_dir = os.path.join(os.getcwd(), "xarm_antipodal")
112
113asyncio.ensure_future(run_example_async(stage_path=stage_path, config_path=config_path, output_dir=output_dir))
Grasping Synthetic Data Generation Workflow
1from isaacsim import SimulationApp
2
3simulation_app = SimulationApp(launch_config={"headless": False})
4
5import asyncio
6import os
7
8import omni.kit.app
9import omni.usd
10from isaacsim.core.utils.extensions import get_extension_path_from_name
11from isaacsim.storage.native import get_assets_root_path
12
13# Make sure the grasping extension is loaded and enabled
14ext_manager = omni.kit.app.get_app().get_extension_manager()
15if not ext_manager.is_extension_enabled("isaacsim.replicator.grasping"):
16 ext_manager.set_extension_enabled_immediate("isaacsim.replicator.grasping", True)
17from isaacsim.replicator.grasping.grasping_manager import GraspingManager
18
19
20def run_example(
21 stage_path,
22 config_path=None,
23 sampler_config=None,
24 physics_scene_path=None,
25 output_dir=None,
26 gripper_path=None,
27 object_prim_path=None,
28):
29 assets_root_path = get_assets_root_path()
30 print(f"Assets root path: {assets_root_path}")
31 stage_url = assets_root_path + stage_path
32 print(f"Opening stage: {stage_url}")
33 omni.usd.get_context().open_stage(stage_url)
34 stage = omni.usd.get_context().get_stage()
35
36 grasping_manager = GraspingManager()
37
38 if config_path is not None:
39 load_status = grasping_manager.load_config(config_path)
40 print(f"Config load status: {load_status}")
41
42 # Make sure the object to grasp is set (either from the config file or from the argument)
43 if not grasping_manager.get_object_prim_path() and object_prim_path:
44 grasping_manager.object_path = object_prim_path
45
46 if not grasping_manager.get_object_prim_path():
47 print("Warning: Object to grasp is not set (missing in config and argument). Aborting.")
48 return
49
50 # Make sure the gripper is set (either from the config file or from the argument)
51 if not grasping_manager.gripper_path and gripper_path:
52 grasping_manager.gripper_path = gripper_path
53
54 if not grasping_manager.gripper_path:
55 print("Warning: Gripper path is not set (missing in config and argument). Aborting.")
56 return
57
58 # If there are already grasp poses in the configuration, don't generate new ones
59 if grasping_manager.grasp_locations:
60 print(
61 f"Found {len(grasping_manager.grasp_locations)} grasp poses in the configuration file. No new poses will be generated."
62 )
63 else:
64 print("No grasp poses found in configuration, generating new ones...")
65
66 # Determine Sampler Configuration
67 if not (grasping_manager.sampler_config and grasping_manager.sampler_config.get("sampler_type")):
68 if sampler_config:
69 grasping_manager.sampler_config = sampler_config.copy()
70 else:
71 print(
72 "Warning: Sampler configuration is missing or invalid (not in config file and not provided as argument). Aborting pose generation."
73 )
74 return
75
76 # Generate the grasp poses
77 success_generation = grasping_manager.generate_grasp_poses()
78 if not success_generation or not grasping_manager.grasp_locations:
79 print("Failed to generate grasp poses or no poses were generated.")
80 return
81 print(f"Generated {len(grasping_manager.grasp_locations)} new grasp poses.")
82
83 # Store the initial gripper pose to be able to restore it after the evaluation
84 grasping_manager.store_initial_gripper_pose()
85
86 print("Evaluating grasp poses...")
87 poses_to_evaluate = grasping_manager.get_grasp_poses(in_world_frame=True)
88 if not poses_to_evaluate:
89 print("No poses available to evaluate..")
90 return
91
92 # Determine Output Path
93 if not output_dir:
94 print("Warning: Output path is not defined data will not be saved.")
95
96 # Set the output path and overwrite flag
97 grasping_manager.set_results_output_dir(output_dir)
98 grasping_manager.set_overwrite_results_output(True)
99
100 # Determine Physics Scene Path
101 physics_scene_path_for_eval = None
102 if physics_scene_path and stage.GetPrimAtPath(physics_scene_path):
103 physics_scene_path_for_eval = physics_scene_path
104 print(f"Physics scene path for evaluation: {physics_scene_path_for_eval}")
105
106 grasping_workflow_task = asyncio.ensure_future(
107 grasping_manager.evaluate_grasp_poses(
108 grasp_poses=poses_to_evaluate,
109 render=True,
110 physics_scene_path=physics_scene_path_for_eval,
111 simulate_using_timeline=False,
112 )
113 )
114
115 while not grasping_workflow_task.done():
116 simulation_app.update()
117
118 print("Grasping workflow example finished.")
119 grasping_manager.clear()
120
121
122stage_path = "/Isaac/Samples/Replicator/Stage/sdg_grasping_xarm.usd"
123ext_path = get_extension_path_from_name("isaacsim.replicator.grasping")
124config_path = os.path.join(ext_path, "data/gripper_configs/xarm_antipodal_soup_can.yaml")
125output_dir = os.path.join(os.getcwd(), "xarm_antipodal")
126
127run_example(stage_path=stage_path, config_path=config_path, output_dir=output_dir)
128
129
130simulation_app.close()