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.
Files changed (99) hide show
  1. assets/materials/realistic/common/ceramic.png +0 -0
  2. assets/materials/realistic/common/cream-plaster.png +0 -0
  3. assets/materials/realistic/common/gray-felt.png +0 -0
  4. assets/materials/realistic/common/gray-plaster.png +0 -0
  5. assets/materials/realistic/common/gray-woodgrain.png +0 -0
  6. assets/materials/realistic/common/light-gray-floor-tile.png +0 -0
  7. assets/materials/realistic/common/light-gray-plaster.png +0 -0
  8. assets/materials/realistic/common/metal.png +0 -0
  9. assets/materials/realistic/common/oak-wood.png +0 -0
  10. assets/materials/realistic/common/steel-brushed.png +0 -0
  11. assets/materials/realistic/common/steel-scratched.png +0 -0
  12. assets/materials/realistic/common/varnished-wood-panels.png +0 -0
  13. assets/materials/realistic/common/walnut-wood.png +0 -0
  14. assets/materials/realistic/common/white-bricks.png +0 -0
  15. assets/materials/realistic/common/wood-tiles.png +0 -0
  16. assets/materials/realistic/tiles074/Tiles074_2K_Color.png +0 -0
  17. assets/materials/realistic/woodfloor049/WoodFloor049_2K_Color.png +0 -0
  18. configs/box_insertion/profile_default.json +204 -0
  19. react_manip/__init__.py +12 -0
  20. react_manip/asset_cli.py +18 -0
  21. react_manip/builtin.py +168 -0
  22. react_manip/cameras.py +301 -0
  23. react_manip/category_objects.py +248 -0
  24. react_manip/core/__init__.py +60 -0
  25. react_manip/core/aggregate.py +59 -0
  26. react_manip/core/compatibility.py +64 -0
  27. react_manip/core/contracts.py +42 -0
  28. react_manip/core/geometry.py +269 -0
  29. react_manip/core/language.py +116 -0
  30. react_manip/core/metrics.py +196 -0
  31. react_manip/core/observation.py +59 -0
  32. react_manip/core/protocol.py +91 -0
  33. react_manip/core/registry.py +94 -0
  34. react_manip/core/runner.py +498 -0
  35. react_manip/core/scenarios.py +110 -0
  36. react_manip/core/specs.py +203 -0
  37. react_manip/core/timeouts.py +44 -0
  38. react_manip/core/visual_randomization.py +261 -0
  39. react_manip/evaluation/__init__.py +4 -0
  40. react_manip/evaluation/metrics.py +17 -0
  41. react_manip/evaluation/protocols.py +326 -0
  42. react_manip/evaluation/viewer.py +240 -0
  43. react_manip/instances/__init__.py +6 -0
  44. react_manip/instances/candidate_bank.py +109 -0
  45. react_manip/instances/public.py +95 -0
  46. react_manip/instances/records.py +345 -0
  47. react_manip/instances/runtime.py +306 -0
  48. react_manip/instances/suite.py +231 -0
  49. react_manip/instances/trajectory.py +59 -0
  50. react_manip/instances/variation.py +118 -0
  51. react_manip/legacy.py +318 -0
  52. react_manip/policies/__init__.py +5 -0
  53. react_manip/policies/base.py +79 -0
  54. react_manip/rendering.py +58 -0
  55. react_manip/robot_registry.py +31 -0
  56. react_manip/robots/__init__.py +33 -0
  57. react_manip/robots/adapters.py +135 -0
  58. react_manip/robots/agilex_adapter.py +35 -0
  59. react_manip/robots/agilex_description.py +74 -0
  60. react_manip/robots/agilex_robosuite.py +246 -0
  61. react_manip/robots/arm_actions.py +17 -0
  62. react_manip/robots/base.py +119 -0
  63. react_manip/robots/catalog.py +18 -0
  64. react_manip/robots/legacy_agilex_robosuite.py +169 -0
  65. react_manip/robots/mobile_base.py +33 -0
  66. react_manip/robots/mounts.py +80 -0
  67. react_manip/robots/resolution.py +103 -0
  68. react_manip/robots/sawyer_robosuite.py +147 -0
  69. react_manip/robots/sensors.py +137 -0
  70. react_manip/utils/__init__.py +1 -0
  71. react_manip/visual_task.py +50 -0
  72. react_manip-0.1.0.dist-info/METADATA +446 -0
  73. react_manip-0.1.0.dist-info/RECORD +99 -0
  74. react_manip-0.1.0.dist-info/WHEEL +5 -0
  75. react_manip-0.1.0.dist-info/entry_points.txt +2 -0
  76. react_manip-0.1.0.dist-info/licenses/LICENSE +131 -0
  77. react_manip-0.1.0.dist-info/top_level.txt +5 -0
  78. scripts/add_phone_lean_to_bank.py +242 -0
  79. scripts/agilex_wheeled_builder.py +133 -0
  80. scripts/audit_task_solvability.py +150 -0
  81. scripts/build_agilex_assets.py +317 -0
  82. scripts/build_legacy_agilex_assets.py +244 -0
  83. scripts/evaluate_all_tasks.py +309 -0
  84. scripts/evaluate_policy.py +281 -0
  85. scripts/piperx_assets.lock.json +181 -0
  86. scripts/pygame_demo.py +360 -0
  87. scripts/pygame_task_debug.py +242 -0
  88. scripts/regenerate_instance_bank.py +192 -0
  89. scripts/remove_task_from_bank.py +103 -0
  90. scripts/select_task_instances.py +64 -0
  91. scripts/verify_curling_reachability.py +206 -0
  92. scripts/verify_piperx_tasks.py +81 -0
  93. tasks/box_insertion/__init__.py +3 -0
  94. tasks/box_insertion/assets/scene.xml +50 -0
  95. tasks/box_insertion/env.py +642 -0
  96. tasks/box_insertion/evaluation.json +16 -0
  97. tasks/box_insertion/instance_contract.json +321 -0
  98. tasks/box_insertion/scoring.py +23 -0
  99. tasks/box_insertion/task_spec.json +333 -0
