react-manip 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- assets/materials/realistic/common/ceramic.png +0 -0
- assets/materials/realistic/common/cream-plaster.png +0 -0
- assets/materials/realistic/common/gray-felt.png +0 -0
- assets/materials/realistic/common/gray-plaster.png +0 -0
- assets/materials/realistic/common/gray-woodgrain.png +0 -0
- assets/materials/realistic/common/light-gray-floor-tile.png +0 -0
- assets/materials/realistic/common/light-gray-plaster.png +0 -0
- assets/materials/realistic/common/metal.png +0 -0
- assets/materials/realistic/common/oak-wood.png +0 -0
- assets/materials/realistic/common/steel-brushed.png +0 -0
- assets/materials/realistic/common/steel-scratched.png +0 -0
- assets/materials/realistic/common/varnished-wood-panels.png +0 -0
- assets/materials/realistic/common/walnut-wood.png +0 -0
- assets/materials/realistic/common/white-bricks.png +0 -0
- assets/materials/realistic/common/wood-tiles.png +0 -0
- assets/materials/realistic/tiles074/Tiles074_2K_Color.png +0 -0
- assets/materials/realistic/woodfloor049/WoodFloor049_2K_Color.png +0 -0
- configs/box_insertion/profile_default.json +204 -0
- react_manip/__init__.py +12 -0
- react_manip/asset_cli.py +18 -0
- react_manip/builtin.py +168 -0
- react_manip/cameras.py +301 -0
- react_manip/category_objects.py +248 -0
- react_manip/core/__init__.py +60 -0
- react_manip/core/aggregate.py +59 -0
- react_manip/core/compatibility.py +64 -0
- react_manip/core/contracts.py +42 -0
- react_manip/core/geometry.py +269 -0
- react_manip/core/language.py +116 -0
- react_manip/core/metrics.py +196 -0
- react_manip/core/observation.py +59 -0
- react_manip/core/protocol.py +91 -0
- react_manip/core/registry.py +94 -0
- react_manip/core/runner.py +498 -0
- react_manip/core/scenarios.py +110 -0
- react_manip/core/specs.py +203 -0
- react_manip/core/timeouts.py +44 -0
- react_manip/core/visual_randomization.py +261 -0
- react_manip/evaluation/__init__.py +4 -0
- react_manip/evaluation/metrics.py +17 -0
- react_manip/evaluation/protocols.py +326 -0
- react_manip/evaluation/viewer.py +240 -0
- react_manip/instances/__init__.py +6 -0
- react_manip/instances/candidate_bank.py +109 -0
- react_manip/instances/public.py +95 -0
- react_manip/instances/records.py +345 -0
- react_manip/instances/runtime.py +306 -0
- react_manip/instances/suite.py +231 -0
- react_manip/instances/trajectory.py +59 -0
- react_manip/instances/variation.py +118 -0
- react_manip/legacy.py +318 -0
- react_manip/policies/__init__.py +5 -0
- react_manip/policies/base.py +79 -0
- react_manip/rendering.py +58 -0
- react_manip/robot_registry.py +31 -0
- react_manip/robots/__init__.py +33 -0
- react_manip/robots/adapters.py +135 -0
- react_manip/robots/agilex_adapter.py +35 -0
- react_manip/robots/agilex_description.py +74 -0
- react_manip/robots/agilex_robosuite.py +246 -0
- react_manip/robots/arm_actions.py +17 -0
- react_manip/robots/base.py +119 -0
- react_manip/robots/catalog.py +18 -0
- react_manip/robots/legacy_agilex_robosuite.py +169 -0
- react_manip/robots/mobile_base.py +33 -0
- react_manip/robots/mounts.py +80 -0
- react_manip/robots/resolution.py +103 -0
- react_manip/robots/sawyer_robosuite.py +147 -0
- react_manip/robots/sensors.py +137 -0
- react_manip/utils/__init__.py +1 -0
- react_manip/visual_task.py +50 -0
- react_manip-0.1.0.dist-info/METADATA +446 -0
- react_manip-0.1.0.dist-info/RECORD +99 -0
- react_manip-0.1.0.dist-info/WHEEL +5 -0
- react_manip-0.1.0.dist-info/entry_points.txt +2 -0
- react_manip-0.1.0.dist-info/licenses/LICENSE +131 -0
- react_manip-0.1.0.dist-info/top_level.txt +5 -0
- scripts/add_phone_lean_to_bank.py +242 -0
- scripts/agilex_wheeled_builder.py +133 -0
- scripts/audit_task_solvability.py +150 -0
- scripts/build_agilex_assets.py +317 -0
- scripts/build_legacy_agilex_assets.py +244 -0
- scripts/evaluate_all_tasks.py +309 -0
- scripts/evaluate_policy.py +281 -0
- scripts/piperx_assets.lock.json +181 -0
- scripts/pygame_demo.py +360 -0
- scripts/pygame_task_debug.py +242 -0
- scripts/regenerate_instance_bank.py +192 -0
- scripts/remove_task_from_bank.py +103 -0
- scripts/select_task_instances.py +64 -0
- scripts/verify_curling_reachability.py +206 -0
- scripts/verify_piperx_tasks.py +81 -0
- tasks/box_insertion/__init__.py +3 -0
- tasks/box_insertion/assets/scene.xml +50 -0
- tasks/box_insertion/env.py +642 -0
- tasks/box_insertion/evaluation.json +16 -0
- tasks/box_insertion/instance_contract.json +321 -0
- tasks/box_insertion/scoring.py +23 -0
- tasks/box_insertion/task_spec.json +333 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0",
|
|
3
|
+
"profile_id": "box_insertion_final_position_v3",
|
|
4
|
+
"task_id": "box_insertion",
|
|
5
|
+
"fixed": {
|
|
6
|
+
"table": {
|
|
7
|
+
"top_z": 0.78,
|
|
8
|
+
"size": [
|
|
9
|
+
0.9,
|
|
10
|
+
1.6,
|
|
11
|
+
0.05
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"box": {
|
|
15
|
+
"fixed": true,
|
|
16
|
+
"mounted_on": "table",
|
|
17
|
+
"has_bottom": false,
|
|
18
|
+
"center": [
|
|
19
|
+
0.26,
|
|
20
|
+
0.0,
|
|
21
|
+
0.815
|
|
22
|
+
],
|
|
23
|
+
"clearance_m": 0.05,
|
|
24
|
+
"inner_depth": 0.3,
|
|
25
|
+
"outer_depth": 0.32,
|
|
26
|
+
"wall_height": 0.07,
|
|
27
|
+
"wall": 0.02
|
|
28
|
+
},
|
|
29
|
+
"wood_block": {
|
|
30
|
+
"size": [
|
|
31
|
+
0.13175,
|
|
32
|
+
1.0,
|
|
33
|
+
0.04421
|
|
34
|
+
],
|
|
35
|
+
"initial_clearance_to_slot_m": 0.06,
|
|
36
|
+
"target_insertion_depth_m": 0.36,
|
|
37
|
+
"bottom_tolerance_m": 0.005
|
|
38
|
+
},
|
|
39
|
+
"physics": {
|
|
40
|
+
"gravity_m_s2": [
|
|
41
|
+
0.0,
|
|
42
|
+
0.0,
|
|
43
|
+
-9.81
|
|
44
|
+
],
|
|
45
|
+
"table_friction": 0.005
|
|
46
|
+
},
|
|
47
|
+
"task": {
|
|
48
|
+
"time_score_max": 50.0,
|
|
49
|
+
"distance_score_max": 50.0,
|
|
50
|
+
"score_horizon_sec": 60.0,
|
|
51
|
+
"time_full_until_sec": 10.0,
|
|
52
|
+
"time_zero_from_sec": 40.0
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"geometry": {
|
|
56
|
+
"wood_block.width_m": {
|
|
57
|
+
"distribution": "uniform",
|
|
58
|
+
"low": 0.6,
|
|
59
|
+
"high": 1.0
|
|
60
|
+
},
|
|
61
|
+
"block_friction.split_ratio": {
|
|
62
|
+
"distribution": "uniform",
|
|
63
|
+
"low": 0.2,
|
|
64
|
+
"high": 0.8
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"physics": {
|
|
68
|
+
"block_friction.left": {
|
|
69
|
+
"distribution": "exponential",
|
|
70
|
+
"low": 0.01,
|
|
71
|
+
"high": 0.6,
|
|
72
|
+
"scale": 0.1
|
|
73
|
+
},
|
|
74
|
+
"block_friction.right": {
|
|
75
|
+
"distribution": "exponential",
|
|
76
|
+
"low": 0.01,
|
|
77
|
+
"high": 0.6,
|
|
78
|
+
"scale": 0.1
|
|
79
|
+
},
|
|
80
|
+
"block_density.light_kg_m3": {
|
|
81
|
+
"distribution": "uniform",
|
|
82
|
+
"low": 350.0,
|
|
83
|
+
"high": 550.0
|
|
84
|
+
},
|
|
85
|
+
"block_density.heavy_kg_m3": {
|
|
86
|
+
"distribution": "uniform",
|
|
87
|
+
"low": 850.0,
|
|
88
|
+
"high": 1150.0
|
|
89
|
+
},
|
|
90
|
+
"block_density.heavy_side": {
|
|
91
|
+
"distribution": "choice",
|
|
92
|
+
"values": [
|
|
93
|
+
"left",
|
|
94
|
+
"right"
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"physics.slot_left_wall_friction": {
|
|
98
|
+
"distribution": "uniform",
|
|
99
|
+
"low": 3.5,
|
|
100
|
+
"high": 5.0
|
|
101
|
+
},
|
|
102
|
+
"physics.slot_right_wall_friction": {
|
|
103
|
+
"distribution": "uniform",
|
|
104
|
+
"low": 3.5,
|
|
105
|
+
"high": 5.0
|
|
106
|
+
},
|
|
107
|
+
"physics.slot_back_wall_friction": {
|
|
108
|
+
"distribution": "uniform",
|
|
109
|
+
"low": 1.0,
|
|
110
|
+
"high": 2.0
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"appearance": {
|
|
114
|
+
"room.floor_texture": {
|
|
115
|
+
"distribution": "choice",
|
|
116
|
+
"values": [
|
|
117
|
+
"light-gray-floor-tile",
|
|
118
|
+
"oak-wood-realistic",
|
|
119
|
+
"ceramic-realistic",
|
|
120
|
+
"gray-carpet-realistic",
|
|
121
|
+
"walnut-wood-realistic"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"room.wall_texture": {
|
|
125
|
+
"distribution": "choice",
|
|
126
|
+
"values": [
|
|
127
|
+
"white-plaster",
|
|
128
|
+
"cool-white-paint",
|
|
129
|
+
"gray-plaster",
|
|
130
|
+
"brick-accent",
|
|
131
|
+
"cream-plaster-realistic"
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
"desk.texture": {
|
|
135
|
+
"distribution": "choice",
|
|
136
|
+
"values": [
|
|
137
|
+
"oak-wood-realistic",
|
|
138
|
+
"walnut-wood-realistic",
|
|
139
|
+
"gray-woodgrain-realistic",
|
|
140
|
+
"varnished-wood-realistic",
|
|
141
|
+
"white-laminate",
|
|
142
|
+
"brushed-steel-realistic"
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
"slot.texture": {
|
|
146
|
+
"distribution": "choice",
|
|
147
|
+
"values": [
|
|
148
|
+
"brushed-steel-realistic",
|
|
149
|
+
"scratched-steel-realistic",
|
|
150
|
+
"drawer-light-metal",
|
|
151
|
+
"drawer-dark-metal",
|
|
152
|
+
"drawer-white-laminate",
|
|
153
|
+
"drawer-blue-metal"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"block.texture": {
|
|
157
|
+
"distribution": "choice",
|
|
158
|
+
"values": [
|
|
159
|
+
"oak-wood-realistic",
|
|
160
|
+
"walnut-wood-realistic",
|
|
161
|
+
"gray-woodgrain-realistic",
|
|
162
|
+
"varnished-wood-realistic",
|
|
163
|
+
"white-laminate",
|
|
164
|
+
"black-laminate"
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"runtime": {
|
|
169
|
+
"lighting.layout": {
|
|
170
|
+
"distribution": "choice",
|
|
171
|
+
"values": [
|
|
172
|
+
"overcast",
|
|
173
|
+
"warm_indoor",
|
|
174
|
+
"daylight_side",
|
|
175
|
+
"cool_office",
|
|
176
|
+
"backlit",
|
|
177
|
+
"mixed_daylight"
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
"lighting.intensity_scale": {
|
|
181
|
+
"distribution": "uniform",
|
|
182
|
+
"low": 0.8,
|
|
183
|
+
"high": 1.35
|
|
184
|
+
},
|
|
185
|
+
"lighting.azimuth_deg": {
|
|
186
|
+
"distribution": "uniform",
|
|
187
|
+
"low": -180,
|
|
188
|
+
"high": 180
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"constraints": [
|
|
192
|
+
{
|
|
193
|
+
"type": "not_equal",
|
|
194
|
+
"paths": [
|
|
195
|
+
"desk.texture",
|
|
196
|
+
"block.texture"
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"assets": {
|
|
201
|
+
"scene": "tasks/box_insertion/assets/scene.xml",
|
|
202
|
+
"asset_version": "box_insertion_robot_v1"
|
|
203
|
+
}
|
|
204
|
+
}
|
react_manip/__init__.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""CL-Manip external-policy evaluation runtime."""
|
|
2
|
+
# Set this before any task imports robosuite/Numba. Some historical task
|
|
3
|
+
# modules use setdefault('NUMBA_DISABLE_JIT', '1') after robosuite is loaded;
|
|
4
|
+
# switching modes mid-process breaks controller compilation and replay IDs.
|
|
5
|
+
import os
|
|
6
|
+
os.environ.setdefault('NUMBA_DISABLE_JIT', '0')
|
|
7
|
+
__version__ = '0.1.0'
|
|
8
|
+
from .core import BenchmarkRunner, SuccessRule, TaskSpec
|
|
9
|
+
from .builtin import discover_task_definitions, register_builtin_tasks
|
|
10
|
+
from .instances.public import InstanceBundle, create_instance, open_instance, task_score
|
|
11
|
+
__all__ = ['BenchmarkRunner', 'SuccessRule', 'TaskSpec', 'discover_task_definitions',
|
|
12
|
+
'register_builtin_tasks', 'InstanceBundle', 'create_instance', 'open_instance', 'task_score']
|
react_manip/asset_cli.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Prepare the checksum-locked PiPER-X assets outside the installed package."""
|
|
2
|
+
import argparse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def main():
|
|
6
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
7
|
+
parser.add_argument('command', choices=('prepare',))
|
|
8
|
+
parser.add_argument('--offline', action='store_true')
|
|
9
|
+
args = parser.parse_args()
|
|
10
|
+
from react_manip.robots.agilex_robosuite import asset_dir, validate_bundle
|
|
11
|
+
from scripts.build_agilex_assets import Builder
|
|
12
|
+
Builder(asset_dir(), args.offline).build()
|
|
13
|
+
validate_bundle()
|
|
14
|
+
print(f'PiPER-X assets ready: {asset_dir()}')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == '__main__':
|
|
18
|
+
main()
|
react_manip/builtin.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Lazy environment registration for the sixteen release tasks."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Callable
|
|
5
|
+
import inspect
|
|
6
|
+
from .core.registry import get_task_registry
|
|
7
|
+
from .core.specs import TaskSpec, load_task_spec
|
|
8
|
+
from .robots.resolution import resolve_robosuite_robot, robot_id_from_model
|
|
9
|
+
from .instances.records import SUPPORTED_TASKS
|
|
10
|
+
|
|
11
|
+
def _lazy_constructor(module_name: str, class_name: str, default_robot: str, *, native_v2: bool = False) -> Callable[..., Any]:
|
|
12
|
+
def factory(*, seed: int | None = None, robot_id: str | None = None, **kwargs: Any) -> Any:
|
|
13
|
+
from importlib import import_module
|
|
14
|
+
from .legacy import LegacyTaskAdapter, attach_robot_context
|
|
15
|
+
|
|
16
|
+
scenario = kwargs.pop("scenario", None)
|
|
17
|
+
cls = getattr(import_module(module_name), class_name)
|
|
18
|
+
robot = robot_id or default_robot
|
|
19
|
+
if native_v2:
|
|
20
|
+
# Native v2 tasks are not robosuite environments. Construct them
|
|
21
|
+
# from the parameters they actually advertise (CurlingSweep, for
|
|
22
|
+
# example, accepts only ``seed``), while forwarding optional
|
|
23
|
+
# arguments to richer native adapters.
|
|
24
|
+
params = dict(kwargs)
|
|
25
|
+
try:
|
|
26
|
+
signature = inspect.signature(cls)
|
|
27
|
+
accepts_kwargs = any(
|
|
28
|
+
p.kind == inspect.Parameter.VAR_KEYWORD
|
|
29
|
+
for p in signature.parameters.values()
|
|
30
|
+
)
|
|
31
|
+
accepted = set(signature.parameters)
|
|
32
|
+
except (TypeError, ValueError):
|
|
33
|
+
accepts_kwargs, accepted = True, set()
|
|
34
|
+
if not accepts_kwargs:
|
|
35
|
+
params = {key: value for key, value in params.items() if key in accepted}
|
|
36
|
+
if accepts_kwargs or "seed" in accepted:
|
|
37
|
+
params.setdefault("seed", seed)
|
|
38
|
+
if "scenario" in accepted:
|
|
39
|
+
params.setdefault("scenario", scenario)
|
|
40
|
+
if "robot_id" in accepted:
|
|
41
|
+
params.setdefault("robot_id", robot_id)
|
|
42
|
+
if "robots" in accepted:
|
|
43
|
+
mapped_robot = robot
|
|
44
|
+
if isinstance(robot, str):
|
|
45
|
+
resolved = resolve_robosuite_robot(robot_id_from_model(robot))
|
|
46
|
+
mapped_robot = resolved.robot_name
|
|
47
|
+
if resolved.controller_configs is not None:
|
|
48
|
+
params.setdefault("controller_configs", resolved.controller_configs)
|
|
49
|
+
params.setdefault("gripper_types", resolved.gripper_types)
|
|
50
|
+
params.setdefault("initialization_noise", resolved.initialization_noise)
|
|
51
|
+
params.setdefault("robots", mapped_robot)
|
|
52
|
+
env = cls(**params)
|
|
53
|
+
attach_robot_context(env, robot_id)
|
|
54
|
+
env.scenario = scenario
|
|
55
|
+
adapted = LegacyTaskAdapter(env)
|
|
56
|
+
adapted.scenario = scenario
|
|
57
|
+
return adapted
|
|
58
|
+
if isinstance(robot, str):
|
|
59
|
+
robot_key = robot_id_from_model(robot)
|
|
60
|
+
resolved = resolve_robosuite_robot(robot_key)
|
|
61
|
+
robot = resolved.robot_name
|
|
62
|
+
# Preserve legacy task-tuned Panda/Sawyer defaults until their
|
|
63
|
+
# controller profiles are migrated; new providers own defaults.
|
|
64
|
+
if robot_key not in {"panda", "sawyer"}:
|
|
65
|
+
kwargs.setdefault("controller_configs", resolved.controller_configs)
|
|
66
|
+
kwargs.setdefault("gripper_types", resolved.gripper_types)
|
|
67
|
+
kwargs.setdefault("initialization_noise", resolved.initialization_noise)
|
|
68
|
+
env = LegacyTaskAdapter(cls(robots=robot, seed=seed, scenario=scenario, **kwargs))
|
|
69
|
+
if isinstance(robot, str):
|
|
70
|
+
env.env.robot_id = robot_key
|
|
71
|
+
# Tasks may resolve a Profile themselves when no Scenario was supplied.
|
|
72
|
+
# Preserve that concrete instance for replay IDs and benchmark logging.
|
|
73
|
+
env.scenario = getattr(env.env, "scenario", None) or scenario
|
|
74
|
+
return env
|
|
75
|
+
|
|
76
|
+
return factory
|
|
77
|
+
|
|
78
|
+
def _laptop_factory(*, seed: int | None = None, robot_id: str | None = None, **kwargs: Any) -> Any:
|
|
79
|
+
"""Use the same physical env construction for v2 and task recordings."""
|
|
80
|
+
|
|
81
|
+
from tasks.laptop_into_drawer.construction import make_env
|
|
82
|
+
from .legacy import LegacyTaskAdapter
|
|
83
|
+
|
|
84
|
+
scenario = kwargs.get("scenario")
|
|
85
|
+
# Headless benchmark runs do not need an OpenGL context. Recorders opt in
|
|
86
|
+
# explicitly so macOS CGL is never initialized on a non-GUI evaluation.
|
|
87
|
+
kwargs.setdefault("has_offscreen_renderer", False)
|
|
88
|
+
env = LegacyTaskAdapter(make_env(seed=0 if seed is None else seed, robot_id=robot_id or "dual_piperx", **kwargs))
|
|
89
|
+
return env
|
|
90
|
+
|
|
91
|
+
def _maze_factory(*, seed=None, robot_id=None, **kwargs):
|
|
92
|
+
from tasks.tilte_maze.env import TilteMazePhysical
|
|
93
|
+
from .legacy import LegacyTaskAdapter
|
|
94
|
+
env = TilteMazePhysical(robots=robot_id or 'dual_piperx', seed=seed, **kwargs)
|
|
95
|
+
adapted = LegacyTaskAdapter(env)
|
|
96
|
+
adapted.scenario = env.scenario
|
|
97
|
+
return adapted
|
|
98
|
+
|
|
99
|
+
def _phone_lean_factory(**kwargs):
|
|
100
|
+
from tasks.phone_lean.benchmark_adapter import make_benchmark_env
|
|
101
|
+
return make_benchmark_env(**kwargs)
|
|
102
|
+
|
|
103
|
+
def _leveling_board1_factory(**kwargs):
|
|
104
|
+
from tasks.leveling_board1.benchmark_adapter import make_benchmark_env
|
|
105
|
+
return make_benchmark_env(**kwargs)
|
|
106
|
+
|
|
107
|
+
def _turntable_gamble1_factory(**kwargs):
|
|
108
|
+
from tasks.turntable_gamble1.benchmark_adapter import make_benchmark_env
|
|
109
|
+
return make_benchmark_env(**kwargs)
|
|
110
|
+
|
|
111
|
+
def _car_drive2_factory(**kwargs):
|
|
112
|
+
from tasks.car_drive2.benchmark_adapter import make_benchmark_env
|
|
113
|
+
return make_benchmark_env(**kwargs)
|
|
114
|
+
|
|
115
|
+
def _ring_toss1_factory(**kwargs):
|
|
116
|
+
from tasks.ring_toss1.benchmark_adapter import make_benchmark_env
|
|
117
|
+
return make_benchmark_env(**kwargs)
|
|
118
|
+
|
|
119
|
+
_SPECIAL_FACTORIES = {'laptop_into_drawer': _laptop_factory, 'tilte_maze': _maze_factory, 'phone_lean': _phone_lean_factory, 'leveling_board1': _leveling_board1_factory, 'turntable_gamble1': _turntable_gamble1_factory, 'car_drive2': _car_drive2_factory, 'ring_toss1': _ring_toss1_factory}
|
|
120
|
+
|
|
121
|
+
def discover_task_definitions(root: str | Path | None = None, *, task_ids=None):
|
|
122
|
+
root_path = Path(root) if root is not None else Path(__file__).resolve().parents[1] / 'tasks'
|
|
123
|
+
definitions = []
|
|
124
|
+
available = (task_id for task_id in SUPPORTED_TASKS
|
|
125
|
+
if (root_path / task_id / 'task_spec.json').is_file())
|
|
126
|
+
for task_id in available if task_ids is None else task_ids:
|
|
127
|
+
spec = load_task_spec(root_path / task_id / 'task_spec.json')
|
|
128
|
+
class_name = ''.join(part.capitalize() for part in task_id.split('_'))
|
|
129
|
+
factory = _SPECIAL_FACTORIES.get(task_id, _lazy_constructor(
|
|
130
|
+
f'tasks.{task_id}.env', class_name,
|
|
131
|
+
spec.supported_robots[0] if spec.supported_robots else 'dual_piperx',
|
|
132
|
+
native_v2=bool(spec.metadata.get('native_v2', False))))
|
|
133
|
+
definitions.append((spec, _camera_factory(factory, spec)))
|
|
134
|
+
return tuple(definitions)
|
|
135
|
+
|
|
136
|
+
def _camera_factory(factory, spec=None):
|
|
137
|
+
"""Uniform opt-in RGB, independent of legacy use_camera_obs support."""
|
|
138
|
+
from functools import wraps
|
|
139
|
+
|
|
140
|
+
@wraps(factory)
|
|
141
|
+
def create(*args, camera_observation_ids=(), camera_width=640, camera_height=480, **kwargs):
|
|
142
|
+
if spec is not None:
|
|
143
|
+
from .core.compatibility import resolve_task_robot
|
|
144
|
+
kwargs['robot_id'] = resolve_task_robot(spec, kwargs.get('robot_id'))
|
|
145
|
+
elif kwargs.get('robot_id') is not None:
|
|
146
|
+
from .robots.catalog import normalize_robot_id
|
|
147
|
+
kwargs['robot_id'] = normalize_robot_id(kwargs['robot_id'])
|
|
148
|
+
env = factory(*args, **kwargs)
|
|
149
|
+
try:
|
|
150
|
+
from .cameras import configure_fixed_cameras
|
|
151
|
+
configure_fixed_cameras(getattr(env, 'env', env))
|
|
152
|
+
from .robots.agilex_robosuite import validate_compiled_grippers
|
|
153
|
+
validate_compiled_grippers(env)
|
|
154
|
+
env.set_camera_observations(camera_observation_ids, width=camera_width, height=camera_height)
|
|
155
|
+
return env
|
|
156
|
+
except Exception:
|
|
157
|
+
env.close()
|
|
158
|
+
raise
|
|
159
|
+
return create
|
|
160
|
+
|
|
161
|
+
def register_builtin_tasks(*, replace: bool = False) -> None:
|
|
162
|
+
"""Register legacy tasks exactly once; safe to call repeatedly."""
|
|
163
|
+
|
|
164
|
+
registry = get_task_registry()
|
|
165
|
+
for spec, factory in discover_task_definitions():
|
|
166
|
+
if spec.task_id in {definition.spec.task_id for definition in registry.list()} and not replace:
|
|
167
|
+
continue
|
|
168
|
+
registry.register(spec, factory, replace=replace)
|