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:
433
docs_crawled/config_dr.md
Normal file
433
docs_crawled/config_dr.md
Normal 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/)
|
||||
Reference in New Issue
Block a user