feat: add test tube pick task with custom assets and grasp annotations

- Add pick_test_tube task: USDC asset repackaging, grasp generation, task config
- Add tools: usdc_to_obj.py, repackage_test_tube.py, fix_test_tube_materials.py
- Add custom_task_guide.md: full Chinese documentation for creating custom tasks
- Add crawled InternDataEngine online docs (23 pages)
- Add grasp generation script (gen_tube_grasp.py) and pipeline config
This commit is contained in:
Tangger
2026-04-05 11:01:59 +08:00
parent 6314603676
commit 3d6b73753a
36 changed files with 18013 additions and 0 deletions

433
docs_crawled/config_dr.md Normal file
View File

@@ -0,0 +1,433 @@
# Source: https://internrobotics.github.io/InternDataEngine-Docs/config/dr.html
# Domain Randomization [](#domain-randomization)
Domain randomization generates diverse training data by varying simulation parameters. This helps bridge the sim-to-real gap and improves model generalization.
## Randomization Types [](#randomization-types)
### 1. Environment Map Randomization [](#_1-environment-map-randomization)
Config Example:
yaml
```
# Source: configs/manip/simbox/pick_and_place/lift2/single_pick/left/omniobject3d-banana.yaml
env_map:
envmap_lib: envmap_lib
apply_randomization: True
intensity_range: [4000, 7000]
rotation_range: [0, 180]
```
1
2
3
4
5
6
Code Example:
python
```
# Source: workflows/simbox/core/tasks/banana.py
def _set_envmap(self):
"""Randomize or reset the environment map (HDR dome light)."""
cfg = self.cfg["env_map"]
if cfg.get("light_type", "DomeLight") == "DomeLight":
envmap_hdr_path_list = glob.glob(os.path.join(self.asset_root, cfg["envmap_lib"], "*.hdr"))
envmap_hdr_path_list.sort()
if cfg.get("apply_randomization", False):
envmap_id = random.randint(0, len(envmap_hdr_path_list) - 1)
intensity = random.uniform(cfg["intensity_range"][0], cfg["intensity_range"][1])
rotation = [random.uniform(cfg["rotation_range"][0], cfg["rotation_range"][1]) for _ in range(3)]
else:
envmap_id = 0
intensity = 1000.0
rotation = [0.0, 0.0, 0.0]
dome_prim_path = f"{self.root_prim_path}/DomeLight"
envmap_hdr_path = envmap_hdr_path_list[envmap_id]
if not is_prim_path_valid(dome_prim_path):
self.dome_light_prim = UsdLux.DomeLight.Define(self.stage, dome_prim_path)
UsdGeom.Xformable(self.dome_light_prim).AddRotateXYZOp().Set((rotation[0], rotation[1], rotation[2]))
else:
self.dome_light_prim.GetOrderedXformOps()[0].Set((rotation[0], rotation[1], rotation[2]))
self.dome_light_prim.GetIntensityAttr().Set(intensity)
self.dome_light_prim.GetTextureFileAttr().Set(envmap_hdr_path)
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
### 2. Texture Randomization [](#_2-texture-randomization)
Config Example:
yaml
```
# Source: workflows/simbox/core/configs/arenas/pick_randomized_arena.yaml
fixtures:
-
name: table
path: table0/instance.usd
target_class: GeometryObject
translation: [0.0, 0.0, 0.375]
scale: [0.001, 0.001053, 0.001056]
texture:
texture_lib: "table_textures"
apply_randomization: True
texture_id: 0
texture_scale: [0.001, 0.001]
```
1
2
3
4
5
6
7
8
9
10
11
12
13
Code Example:
python
```
# Source: workflows/simbox/core/objects/plane_object.py
def apply_texture(self, asset_root, cfg):
texture_name = cfg["texture_lib"]
texture_path_list = glob.glob(os.path.join(asset_root, texture_name, "*"))
texture_path_list.sort()
if cfg.get("apply_randomization", False):
texture_id = random.randint(0, len(texture_path_list) - 1)
else:
texture_id = cfg["texture_id"]
texture_path = texture_path_list[texture_id]
mat_prim_path = f"{self.prim_path}/Looks/Material"
if not is_prim_path_valid(mat_prim_path):
self.mat = OmniPBR(
prim_path=mat_prim_path,
name="Material",
texture_path=texture_path,
texture_scale=cfg.get("texture_scale"),
)
self.apply_visual_material(self.mat)
else:
self.mat.set_texture(
texture_path,
)
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
### 3. Camera Pose Randomization [](#_3-camera-pose-randomization)
Config Example:
yaml
```
# Source: configs/manip/simbox/pick_and_place/lift2/single_pick/left/omniobject3d-banana.yaml
cameras:
-
name: lift2_hand_left
translation: [0.07, 0.01, 0.08]
orientation: [0.62, 0.33, -0.33, -0.62]
camera_axes: usd
camera_file: workflows/simbox/core/configs/cameras/realsense_d405.yaml
parent: "lift2/lift2/lift2/fl/link6" # todo
apply_randomization: True
max_translation_noise: 0.02
max_orientation_noise: 2.5
```
1
2
3
4
5
6
7
8
9
10
11
12
Code Example:
python
```
# Source: workflows/simbox/core/tasks/banana.py
def _perturb_camera(self, camera, cfg, max_translation_noise=0.05, max_orientation_noise=10.0):
translation = np.array(cfg["translation"])
orientation = np.array(cfg["orientation"])
random_direction = np.random.randn(3)
random_direction /= np.linalg.norm(random_direction)
random_distance = np.random.uniform(0, max_translation_noise)
perturbed_translation = translation + random_direction * random_distance
original_rot = R.from_quat(orientation, scalar_first=True)
random_axis = np.random.randn(3)
random_axis /= np.linalg.norm(random_axis)
random_angle_deg = np.random.uniform(-max_orientation_noise, max_orientation_noise)
random_angle_rad = np.radians(random_angle_deg)
perturbation_rot = R.from_rotvec(random_axis * random_angle_rad)
perturbed_rot = perturbation_rot * original_rot
perturbed_orientation = perturbed_rot.as_quat(scalar_first=True)
camera.set_local_pose(
translation=perturbed_translation,
orientation=perturbed_orientation,
camera_axes=cfg["camera_axes"],
)
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
### 4. Region Randomization [](#_4-region-randomization)
Config Example:
yaml
```
# Source: configs/manip/simbox/pick_and_place/lift2/single_pick/left/omniobject3d-banana.yaml
regions:
-
object: pick_object_left
target: table
random_type: A_on_B_region_sampler
random_config:
pos_range: [
[-0.35, -0.25, 0.0],
[0.05, 0.05, 0.0]
]
yaw_rotation: [-180.0, 180.0]
-
object: lift2
target: table
random_type: A_on_B_region_sampler
random_config:
pos_range: [
[-0.025, -0.80, -0.775],
[0.025, -0.80, -0.67]
]
yaw_rotation: [-0.0, 0.0]
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Code Example:
python
```
# Source: workflows/simbox/core/tasks/banana.py
def _set_regions(self):
"""Randomize object poses according to region configs."""
random_region_list = deepcopy(self.random_region_list)
for cfg in self.cfg["regions"]:
obj = self._task_objects[cfg["object"]]
tgt = self._task_objects[cfg["target"]]
if "sub_tgt_prim" in cfg:
tgt = XFormPrim(prim_path=tgt.prim_path + cfg["sub_tgt_prim"])
if "priority" in cfg:
if cfg["priority"]:
idx = random.choice(cfg["priority"])
else:
idx = random.randint(0, len(random_region_list) - 1)
random_config = (random_region_list.pop(idx))["random_config"]
sampler_fn = getattr(RandomRegionSampler, cfg["random_type"])
pose = sampler_fn(obj, tgt, **random_config)
obj.set_local_pose(*pose)
elif "container" in cfg:
container = self._task_objects[cfg["container"]]
obj_trans = container.get_local_pose()[0]
x_bias = random.choice(container.gap) if container.gap else 0
obj_trans[0] += x_bias
obj_trans[2] += cfg["z_init"]
obj_ori = obj.get_local_pose()[1]
obj.set_local_pose(obj_trans, obj_ori)
elif "target2" in cfg:
tgt2 = self._task_objects[cfg["target2"]]
sampler_fn = getattr(RandomRegionSampler, cfg["random_type"])
pose = sampler_fn(obj, tgt, tgt2, **cfg["random_config"])
obj.set_local_pose(*pose)
else:
sampler_fn = getattr(RandomRegionSampler, cfg["random_type"])
pose = sampler_fn(obj, tgt, **cfg["random_config"])
obj.set_local_pose(*pose)
# Source: workflows/simbox/core/utils/region_sampler.py
@staticmethod
def A_on_B_region_sampler(obj, tgt, pos_range, yaw_rotation):
# Translation
shift = np.random.uniform(*pos_range)
bbox_obj = compute_bbox(obj.prim)
obj_z_min = bbox_obj.min[2]
bbox_tgt = compute_bbox(tgt.prim)
tgt_center = (np.asarray(bbox_tgt.min) + np.asarray(bbox_tgt.max)) / 2
tgt_z_max = bbox_tgt.max[2]
place_pos = np.zeros(3)
place_pos[0] = tgt_center[0]
place_pos[1] = tgt_center[1]
place_pos[2] = (
tgt_z_max + (obj.get_local_pose()[0][2] - obj_z_min) + 0.001
) # add a small value to avoid penetration
place_pos += shift
# Orientation
yaw = np.random.uniform(*yaw_rotation)
dr = R.from_euler("xyz", [0.0, 0.0, yaw], degrees=True)
r = R.from_quat(obj.get_local_pose()[1], scalar_first=True)
orientation = (dr * r).as_quat(scalar_first=True)
return place_pos, orientation
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
## Key Files [](#key-files)
- **utils/dr.py **( file ): Randomization utilities.
- **utils/constants.py **( file ): Category parameters.
- **tasks/banana.py **( file ): Randomization implementation.
## References [](#references)
- [Omni6DPose: A Benchmark and Model for Universal 6D Object Pose Estimation and Tracking (ECCV 2024)](https://jiyao06.github.io/Omni6DPose/)