@@ -0,0 +1,321 @@
1
+ {
2
+ "schema_version": "cl-manip.instance-contract.v1",
3
+ "status": "pilot",
4
+ "robot_id": "piperx",
5
+ "time": {
6
+ "clock": "synchronous_simulation",
7
+ "policy_wait_advances_physics": false
8
+ },
9
+ "observation": {
10
+ "public": [
11
+ "proprio",
12
+ "visual",
13
+ "current_instruction",
14
+ "task_feedback"
15
+ ],
16
+ "private": [
17
+ "resolved_parameters",
18
+ "initial_state_file",
19
+ "future_round_plan"
20
+ ]
21
+ },
22
+ "action": {
23
+ "frame": "world",
24
+ "bounds": [
25
+ -1,
26
+ 1
27
+ ],
28
+ "layout": "runtime.action_layout",
29
+ "invalid_action": "invalid_run",
30
+ "left_arm": "not_present",
31
+ "layout_note": "piperx has 7 arm/gripper controls; runtime.action_layout is authoritative."
32
+ },
33
+ "reset": {
34
+ "format": "mujoco.integration.v1",
35
+ "time": 0,
36
+ "task_counters": "zero",
37
+ "initialization_noise": null,
38
+ "state_restore_during_step": false,
39
+ "variation": "Explicit Episode variation applied before compilation; reset repeats that Episode exactly.",
40
+ "round_plan": null
41
+ },
42
+ "evaluation": {
43
+ "practice": 10,
44
+ "exam": 5,
45
+ "primary": "mean_exam_task_score",
46
+ "invalid": "abort_group_without_official_score",
47
+ "exam_adaptation": "online",
48
+ "score_key": "total_score"
49
+ },
50
+ "task_id": "box_insertion",
51
+ "contract_version": "1.0-episode-v1",
52
+ "control_hz": 20,
53
+ "horizon_sec": 60,
54
+ "ownership": {
55
+ "spec": [
56
+ "block length/height, U slot, fixed initial pose, +X pushing",
57
+ "20 Hz / 60 s, scoring t1=10 and t2=40 s, corner tolerances and success conditions",
58
+ "fixed ALOHA mount/controller, no initialization noise, sampling domains"
59
+ ],
60
+ "task_instance": [
61
+ "wood_block.width_m (baseline; Episode may override fields listed in episode_randomization)",
62
+ "block_friction.split_ratio (baseline; Episode may override fields listed in episode_randomization)",
63
+ "block_friction.left/right (baseline; Episode may override fields listed in episode_randomization)",
64
+ "block_density.light_kg_m3/heavy_kg_m3/heavy_side (baseline; Episode may override fields listed in episode_randomization)",
65
+ "physics.slot_left_wall_friction/slot_right_wall_friction/slot_back_wall_friction (baseline; Episode may override fields listed in episode_randomization)",
66
+ "room/desk/slot/block textures and lighting (baseline; Episode may override fields listed in episode_randomization)"
67
+ ],
68
+ "derived": [
69
+ "slot opening=block width+.05",
70
+ "block mass, COM and inertia from disjoint region volumes and densities; compiled into runtime model identity"
71
+ ],
72
+ "episode_instance": [
73
+ "left/right block sliding friction",
74
+ "uniform density multiplier preserving COM and scaling mass/inertia together",
75
+ "explicit integration initial_state",
76
+ "compiled Episode runtime identity",
77
+ "round_plan=null"
78
+ ],
79
+ "policy_decision": [
80
+ "robot pushing actions"
81
+ ]
82
+ },
83
+ "rules": {
84
+ "success": "all rotated eight corners inside X[.10,.40], Y[-opening/2,opening/2], Z[.78,.85], inclusive tolerance .0005; current clipped displacement from initial x >=.355; linear speed<=.025 and angular speed<=.08; continuous 10 ticks; interruption resets; success ends episode, no release requirement",
85
+ "distance": "50*clip((current_center_x-.10)/(.40-half_length-.10),0,1), no historical maximum; all corners inside Y/Z/back boundary with .0005 tolerance, but no front X bound; invalid position or failure =>0",
86
+ "time": "success only: 50 for t<=10; 50*(40-t)/30 for 10<t<40; zero for t>=40; elapsed includes 10 stable ticks",
87
+ "total": "distance+time; success tolerance can yield distance slightly below50; no automatic rounding up",
88
+ "failure": "center z<.65 ends and scores0; nonfinite simulation is invalid in replay",
89
+ "timeout": "1200 steps / 60 s: preserve valid final-position distance, time0; success on final tick takes precedence",
90
+ "reward": "change in current total_score, may be negative on retreat; not official score",
91
+ "rounds": false,
92
+ "feasibility": "three-layer and evaluator checks only; no ALOHA grasp or pushing demo recertification"
93
+ },
94
+ "sampling_profile": {
95
+ "schema_version": "1.0",
96
+ "profile_id": "box_insertion_final_position_v3",
97
+ "task_id": "box_insertion",
98
+ "fixed": {
99
+ "table": {
100
+ "top_z": 0.78,
101
+ "size": [
102
+ 0.9,
103
+ 1.6,
104
+ 0.05
105
+ ]
106
+ },
107
+ "box": {
108
+ "fixed": true,
109
+ "mounted_on": "table",
110
+ "has_bottom": false,
111
+ "center": [
112
+ 0.26,
113
+ 0.0,
114
+ 0.815
115
+ ],
116
+ "clearance_m": 0.05,
117
+ "inner_depth": 0.3,
118
+ "outer_depth": 0.32,
119
+ "wall_height": 0.07,
120
+ "wall": 0.02
121
+ },
122
+ "wood_block": {
123
+ "size": [
124
+ 0.13175,
125
+ 1.0,
126
+ 0.04421
127
+ ],
128
+ "initial_clearance_to_slot_m": 0.06,
129
+ "target_insertion_depth_m": 0.36,
130
+ "bottom_tolerance_m": 0.005
131
+ },
132
+ "physics": {
133
+ "gravity_m_s2": [
134
+ 0.0,
135
+ 0.0,
136
+ -9.81
137
+ ],
138
+ "table_friction": 0.005
139
+ },
140
+ "task": {
141
+ "time_score_max": 50.0,
142
+ "distance_score_max": 50.0,
143
+ "score_horizon_sec": 60.0,
144
+ "time_full_until_sec": 10.0,
145
+ "time_zero_from_sec": 40.0
146
+ }
147
+ },
148
+ "geometry": {
149
+ "wood_block.width_m": {
150
+ "distribution": "uniform",
151
+ "low": 0.6,
152
+ "high": 1.0
153
+ },
154
+ "block_friction.split_ratio": {
155
+ "distribution": "uniform",
156
+ "low": 0.2,
157
+ "high": 0.8
158
+ }
159
+ },
160
+ "physics": {
161
+ "block_friction.left": {
162
+ "distribution": "exponential",
163
+ "low": 0.01,
164
+ "high": 0.6,
165
+ "scale": 0.1
166
+ },
167
+ "block_friction.right": {
168
+ "distribution": "exponential",
169
+ "low": 0.01,
170
+ "high": 0.6,
171
+ "scale": 0.1
172
+ },
173
+ "block_density.light_kg_m3": {
174
+ "distribution": "uniform",
175
+ "low": 350.0,
176
+ "high": 550.0
177
+ },
178
+ "block_density.heavy_kg_m3": {
179
+ "distribution": "uniform",
180
+ "low": 850.0,
181
+ "high": 1150.0
182
+ },
183
+ "block_density.heavy_side": {
184
+ "distribution": "choice",
185
+ "values": [
186
+ "left",
187
+ "right"
188
+ ]
189
+ },
190
+ "physics.slot_left_wall_friction": {
191
+ "distribution": "uniform",
192
+ "low": 3.5,
193
+ "high": 5.0
194
+ },
195
+ "physics.slot_right_wall_friction": {
196
+ "distribution": "uniform",
197
+ "low": 3.5,
198
+ "high": 5.0
199
+ },
200
+ "physics.slot_back_wall_friction": {
201
+ "distribution": "uniform",
202
+ "low": 1.0,
203
+ "high": 2.0
204
+ }
205
+ },
206
+ "appearance": {
207
+ "room.floor_texture": {
208
+ "distribution": "choice",
209
+ "values": [
210
+ "light-gray-floor-tile",
211
+ "oak-wood-realistic",
212
+ "ceramic-realistic",
213
+ "gray-carpet-realistic",
214
+ "walnut-wood-realistic"
215
+ ]
216
+ },
217
+ "room.wall_texture": {
218
+ "distribution": "choice",
219
+ "values": [
220
+ "white-plaster",
221
+ "cool-white-paint",
222
+ "gray-plaster",
223
+ "brick-accent",
224
+ "cream-plaster-realistic"
225
+ ]
226
+ },
227
+ "desk.texture": {
228
+ "distribution": "choice",
229
+ "values": [
230
+ "oak-wood-realistic",
231
+ "walnut-wood-realistic",
232
+ "gray-woodgrain-realistic",
233
+ "varnished-wood-realistic",
234
+ "white-laminate",
235
+ "brushed-steel-realistic"
236
+ ]
237
+ },
238
+ "slot.texture": {
239
+ "distribution": "choice",
240
+ "values": [
241
+ "brushed-steel-realistic",
242
+ "scratched-steel-realistic",
243
+ "drawer-light-metal",
244
+ "drawer-dark-metal",
245
+ "drawer-white-laminate",
246
+ "drawer-blue-metal"
247
+ ]
248
+ },
249
+ "block.texture": {
250
+ "distribution": "choice",
251
+ "values": [
252
+ "oak-wood-realistic",
253
+ "walnut-wood-realistic",
254
+ "gray-woodgrain-realistic",
255
+ "varnished-wood-realistic",
256
+ "white-laminate",
257
+ "black-laminate"
258
+ ]
259
+ }
260
+ },
261
+ "runtime": {
262
+ "lighting.layout": {
263
+ "distribution": "choice",
264
+ "values": [
265
+ "overcast",
266
+ "warm_indoor",
267
+ "daylight_side",
268
+ "cool_office",
269
+ "backlit",
270
+ "mixed_daylight"
271
+ ]
272
+ },
273
+ "lighting.intensity_scale": {
274
+ "distribution": "uniform",
275
+ "low": 0.8,
276
+ "high": 1.35
277
+ },
278
+ "lighting.azimuth_deg": {
279
+ "distribution": "uniform",
280
+ "low": -180,
281
+ "high": 180
282
+ }
283
+ },
284
+ "constraints": [
285
+ {
286
+ "type": "not_equal",
287
+ "paths": [
288
+ "desk.texture",
289
+ "block.texture"
290
+ ]
291
+ }
292
+ ],
293
+ "assets": {
294
+ "scene": "tasks/box_insertion/assets/scene.xml",
295
+ "asset_version": "box_insertion_robot_v1"
296
+ }
297
+ },
298
+ "publication_status": "development_only",
299
+ "episode_randomization": {
300
+ "version": 1,
301
+ "domains": {
302
+ "friction_multiplier": [
303
+ 0.6,
304
+ 1.4
305
+ ],
306
+ "friction_limits": [
307
+ 0.01,
308
+ 0.6
309
+ ],
310
+ "mass_scale": [
311
+ 0.7,
312
+ 1.3
313
+ ]
314
+ },
315
+ "sampler": "react_manip.instances.variation.sample_variation",
316
+ "storage": "Episode variation + runtime + initial_state; Task scenario is the baseline",
317
+ "schedule": "independently shuffled five-stratum batches; two practice batches and one exam batch use the same domain; phone small count alternates 2/3",
318
+ "replay": "rebuild resolved Episode model; verify full runtime identity; restore exact initial state; no resampling during reset/step",
319
+ "policy_visibility": "qualitative runtime English instructions only; sampled values, solution axes, small-support names and files remain private"
320
+ }
321
+ }
@@ -0,0 +1,23 @@
1
+ """Final-position score, independent of historical maximum insertion depth."""
2
+ import numpy as np
3
+
4
+ T1 = 10.0
5
+ T2 = 40.0
6
+ T3 = 60.0
7
+
8
+
9
+ def score_state(*, center, corners, bounds, z_bounds, half_length, elapsed, success, failed=False):
10
+ center, corners = np.asarray(center), np.asarray(corners)
11
+ xmin,xmax,ymin,ymax=bounds
12
+ zmin,zmax=z_bounds
13
+ tol=.0005
14
+ valid=bool(not failed and np.isfinite(center).all() and np.isfinite(corners).all()
15
+ and center[2]>=.65 and np.all(corners[:,0]<=xmax+tol)
16
+ and np.all(corners[:,1]>=ymin-tol) and np.all(corners[:,1]<=ymax+tol)
17
+ and np.all(corners[:,2]>=zmin-tol) and np.all(corners[:,2]<=zmax+tol))
18
+ # Entry X is deliberately unbounded: partial insertion can earn points.
19
+ full_x=xmax-half_length
20
+ distance=50.*float(np.clip((center[0]-xmin)/(full_x-xmin),0.,1.)) if valid else 0.
21
+ time=50.*float(np.clip((T2-elapsed)/(T2-T1),0.,1.)) if success and not failed else 0.
22
+ return {'distance_score':distance,'time_score':time,'total_score':distance+time,
23
+ 'score_position_valid':valid,'score_entry_x_m':float(xmin),'score_full_x_m':float(full_x)}
@@ -0,0 +1,333 @@
1
+ {
2
+ "api_version": "2.0",
3
+ "task_id": "box_insertion",
4
+ "task_version": "1.7",
5
+ "task_type": "one_shot",
6
+ "required_arms": 1,
7
+ "required_gripper": "parallel",
8
+ "required_eef_dof": 6,
9
+ "supported_robots": [
10
+ "piperx"
11
+ ],
12
+ "horizon_sec": 60,
13
+ "control_hz": 20,
14
+ "done_behavior": "stop",
15
+ "success": {
16
+ "min_occupancy": 0,
17
+ "min_events": 1,
18
+ "max_failures": 0,
19
+ "require_terminal_success": true
20
+ },
21
+ "observation": {
22
+ "modalities": [
23
+ "proprio",
24
+ "geometry",
25
+ "visual",
26
+ "language"
27
+ ],
28
+ "default_policy_view": [
29
+ "proprio",
30
+ "visual",
31
+ "language"
32
+ ],
33
+ "geometry_view": "internal",
34
+ "fields": {
35
+ "eef_pos": {
36
+ "shape": [
37
+ 3
38
+ ],
39
+ "dtype": "float32"
40
+ },
41
+ "eef_mat": {
42
+ "shape": [
43
+ 9
44
+ ],
45
+ "dtype": "float32"
46
+ },
47
+ "robot_qpos": {
48
+ "dtype": "float32"
49
+ },
50
+ "robot_qvel": {
51
+ "dtype": "float32"
52
+ },
53
+ "gripper_qpos": {
54
+ "dtype": "float32"
55
+ },
56
+ "block_pose": {
57
+ "shape": [
58
+ 3
59
+ ],
60
+ "dtype": "float32"
61
+ },
62
+ "block_velocity": {
63
+ "shape": [
64
+ 3
65
+ ],
66
+ "dtype": "float32"
67
+ },
68
+ "block_angular_velocity": {
69
+ "shape": [
70
+ 3
71
+ ],
72
+ "dtype": "float32"
73
+ },
74
+ "block_patch_friction": {
75
+ "shape": [
76
+ 2
77
+ ],
78
+ "dtype": "float32"
79
+ },
80
+ "block_patch_density_kg_m3": {
81
+ "shape": [
82
+ 2
83
+ ],
84
+ "dtype": "float32"
85
+ },
86
+ "block_mass_kg": {
87
+ "shape": [
88
+ 1
89
+ ],
90
+ "dtype": "float32"
91
+ },
92
+ "block_com_local_m": {
93
+ "shape": [
94
+ 3
95
+ ],
96
+ "dtype": "float32"
97
+ },
98
+ "slot_wall_friction": {
99
+ "shape": [
100
+ 3
101
+ ],
102
+ "dtype": "float32"
103
+ },
104
+ "block_patch_width_m": {
105
+ "shape": [
106
+ 2
107
+ ],
108
+ "dtype": "float32"
109
+ },
110
+ "block_width_m": {
111
+ "shape": [
112
+ 1
113
+ ],
114
+ "dtype": "float32"
115
+ },
116
+ "slot_opening_width_m": {
117
+ "shape": [
118
+ 1
119
+ ],
120
+ "dtype": "float32"
121
+ },
122
+ "slot_clearance_m": {
123
+ "shape": [
124
+ 1
125
+ ],
126
+ "dtype": "float32"
127
+ },
128
+ "block_friction_split_y_m": {
129
+ "shape": [
130
+ 1
131
+ ],
132
+ "dtype": "float32"
133
+ },
134
+ "block_friction_split_from_left_m": {
135
+ "shape": [
136
+ 1
137
+ ],
138
+ "dtype": "float32"
139
+ },
140
+ "block_lateral_m": {
141
+ "shape": [
142
+ 1
143
+ ],
144
+ "dtype": "float32"
145
+ },
146
+ "block_yaw_rad": {
147
+ "shape": [
148
+ 1
149
+ ],
150
+ "dtype": "float32"
151
+ },
152
+ "block_contained": {
153
+ "shape": [
154
+ 1
155
+ ],
156
+ "dtype": "bool"
157
+ },
158
+ "bottom_reached": {
159
+ "shape": [
160
+ 1
161
+ ],
162
+ "dtype": "bool"
163
+ },
164
+ "insertion_depth_m": {
165
+ "shape": [
166
+ 1
167
+ ],
168
+ "dtype": "float32"
169
+ },
170
+ "insertion_fraction": {
171
+ "shape": [
172
+ 1
173
+ ],
174
+ "dtype": "float32"
175
+ },
176
+ "eef_to_push_face": {
177
+ "shape": [
178
+ 3
179
+ ],
180
+ "dtype": "float32"
181
+ },
182
+ "contact_force_N": {
183
+ "shape": [
184
+ 1
185
+ ],
186
+ "dtype": "float32"
187
+ }
188
+ },
189
+ "visibility": {
190
+ "block_patch_density_kg_m3": "internal",
191
+ "block_mass_kg": "internal",
192
+ "block_com_local_m": "internal",
193
+ "slot_wall_friction": "geometry_only",
194
+ "block_pose": "geometry_only",
195
+ "block_width_m": "geometry_only",
196
+ "slot_opening_width_m": "geometry_only",
197
+ "slot_clearance_m": "geometry_only",
198
+ "block_patch_friction": "internal",
199
+ "block_patch_width_m": "geometry_only",
200
+ "block_friction_split_y_m": "geometry_only",
201
+ "block_friction_split_from_left_m": "geometry_only",
202
+ "contact_force_N": "geometry_only"
203
+ }
204
+ },
205
+ "action": {
206
+ "type": "eef_delta",
207
+ "shape": [
208
+ 7
209
+ ],
210
+ "bounds": [
211
+ -1,
212
+ 1
213
+ ],
214
+ "frame": "world",
215
+ "fields": {
216
+ "position_delta": {
217
+ "indices": [
218
+ 0,
219
+ 1,
220
+ 2
221
+ ],
222
+ "units": "normalized"
223
+ },
224
+ "orientation_delta": {
225
+ "indices": [
226
+ 3,
227
+ 4,
228
+ 5
229
+ ],
230
+ "units": "normalized"
231
+ },
232
+ "gripper": {
233
+ "index": 6,
234
+ "open_value": -1,
235
+ "close_value": 1
236
+ }
237
+ }
238
+ },
239
+ "feedback": {
240
+ "fields": {
241
+ "task_seed": "int",
242
+ "block_patch_density_kg_m3": "float[2]",
243
+ "block_mass_kg": "float",
244
+ "block_com_local_m": "float[3]",
245
+ "slot_wall_friction": "float[3]",
246
+ "success_state": "bool",
247
+ "block_contained": "bool",
248
+ "bottom_reached": "bool",
249
+ "success_blockers": "string[]",
250
+ "insertion_depth_m": "float",
251
+ "remaining_insertion_distance_m": "float",
252
+ "block_lateral_m": "float",
253
+ "block_yaw_rad": "float",
254
+ "block_width_m": "float",
255
+ "slot_opening_width_m": "float",
256
+ "slot_clearance_m": "float",
257
+ "block_patch_friction": "float[2]",
258
+ "block_patch_width_m": "float[2]",
259
+ "block_friction_split_y_m": "float",
260
+ "block_friction_split_from_left_m": "float",
261
+ "total_score": "float",
262
+ "failure": "object",
263
+ "distance_score": "float",
264
+ "time_score": "float",
265
+ "score_position_valid": "bool"
266
+ },
267
+ "events": [
268
+ "block_inserted"
269
+ ],
270
+ "success_signals": [
271
+ "success_state",
272
+ "terminal_success"
273
+ ]
274
+ },
275
+ "metadata": {
276
+ "camera_contract": {
277
+ "version": "3.0",
278
+ "fixed": [
279
+ "workspace_oblique",
280
+ "workspace_top",
281
+ "room_overview"
282
+ ],
283
+ "mounted": "query get_camera_specs(); only physical embodiment sensors",
284
+ "observation_key": "images",
285
+ "default_resolution": [
286
+ 640,
287
+ 480
288
+ ],
289
+ "room_and_debug_opt_in": true,
290
+ "policy_cameras": [
291
+ "robot0_head_camera",
292
+ "robot0_wrist_right"
293
+ ],
294
+ "policy_mounting": "robot_main_and_wrists"
295
+ },
296
+ "stage": "robot_v1",
297
+ "physics": "passive_free_body_contact_only",
298
+ "score_max": 100.0,
299
+ "notes": "The block width is sampled uniformly from 0.60 to 1.00 m. For every scenario the slot opening is derived as block width + at least 0.05 m total nominal clearance (2.5 cm per side at the minimum). The gravity-loaded free rigid body has two independently sampled bottom contact regions separated at 20-80% of its width. It must be pushed to within 0.005 m of the deep slot back wall and settle before success. Task step never writes its qpos/qvel; off-center pushes can translate, rotate or tip it. The baseline may fail. Default construction samples the Profile using seed (0 if omitted); reset reuses that Task Instance. The two regions also have unequal sampled densities: light 350-550 and heavy 850-1150 kg/m3, with a random heavy side. Mass, COM and inertia follow the solid volumes. Left/right wall sliding friction is independently uniform 3.5-5.0; back wall 1.0-2.0. slot_wall_friction order is left, right, back; density order is left, right.",
300
+ "episode_randomization": {
301
+ "version": 1,
302
+ "domains": {
303
+ "friction_multiplier": [
304
+ 0.6,
305
+ 1.4
306
+ ],
307
+ "friction_limits": [
308
+ 0.01,
309
+ 0.6
310
+ ],
311
+ "mass_scale": [
312
+ 0.7,
313
+ 1.3
314
+ ]
315
+ },
316
+ "sampler": "react_manip.instances.variation.sample_variation",
317
+ "storage": "Episode variation + runtime + initial_state; Task scenario is the baseline",
318
+ "schedule": "independently shuffled five-stratum batches; two practice batches and one exam batch use the same domain; phone small count alternates 2/3",
319
+ "replay": "rebuild resolved Episode model; verify full runtime identity; restore exact initial state; no resampling during reset/step",
320
+ "policy_visibility": "qualitative runtime English instructions only; sampled values, solution axes, small-support names and files remain private"
321
+ }
322
+ },
323
+ "evaluation": {
324
+ "protocol": "practice_exam",
325
+ "practice_episodes": 10,
326
+ "exam_episodes": 5,
327
+ "exam_adaptation": "online",
328
+ "scoring": {
329
+ "primary": "mean_exam_task_score",
330
+ "score_key": "total_score"
331
+ }
332
+ }
333
+ }