react-manip 0.1.0__tar.gz
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.
- react_manip-0.1.0/LICENSE +131 -0
- react_manip-0.1.0/PKG-INFO +446 -0
- react_manip-0.1.0/README.md +422 -0
- react_manip-0.1.0/assets/materials/realistic/common/ceramic.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/cream-plaster.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/gray-felt.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/gray-plaster.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/gray-woodgrain.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/light-gray-floor-tile.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/light-gray-plaster.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/metal.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/oak-wood.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/steel-brushed.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/steel-scratched.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/varnished-wood-panels.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/walnut-wood.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/white-bricks.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/common/wood-tiles.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/tiles074/Tiles074_2K_Color.png +0 -0
- react_manip-0.1.0/assets/materials/realistic/woodfloor049/WoodFloor049_2K_Color.png +0 -0
- react_manip-0.1.0/configs/box_insertion/profile_default.json +204 -0
- react_manip-0.1.0/pyproject.toml +43 -0
- react_manip-0.1.0/react_manip/__init__.py +12 -0
- react_manip-0.1.0/react_manip/asset_cli.py +18 -0
- react_manip-0.1.0/react_manip/builtin.py +168 -0
- react_manip-0.1.0/react_manip/cameras.py +301 -0
- react_manip-0.1.0/react_manip/category_objects.py +248 -0
- react_manip-0.1.0/react_manip/core/__init__.py +60 -0
- react_manip-0.1.0/react_manip/core/aggregate.py +59 -0
- react_manip-0.1.0/react_manip/core/compatibility.py +64 -0
- react_manip-0.1.0/react_manip/core/contracts.py +42 -0
- react_manip-0.1.0/react_manip/core/geometry.py +269 -0
- react_manip-0.1.0/react_manip/core/language.py +116 -0
- react_manip-0.1.0/react_manip/core/metrics.py +196 -0
- react_manip-0.1.0/react_manip/core/observation.py +59 -0
- react_manip-0.1.0/react_manip/core/protocol.py +91 -0
- react_manip-0.1.0/react_manip/core/registry.py +94 -0
- react_manip-0.1.0/react_manip/core/runner.py +498 -0
- react_manip-0.1.0/react_manip/core/scenarios.py +110 -0
- react_manip-0.1.0/react_manip/core/specs.py +203 -0
- react_manip-0.1.0/react_manip/core/timeouts.py +44 -0
- react_manip-0.1.0/react_manip/core/visual_randomization.py +261 -0
- react_manip-0.1.0/react_manip/evaluation/__init__.py +4 -0
- react_manip-0.1.0/react_manip/evaluation/metrics.py +17 -0
- react_manip-0.1.0/react_manip/evaluation/protocols.py +326 -0
- react_manip-0.1.0/react_manip/evaluation/viewer.py +240 -0
- react_manip-0.1.0/react_manip/instances/__init__.py +6 -0
- react_manip-0.1.0/react_manip/instances/candidate_bank.py +109 -0
- react_manip-0.1.0/react_manip/instances/public.py +95 -0
- react_manip-0.1.0/react_manip/instances/records.py +345 -0
- react_manip-0.1.0/react_manip/instances/runtime.py +306 -0
- react_manip-0.1.0/react_manip/instances/suite.py +231 -0
- react_manip-0.1.0/react_manip/instances/trajectory.py +59 -0
- react_manip-0.1.0/react_manip/instances/variation.py +118 -0
- react_manip-0.1.0/react_manip/legacy.py +318 -0
- react_manip-0.1.0/react_manip/policies/__init__.py +5 -0
- react_manip-0.1.0/react_manip/policies/base.py +79 -0
- react_manip-0.1.0/react_manip/rendering.py +58 -0
- react_manip-0.1.0/react_manip/robot_registry.py +31 -0
- react_manip-0.1.0/react_manip/robots/__init__.py +33 -0
- react_manip-0.1.0/react_manip/robots/adapters.py +135 -0
- react_manip-0.1.0/react_manip/robots/agilex_adapter.py +35 -0
- react_manip-0.1.0/react_manip/robots/agilex_description.py +74 -0
- react_manip-0.1.0/react_manip/robots/agilex_robosuite.py +246 -0
- react_manip-0.1.0/react_manip/robots/arm_actions.py +17 -0
- react_manip-0.1.0/react_manip/robots/base.py +119 -0
- react_manip-0.1.0/react_manip/robots/catalog.py +18 -0
- react_manip-0.1.0/react_manip/robots/legacy_agilex_robosuite.py +169 -0
- react_manip-0.1.0/react_manip/robots/mobile_base.py +33 -0
- react_manip-0.1.0/react_manip/robots/mounts.py +80 -0
- react_manip-0.1.0/react_manip/robots/resolution.py +103 -0
- react_manip-0.1.0/react_manip/robots/sawyer_robosuite.py +147 -0
- react_manip-0.1.0/react_manip/robots/sensors.py +137 -0
- react_manip-0.1.0/react_manip/utils/__init__.py +1 -0
- react_manip-0.1.0/react_manip/visual_task.py +50 -0
- react_manip-0.1.0/react_manip.egg-info/PKG-INFO +446 -0
- react_manip-0.1.0/react_manip.egg-info/SOURCES.txt +132 -0
- react_manip-0.1.0/react_manip.egg-info/dependency_links.txt +1 -0
- react_manip-0.1.0/react_manip.egg-info/entry_points.txt +2 -0
- react_manip-0.1.0/react_manip.egg-info/requires.txt +15 -0
- react_manip-0.1.0/react_manip.egg-info/top_level.txt +5 -0
- react_manip-0.1.0/scripts/add_phone_lean_to_bank.py +242 -0
- react_manip-0.1.0/scripts/agilex_wheeled_builder.py +133 -0
- react_manip-0.1.0/scripts/audit_task_solvability.py +150 -0
- react_manip-0.1.0/scripts/build_agilex_assets.py +317 -0
- react_manip-0.1.0/scripts/build_legacy_agilex_assets.py +244 -0
- react_manip-0.1.0/scripts/evaluate_all_tasks.py +309 -0
- react_manip-0.1.0/scripts/evaluate_policy.py +281 -0
- react_manip-0.1.0/scripts/piperx_assets.lock.json +181 -0
- react_manip-0.1.0/scripts/pygame_demo.py +360 -0
- react_manip-0.1.0/scripts/pygame_task_debug.py +242 -0
- react_manip-0.1.0/scripts/regenerate_instance_bank.py +192 -0
- react_manip-0.1.0/scripts/remove_task_from_bank.py +103 -0
- react_manip-0.1.0/scripts/select_task_instances.py +64 -0
- react_manip-0.1.0/scripts/verify_curling_reachability.py +206 -0
- react_manip-0.1.0/scripts/verify_piperx_tasks.py +81 -0
- react_manip-0.1.0/setup.cfg +4 -0
- react_manip-0.1.0/tasks/box_insertion/__init__.py +3 -0
- react_manip-0.1.0/tasks/box_insertion/assets/scene.xml +50 -0
- react_manip-0.1.0/tasks/box_insertion/env.py +642 -0
- react_manip-0.1.0/tasks/box_insertion/evaluation.json +16 -0
- react_manip-0.1.0/tasks/box_insertion/instance_contract.json +321 -0
- react_manip-0.1.0/tasks/box_insertion/scoring.py +23 -0
- react_manip-0.1.0/tasks/box_insertion/task_spec.json +333 -0
- react_manip-0.1.0/tests/test_box_initial_clearance.py +45 -0
- react_manip-0.1.0/tests/test_button_five_rounds.py +85 -0
- react_manip-0.1.0/tests/test_button_indicator_matching.py +26 -0
- react_manip-0.1.0/tests/test_car_control_frame.py +65 -0
- react_manip-0.1.0/tests/test_curling_manual_push.py +50 -0
- react_manip-0.1.0/tests/test_curling_reachability_audit.py +34 -0
- react_manip-0.1.0/tests/test_drawer_round_language.py +135 -0
- react_manip-0.1.0/tests/test_episode_variation.py +143 -0
- react_manip-0.1.0/tests/test_evaluate_cli_defaults.py +141 -0
- react_manip-0.1.0/tests/test_gripper_toggle.py +69 -0
- react_manip-0.1.0/tests/test_harness_vla_bridge.py +113 -0
- react_manip-0.1.0/tests/test_harness_vla_cli.py +42 -0
- react_manip-0.1.0/tests/test_harness_vla_primitives.py +89 -0
- react_manip-0.1.0/tests/test_harness_vla_rgbd.py +50 -0
- react_manip-0.1.0/tests/test_harness_vla_rpent.py +130 -0
- react_manip-0.1.0/tests/test_instance_bootstrap.py +46 -0
- react_manip-0.1.0/tests/test_level_reset_hold.py +42 -0
- react_manip-0.1.0/tests/test_pan_initial_pose.py +39 -0
- react_manip-0.1.0/tests/test_phone_lean.py +230 -0
- react_manip-0.1.0/tests/test_piperx_assets.py +187 -0
- react_manip-0.1.0/tests/test_piperx_cameras.py +141 -0
- react_manip-0.1.0/tests/test_pygame_pose_control.py +111 -0
- react_manip-0.1.0/tests/test_pygame_robot_defaults.py +43 -0
- react_manip-0.1.0/tests/test_restored_embodiments.py +43 -0
- react_manip-0.1.0/tests/test_rope_hang_support.py +69 -0
- react_manip-0.1.0/tests/test_rpent_embodiments.py +154 -0
- react_manip-0.1.0/tests/test_rpent_embodiments_runtime.py +84 -0
- react_manip-0.1.0/tests/test_rpent_native_clients.py +92 -0
- react_manip-0.1.0/tests/test_runtime_language.py +102 -0
- react_manip-0.1.0/tests/test_task_robot_defaults.py +32 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# PolyForm Noncommercial License 1.0.0
|
|
2
|
+
|
|
3
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
In order to get any license under these terms, you must agree
|
|
8
|
+
to them as both strict obligations and conditions to all
|
|
9
|
+
your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the
|
|
14
|
+
software to do everything you might do with the software
|
|
15
|
+
that would otherwise infringe the licensor's copyright
|
|
16
|
+
in it for any permitted purpose. However, you may
|
|
17
|
+
only distribute the software according to [Distribution
|
|
18
|
+
License](#distribution-license) and make changes or new works
|
|
19
|
+
based on the software according to [Changes and New Works
|
|
20
|
+
License](#changes-and-new-works-license).
|
|
21
|
+
|
|
22
|
+
## Distribution License
|
|
23
|
+
|
|
24
|
+
The licensor grants you an additional copyright license
|
|
25
|
+
to distribute copies of the software. Your license
|
|
26
|
+
to distribute covers distributing the software with
|
|
27
|
+
changes and new works permitted by [Changes and New Works
|
|
28
|
+
License](#changes-and-new-works-license).
|
|
29
|
+
|
|
30
|
+
## Notices
|
|
31
|
+
|
|
32
|
+
You must ensure that anyone who gets a copy of any part of
|
|
33
|
+
the software from you also gets a copy of these terms or the
|
|
34
|
+
URL for them above, as well as copies of any plain-text lines
|
|
35
|
+
beginning with `Required Notice:` that the licensor provided
|
|
36
|
+
with the software. For example:
|
|
37
|
+
|
|
38
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
39
|
+
|
|
40
|
+
## Changes and New Works License
|
|
41
|
+
|
|
42
|
+
The licensor grants you an additional copyright license to
|
|
43
|
+
make changes and new works based on the software for any
|
|
44
|
+
permitted purpose.
|
|
45
|
+
|
|
46
|
+
## Patent License
|
|
47
|
+
|
|
48
|
+
The licensor grants you a patent license for the software that
|
|
49
|
+
covers patent claims the licensor can license, or becomes able
|
|
50
|
+
to license, that you would infringe by using the software.
|
|
51
|
+
|
|
52
|
+
## Noncommercial Purposes
|
|
53
|
+
|
|
54
|
+
Any noncommercial purpose is a permitted purpose.
|
|
55
|
+
|
|
56
|
+
## Personal Uses
|
|
57
|
+
|
|
58
|
+
Personal use for research, experiment, and testing for
|
|
59
|
+
the benefit of public knowledge, personal study, private
|
|
60
|
+
entertainment, hobby projects, amateur pursuits, or religious
|
|
61
|
+
observance, without any anticipated commercial application,
|
|
62
|
+
is use for a permitted purpose.
|
|
63
|
+
|
|
64
|
+
## Noncommercial Organizations
|
|
65
|
+
|
|
66
|
+
Use by any charitable organization, educational institution,
|
|
67
|
+
public research organization, public safety or health
|
|
68
|
+
organization, environmental protection organization,
|
|
69
|
+
or government institution is use for a permitted purpose
|
|
70
|
+
regardless of the source of funding or obligations resulting
|
|
71
|
+
from the funding.
|
|
72
|
+
|
|
73
|
+
## Fair Use
|
|
74
|
+
|
|
75
|
+
You may have "fair use" rights for the software under the
|
|
76
|
+
law. These terms do not limit them.
|
|
77
|
+
|
|
78
|
+
## No Other Rights
|
|
79
|
+
|
|
80
|
+
These terms do not allow you to sublicense or transfer any of
|
|
81
|
+
your licenses to anyone else, or prevent the licensor from
|
|
82
|
+
granting licenses to anyone else. These terms do not imply
|
|
83
|
+
any other licenses.
|
|
84
|
+
|
|
85
|
+
## Patent Defense
|
|
86
|
+
|
|
87
|
+
If you make any written claim that the software infringes or
|
|
88
|
+
contributes to infringement of any patent, your patent license
|
|
89
|
+
for the software granted under these terms ends immediately. If
|
|
90
|
+
your company makes such a claim, your patent license ends
|
|
91
|
+
immediately for work on behalf of your company.
|
|
92
|
+
|
|
93
|
+
## Violations
|
|
94
|
+
|
|
95
|
+
The first time you are notified in writing that you have
|
|
96
|
+
violated any of these terms, or done anything with the software
|
|
97
|
+
not covered by your licenses, your licenses can nonetheless
|
|
98
|
+
continue if you come into full compliance with these terms,
|
|
99
|
+
and take practical steps to correct past violations, within
|
|
100
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
101
|
+
end immediately.
|
|
102
|
+
|
|
103
|
+
## No Liability
|
|
104
|
+
|
|
105
|
+
***As far as the law allows, the software comes as is, without
|
|
106
|
+
any warranty or condition, and the licensor will not be liable
|
|
107
|
+
to you for any damages arising out of these terms or the use
|
|
108
|
+
or nature of the software, under any kind of legal claim.***
|
|
109
|
+
|
|
110
|
+
## Definitions
|
|
111
|
+
|
|
112
|
+
The **licensor** is the individual or entity offering these
|
|
113
|
+
terms, and the **software** is the software the licensor makes
|
|
114
|
+
available under these terms.
|
|
115
|
+
|
|
116
|
+
**You** refers to the individual or entity agreeing to these
|
|
117
|
+
terms.
|
|
118
|
+
|
|
119
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
120
|
+
or other kind of organization that you work for, plus all
|
|
121
|
+
organizations that have control over, are under the control of,
|
|
122
|
+
or are under common control with that organization. **Control**
|
|
123
|
+
means ownership of substantially all the assets of an entity,
|
|
124
|
+
or the power to direct its management and policies by vote,
|
|
125
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
126
|
+
|
|
127
|
+
**Your licenses** are all the licenses granted to you for the
|
|
128
|
+
software under these terms.
|
|
129
|
+
|
|
130
|
+
**Use** means anything you do with the software requiring one
|
|
131
|
+
of your licenses.
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: react-manip
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Development API for sampled manipulation instances and MuJoCo simulation
|
|
5
|
+
License-Expression: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
Requires-Python: <3.11,>=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: numpy==1.26.4
|
|
10
|
+
Requires-Dist: mujoco==3.3.1
|
|
11
|
+
Requires-Dist: robosuite==1.5.2
|
|
12
|
+
Requires-Dist: scipy==1.15.3
|
|
13
|
+
Requires-Dist: numba==0.67.0
|
|
14
|
+
Provides-Extra: assets
|
|
15
|
+
Requires-Dist: trimesh==5.1.1; extra == "assets"
|
|
16
|
+
Requires-Dist: pycollada==0.9.3; extra == "assets"
|
|
17
|
+
Requires-Dist: lxml==6.1.3; extra == "assets"
|
|
18
|
+
Requires-Dist: python-dateutil==2.9.0.post0; extra == "assets"
|
|
19
|
+
Requires-Dist: six==1.17.0; extra == "assets"
|
|
20
|
+
Requires-Dist: coacd==1.0.7; extra == "assets"
|
|
21
|
+
Requires-Dist: rtree==1.4.1; extra == "assets"
|
|
22
|
+
Requires-Dist: networkx==3.4.2; extra == "assets"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# ReAct-Manip 0.3
|
|
26
|
+
|
|
27
|
+
> **Robot asset update:** The active embodiments now use official PiPER-X arms:
|
|
28
|
+
> `piperx`, `dual_piperx`, and `mobile_dual_piperx` (custom Tracer assembly).
|
|
29
|
+
> Build with `python scripts/build_agilex_assets.py`; pinned upstream revisions,
|
|
30
|
+
> URLs, and SHA-256 digests are recorded in [`scripts/piperx_assets.lock.json`](scripts/piperx_assets.lock.json). The PiPER-X candidate bank
|
|
31
|
+
> contains regenerated initial states and main/wrist camera observations. Old ALOHA
|
|
32
|
+
> selections remain incompatible; draw from the new bank below.
|
|
33
|
+
|
|
34
|
+
> Optional HarnessVLA and four RPent native-embodiment integrations live under
|
|
35
|
+
> `integrations/harness_vla/` and `integrations/rpent_embodiments/`. They do not
|
|
36
|
+
> change the task defaults or the maintained PiPER-X evaluation bank.
|
|
37
|
+
|
|
38
|
+
[简体中文](README.zh-CN.md)
|
|
39
|
+
|
|
40
|
+
A robotics evaluation runtime for external policies, with 16 tasks, a fixed candidate bank, and one evaluation entry point. Optional features include a policy-view window, video recording, and keyboard control through Pygame. Training and reference solving policies are outside this release. Robot asset construction and rebuilding existing resolved instance banks are supported by scripts.
|
|
41
|
+
|
|
42
|
+
> **Full evaluation scope:** A complete ReAct-Manip protocol run must run all 16 tasks in the main bank, all three Task Instances for every task, and all 15 Episodes for every instance (10 practice + 5 exam): 48 evaluation groups and 720 Episodes in total. A single task, task subset, single instance, shortened run, smoke check, aborted run, or otherwise incomplete run is for debugging or partial analysis only and must not be reported as a full protocol result. This pilot release does not yet produce an `official_score`.
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
Project-authored code, benchmark records, documentation, and original assets are released under the [PolyForm Noncommercial License 1.0.0](LICENSE). This permits use, modification, and redistribution for permitted noncommercial purposes; it is a source-available license, not an Open Source Initiative approved open-source license. Third-party dependencies and assets retain their own licenses, including bundled third-party textures and robot assets obtained through the asset builder. See the notices shipped with those assets and [`scripts/piperx_assets.lock.json`](scripts/piperx_assets.lock.json).
|
|
47
|
+
|
|
48
|
+
## Background: why we built this Benchmark
|
|
49
|
+
|
|
50
|
+
Physical manipulation is sensitive to changes in the robot, workspace, object geometry, mass, friction, contact dynamics, and visual conditions. A policy that succeeds in one setting may fail after a small change. Reliable generalization therefore involves more than recognizing a task or producing an initial action: the robot must observe the consequences of its actions and respond to the environment.
|
|
51
|
+
|
|
52
|
+
ReAct-Manip studies this process of acting, observing, learning, and adapting. Zero-shot performance is a useful baseline, but contact-rich tasks also require feedback, repeated attempts, and recovery. We build tasks that make these capabilities measurable through reproducible physical interactions, including cases where an initially plausible strategy does not work.
|
|
53
|
+
|
|
54
|
+
The practice/exam protocol gives this motivation a concrete experimental setting. A policy receives 10 practice episodes followed by 5 exam episodes on the same Task Instance. It can retain experience across those episodes and continue adapting during exams; a fresh policy is created for the next Task Instance. The primary score measures exam performance. Practice trajectories, failures, and recovery behavior help explain how that performance was reached. The runtime provides the evaluation setting; the external policy determines whether and how to learn.
|
|
55
|
+
|
|
56
|
+
Across those 15 Episodes, all four closed-loop parameter-adaptation tasks continuously change task-critical conditions. The policy does not face one fixed geometry and dynamics configuration: it must infer the current condition from action consequences while carrying useful probing and correction methods forward from practice. A complete evaluation runs every candidate and every saved parameter sequence; selecting only favorable Episodes cannot produce a complete score.
|
|
57
|
+
|
|
58
|
+
## Use cases
|
|
59
|
+
|
|
60
|
+
- **In-context adaptation:** use task language and interaction history to infer properties of the current instance and improve subsequent actions.
|
|
61
|
+
- **Continual adaptation within a Task Instance:** compare performance across practice and exam episodes while retaining policy state. The public protocol resets policy state between Task Instances, so it does not by itself measure lifelong learning across tasks.
|
|
62
|
+
- **Generalization across scenes and tasks:** study sensitivity to the geometry, physical parameters, object choices, and initial conditions that each task actually samples. Randomization is task-specific, not a promise that every parameter varies in every task.
|
|
63
|
+
- **Embodiment research:** develop policies for the single-arm, fixed dual-arm, and mobile dual-arm PiPER-X configurations. Each released task declares its supported robot; changing that embodiment requires compatible assets, task validation, and regenerated instances rather than a bank-mode CLI override.
|
|
64
|
+
- **Closed-loop behavior analysis:** inspect actions, observations, contacts, task events, errors, and recovery using the feedback available for that task, alongside final scores.
|
|
65
|
+
- **Geometry diagnostics:** inspect simulator geometry truth during local debugging. These Features are never inputs to a benchmark policy.
|
|
66
|
+
- **Simulation-to-real preparation:** investigate collision, reachability, and contact sensitivity before hardware experiments. Simulator performance alone does not establish hardware calibration or real-world transfer.
|
|
67
|
+
|
|
68
|
+
## Benchmark design principles
|
|
69
|
+
|
|
70
|
+
1. **Evaluate adaptation through interaction.** An unsuccessful attempt is useful evidence. Retries, recovery, and the time available for them follow the task's rules; success is not assumed for an Oracle or a reference strategy.
|
|
71
|
+
2. **Use physical execution as the source of truth.** Runtime actions must flow through the task's controller, actuators, and MuJoCo contact dynamics. Initialization and explicit replay may restore saved state; writing poses or velocities during an attempt to manufacture success is not a valid solution.
|
|
72
|
+
3. **Separate rules, instances, and episodes.** TaskSpec and the instance contract define the task; Task Instances resolve the parameters they own; Episode Instances specify their permitted initial-state or instruction variation. Profiles describe sampling distributions. Ownership is declared per task so that randomization remains controlled and reproducible.
|
|
73
|
+
4. **Separate public observations from privileged information.** Proprioception, policy images, language, and declared feedback form the public interface. Simulator geometry, hidden assignments, and object locations belong to a separate internal channel. Comparisons must state which information a policy received.
|
|
74
|
+
5. **Keep time and scoring explicit.** Physics advances synchronously with control steps. Task-defined completion, timeout, and score rules govern each episode; exam scores are aggregated by the protocol. Diagnostics and wall-clock inference latency help interpret results but do not replace the declared score.
|
|
75
|
+
6. **Make comparisons reproducible.** Preserve task and episode identities, resolved parameters, source/model/controller digests, dependency versions, and the selected policy track. Changed task semantics or physics require compatible instances; old and new results should not be silently mixed.
|
|
76
|
+
7. **Keep extensions declarative and evidence scoped.** Register tasks and geometry adapters through the existing interfaces. Distinguish successful loading, exact replay, a physical target-state witness, and a complete robot solution: none automatically proves the next.
|
|
77
|
+
|
|
78
|
+
## Cross-Episode parameter changes in closed-loop tasks
|
|
79
|
+
|
|
80
|
+
The main bank stores explicit Episode-level variations for all four closed-loop parameter-adaptation tasks: three Task Instances per task and 15 Episodes per instance, for 180 parameter-varying Episodes. Parameters are resolved before an Episode starts and remain fixed within it. Resetting the same Episode replays the exact saved condition instead of resampling it.
|
|
81
|
+
|
|
82
|
+
| Task | Condition changed between Episodes | Domain |
|
|
83
|
+
| --- | --- | --- |
|
|
84
|
+
| `leveling_board1` | 3D dimensions of all six shims; identity and thin-axis orientation of the three thin shims | Ordinary dimensions 6–14 cm; thin dimensions 3, 4, and 5 cm |
|
|
85
|
+
| `conveyor_grasp` | Conveyor speed and the size of every target object | 0.08–0.20 m/s; target scale 0.80–1.15× |
|
|
86
|
+
| `box_insertion` | Sliding friction of the left/right contact regions and total block mass | Friction 0.6–1.4× baseline, clipped to [0.01, 0.6]; mass 0.7–1.3× baseline |
|
|
87
|
+
| `car_drive2` | Vehicle nominal-speed gain associated with throttle displacement | 0.90–1.15 m/s |
|
|
88
|
+
|
|
89
|
+
Continuous variables use five-stratum coverage. Practice Episodes 1–5, practice Episodes 6–10, and exam Episodes 1–5 each cover the same full domain in an independently shuffled order. Practice and exam therefore share a parameter domain but differ in exact values and ordering. The saved instance records, including sampled parameters, are published in this repository. The policy API does not pass those records directly; which values appear in observations or feedback depends on each task's declared visibility contract. A policy must adapt through the permitted interface. A result should disclose any use of instance records or task-specific tuning, since those conditions differ from the policy-interface-only setting.
|
|
90
|
+
|
|
91
|
+
The variations are applied before MuJoCo model compilation and initial-state capture, then stored with the resolved runtime, model identity, and initial integration state in each Episode Instance. `phone_lean` also changes phone/support initial positions between Episodes, but support identities, sizes, masses, friction, and gravity belong to the Task Instance and stay fixed across its 15 Episodes; it is therefore reported separately from these four parameter-adaptation tasks.
|
|
92
|
+
|
|
93
|
+
## Installation
|
|
94
|
+
|
|
95
|
+
The source checkout now builds a minimal wheel for the `box_insertion` development API. The distribution has **not been published to PyPI**. Installation from this checkout does not include the 16-task candidate bank or the complete evaluation CLI.
|
|
96
|
+
|
|
97
|
+
The candidate bank requires **Python 3.10, NumPy 1.26.4, MuJoCo 3.3.1, and robosuite 1.5.2**. Use the same virtual-environment setup on macOS or Linux. From the repository root:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
python3.10 -m venv .venv
|
|
101
|
+
source .venv/bin/activate
|
|
102
|
+
python -m pip install -r requirements.txt
|
|
103
|
+
python scripts/build_agilex_assets.py
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For the minimal installed API, use Python 3.10 and install from this checkout:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
python3.10 -m venv .venv
|
|
110
|
+
source .venv/bin/activate
|
|
111
|
+
python -m pip install '.[assets]'
|
|
112
|
+
react-manip-assets prepare
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`react-manip-assets prepare` builds the checksum-locked PiPER-X assets in the checkout when installed from source, or in the user cache when installed from a wheel. The first build needs network access. To try a wheel without publishing it, build one with `python -m pip wheel . --no-deps` and install that wheel with its `[assets]` extra.
|
|
116
|
+
|
|
117
|
+
The installed development API generates one validated Task/Episode pair, replays it, and exposes the task's current score. It is for debugging and integration work; it does not produce an official benchmark result:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import numpy as np
|
|
121
|
+
from react_manip import create_instance, open_instance, task_score
|
|
122
|
+
|
|
123
|
+
bundle = create_instance('box_insertion', seed=7, episode_index=0)
|
|
124
|
+
bundle.save('example_instance')
|
|
125
|
+
with open_instance(bundle, cameras=False) as env:
|
|
126
|
+
obs, reset_info = env.reset()
|
|
127
|
+
obs, reward, terminated, truncated, info = env.step(np.zeros(env.action_dim))
|
|
128
|
+
print(task_score(info, 'box_insertion'))
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Robot assets are not committed to Git. The builder downloads official source models and meshes from pinned upstream commits and generates `assets/robots/agilex/`. The first build requires network access; cached sources are reused. Generated assets are gitignored and do not need to be downloaded again for evaluation. Small scene assets are included in the repository. Do not substitute other object assets: the bank validates the compiled model identity. The single `requirements.txt` also includes asset-builder, visualization, Pygame, and HarnessVLA API dependencies.
|
|
132
|
+
|
|
133
|
+
The runtime defaults to `NUMBA_DISABLE_JIT=0` before importing simulation dependencies, matching the recorded bank. Do not switch JIT modes within one process. Optional IK or private-configuration warnings from robosuite do not imply missing dependencies for the controllers used here.
|
|
134
|
+
|
|
135
|
+
Visual evaluation requires a working OpenGL context. macOS uses its default backend. Headless Linux typically uses `MUJOCO_GL=egl` with a working EGL driver, or `MUJOCO_GL=osmesa` with OSMesa installed. `--state-only-smoke` checks the pipeline without images and produces no protocol score.
|
|
136
|
+
|
|
137
|
+
## Evaluation
|
|
138
|
+
|
|
139
|
+
The main-bank command below performs a full protocol run. It does not use `--draw-seed` to choose only one candidate per task: it runs all 16 tasks, all 48 Task Instances, and all 720 Episodes, including all 180 parameter-varying Episodes from the four closed-loop tasks. The aggregate `protocol_score` is a full-run pilot result only when every group finishes validly; if any group is missing or invalid, the score is `null`. `--task`, task-specific manifests, and `--state-only-smoke` are not full protocol runs.
|
|
140
|
+
|
|
141
|
+
When neither `--manifest` nor `--task` is specified, evaluation defaults to the shipped `react_manip/suites/piperx_candidates_v1/bank.json`, resolved relative to the repository rather than the current working directory. `--draw-seed` remains required. Use `--candidate-bank <path>` to select another bank; explicit manifest and task modes retain their existing behavior.
|
|
142
|
+
|
|
143
|
+
For a live evaluation window or video recording, see [First-person cameras and visualization](#first-person-cameras-and-visualization). Add `--visualize` to bank or manifest evaluation; add `--video-dir` to save videos.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
python scripts/evaluate_all_tasks.py \
|
|
147
|
+
--draw-seed 42 \
|
|
148
|
+
--policy my_policy:build \
|
|
149
|
+
--out-dir outputs/model_seed42_full
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`evaluate_all_tasks.py` is the complete-evaluation entry point. It invokes the lower-level `evaluate_policy.py` and additionally verifies the task count, 48 evaluation groups, 720 completed Episodes, and the 10/5 protocol shape before writing results, logs, and `summary.json` under the output directory. Place `my_policy.py` in the repository root or on the Python module search path. Each task has three candidate Task Instances, and candidate-bank evaluation runs all three. The draw seed is retained for reproducible selection provenance but no longer drops any instance; do not pass `candidates.json` directly as an evaluation manifest. Omitting `--policy` selects the random policy for pipeline checks; it is not a model result.
|
|
153
|
+
|
|
154
|
+
Evaluations also have wall-clock safeguards: by default, each episode is limited to 30 minutes. The aggregate limit for all episodes of one task is 2 hours for `conveyor_grasp`, 4 hours for `find_object_in_drawer2`, and 1 hour for other tasks. Completed results are retained, but a timed-out task/evaluation is marked invalid. Override these limits with `--episode-wall-timeout-sec` and `--task-wall-timeout-sec`. The limits run in the shared evaluator layer, so they also apply when calling `BenchmarkRunner` or the manifest suite directly.
|
|
155
|
+
|
|
156
|
+
By default, the draw is saved beside the result as `<result_stem>_selection/`, containing a replayable manifest and all three instances and their episode records for every task. The same bank and `--draw-seed` produce the same manifest contents. Result files, selection directories, and trace directories must use new paths.
|
|
157
|
+
Selection sidecars generated by the old one-instance-per-task protocol are rejected; draw a fresh selection after this change.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Replay the exact selected instances.
|
|
161
|
+
python scripts/evaluate_policy.py \
|
|
162
|
+
--manifest outputs/model_seed42_full/all_tasks_selection/manifest.json \
|
|
163
|
+
--policy my_policy:build --out outputs/model_seed42_repeat.json
|
|
164
|
+
|
|
165
|
+
# State-only pipeline check, using the default random policy; no protocol_score.
|
|
166
|
+
python scripts/evaluate_all_tasks.py \
|
|
167
|
+
--draw-seed 0 --state-only-smoke --out-dir outputs/smoke_full
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Use `--trace-dir outputs/new_trace` to record public observations, actions, and transitions. In bank/manifest mode, the records own the robot, scene, horizon, control frequency, and episode counts; CLI overrides are rejected. For task-default debugging, use `--task TASK --policy my_policy:build`. Its protocol follows the task declaration and is separate from fixed-bank evaluation.
|
|
171
|
+
|
|
172
|
+
## External policy interface
|
|
173
|
+
|
|
174
|
+
This minimal zero-action adapter implements the interface; it is not a solving policy:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# my_policy.py
|
|
178
|
+
import numpy as np
|
|
179
|
+
|
|
180
|
+
class ModelPolicy:
|
|
181
|
+
policy_id = "my-model"
|
|
182
|
+
|
|
183
|
+
def __init__(self):
|
|
184
|
+
self.history = []
|
|
185
|
+
|
|
186
|
+
def set_action_dim(self, action_dim):
|
|
187
|
+
self.action_dim = action_dim
|
|
188
|
+
|
|
189
|
+
def reset(self, *, seed=None, task_spec=None):
|
|
190
|
+
# Independent --task episodes: initialize your model state here.
|
|
191
|
+
pass
|
|
192
|
+
|
|
193
|
+
def begin_episode(self, *, phase, episode_index, seed, task_spec):
|
|
194
|
+
# phase is practice or exam; episode_index starts at zero per phase.
|
|
195
|
+
# Clear episode-local caches while retaining cross-episode learning.
|
|
196
|
+
self.phase = phase
|
|
197
|
+
|
|
198
|
+
def act(self, observation, info):
|
|
199
|
+
# observation["images"]: {camera_id: RGB uint8 H×W×3 array}
|
|
200
|
+
# info.get("language_prompt"): current task instruction
|
|
201
|
+
# Map model outputs to the robot's action layout.
|
|
202
|
+
return np.zeros(self.action_dim, dtype=np.float32)
|
|
203
|
+
|
|
204
|
+
def end_episode(self, **feedback):
|
|
205
|
+
self.history.append(feedback)
|
|
206
|
+
|
|
207
|
+
def build():
|
|
208
|
+
return ModelPolicy()
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The factory must return a fresh policy. Fixed-bank evaluation creates one policy per Task Instance and reuses it for all 15 episodes. Learning state persists between practice and exam; online adaptation is allowed during exams. Each new task receives a fresh policy. Avoid leaking learned state across tasks through module globals.
|
|
212
|
+
|
|
213
|
+
Actions must be finite vectors of length `action_dim`, with all values in `[-1, 1]`. Invalid actions invalidate the group; they are not silently clipped. Each Task Instance selects its declared PiPER-X embodiment and recorded controller layout; a seven-dimensional single-arm policy cannot be applied unchanged to a dual-arm instance. Actual observation dictionaries and TaskSpecs define the image, instruction, and proprioceptive inputs. Instance files are not passed to the policy. Observation filtering follows task declarations; some tasks still expose task state or physical parameters. The public track rejects policies with `requires_geometry_truth=True`.
|
|
214
|
+
|
|
215
|
+
An instance/group score is the mean of its five exam scores; the candidate-bank protocol score is the mean across all 48 groups (equivalently, each task's 15 exam episodes receive equal weight). If any group is invalid, the protocol score is null and the CLI exits with a nonzero status. `official_score` remains null: this pilot release has not established an official comparison track or certified solvability for every task. Report `protocol_score` as a pilot protocol result, together with the observation track, policy setup, and run provenance. Simulation advances synchronously; slow inference does not consume extra control steps.
|
|
216
|
+
|
|
217
|
+
## Reported pilot baselines
|
|
218
|
+
|
|
219
|
+
The following results were reported from tests using the [RPent framework](https://github.com/RLinf/RPent) on the 48-group, 720-Episode protocol. Each completed row uses 480 practice and 240 exam Episodes; the exam mean is on a 0–100 scale. Pass counts and mean scores are reported values, not independently reproduced by this repository. The exact RPent configuration, policy implementation, prompts, run logs, runtime revision, and any timeout overrides are not included with these figures here. Comparisons should disclose those settings and any access to the published instance records.
|
|
220
|
+
|
|
221
|
+
| Model / configuration | Practice passes | Exam passes | Exam mean / 100 | Groups passing all five exams |
|
|
222
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
223
|
+
| GPT-6 Astra | 177/480 (36.88%) | 130/240 (54.17%) | 52.62 | 22/48 |
|
|
224
|
+
| GPT-6.1 Sol | 134/480 (27.92%) | 95/240 (39.58%) | 38.30 | 16/48 |
|
|
225
|
+
| GPT-6.1 Terra | 96/480 (20.00%) | 94/240 (39.17%) | 33.73 | 17/48 |
|
|
226
|
+
| GPT-5.6 Sol | 42/480 (8.75%) | 31/240 (12.92%) | 17.93 | 4/48 |
|
|
227
|
+
| GPT-6 Astra + PI - 0.5 | Pending | Pending | Pending | Pending |
|
|
228
|
+
|
|
229
|
+
## First-person cameras and visualization
|
|
230
|
+
|
|
231
|
+
PiPER-X evaluation supplies all public views through `observation["images"]` as 640×480 RGB uint8 arrays:
|
|
232
|
+
|
|
233
|
+
| Embodiment | Camera IDs in order |
|
|
234
|
+
| --- | --- |
|
|
235
|
+
| `piperx` | `robot0_head_camera`, `robot0_wrist_right` |
|
|
236
|
+
| `dual_piperx` / `mobile_dual_piperx` | `robot0_head_camera`, `robot0_wrist_right`, `robot0_wrist_left` |
|
|
237
|
+
|
|
238
|
+
The single-arm main camera is fixed above and behind the arm base. Dual models retain their main mounts. Wrist cameras now use the local pose `(-0.1, 0, -0.08)` and 65° field of view on the rigid gripper frame; their optical axis targets `(0, 0, 0.06)` and local `-X` is image-up. This first fit trial lifts the sensor 10 cm in the local image-up direction to reduce gripper-root occlusion while preserving the TCP aiming point. They follow the wrist, not finger opening, and never track targets. All views render the same simulation state without advancing physics. These are simulation sensor configurations, not hardware calibration. Pygame and evaluation use the same camera poses and image orientation; the display transpose only adapts array width/height to pygame and is not a 90° image rotation. Wrist images still roll with the wrist during wrist roll, while the neutral view is upright; the gripper can occlude part of the initial view, so use the main view alongside it.
|
|
239
|
+
|
|
240
|
+
Visualization dependencies are included in `requirements.txt`; no second install command is needed.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Evaluate the main bank with a live window and video recording.
|
|
244
|
+
python scripts/evaluate_all_tasks.py \
|
|
245
|
+
--draw-seed 42 \
|
|
246
|
+
--policy my_policy:build \
|
|
247
|
+
--visualize \
|
|
248
|
+
--video-dir outputs/visual_eval_42_videos \
|
|
249
|
+
--out-dir outputs/visual_eval_42
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Run from the repository root in your configured Python environment. Replace `my_policy:build` with your policy entry point. Use new result, selection and video paths. `--visualize` requires a desktop display and a working OpenGL context; do not set `MUJOCO_GL=disable`. On a headless machine, omit `--visualize` and use `--video-dir` with a working offscreen rendering backend.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Task-default debugging.
|
|
256
|
+
python scripts/evaluate_policy.py \
|
|
257
|
+
--task box_insertion --policy my_policy:build \
|
|
258
|
+
--visualize --video-dir outputs/new_camera_videos \
|
|
259
|
+
--out outputs/new_camera_result.json
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The task selects its configured robot. Display and recording work independently in task mode and with regenerated manifests/banks. Use a new video directory. Omitting `--policy` uses random actions for pipeline checks.
|
|
263
|
+
|
|
264
|
+
- The viewer uses the actual policy images: main view on the left, wrist views on the right, instructions and feedback in the sidebar.
|
|
265
|
+
- Each episode produces `EPISODE.mp4` (composite), `EPISODE.CAMERA_ID.mp4` for each full-resolution view, and JSON metadata. Videos share frame counts/order and control frequency; none contain UI/debug overlays.
|
|
266
|
+
- Up/Down scroll instructions, Space pauses, Tab shows a debug view excluded from policy input, and Esc aborts evaluation. Pauses neither advance physics nor duplicate recorded frames.
|
|
267
|
+
- `--state-only-smoke` disables images for task/instance checks and labels results accordingly; these are not RGB evaluation results. It cannot display or record. `--render` remains the separate native debugging viewer.
|
|
268
|
+
|
|
269
|
+
Camera contracts are now version 3.0. Old single-camera instances need regenerated runtime records and compatible instances, not merely a fresh draw. Source, TaskSpec and compiled-model identities remain checked. Existing PiPER-X mesh assets do not need downloading again: the common model assembly installs the new main sensor.
|
|
270
|
+
|
|
271
|
+
## Tasks
|
|
272
|
+
|
|
273
|
+
| task_id | Task |
|
|
274
|
+
| --- | --- |
|
|
275
|
+
| curling_push | Push a curling stone |
|
|
276
|
+
| button_indicator_matching | Match buttons and indicators |
|
|
277
|
+
| phone_lean | Lean a phone against a support |
|
|
278
|
+
| leveling_board1 | Level a board with shims |
|
|
279
|
+
| rail_ball_to_cup | Roll a ball along a rail into a cup |
|
|
280
|
+
| pitch_pot | Toss into a pot |
|
|
281
|
+
| conveyor_grasp | Sort conveyor objects into bins |
|
|
282
|
+
| turntable_gamble1 | Push a turntable through contact |
|
|
283
|
+
| ring_toss1 | Toss rings |
|
|
284
|
+
| box_insertion | Insert a block into a slot |
|
|
285
|
+
| car_drive2 | Drive using two physical joysticks |
|
|
286
|
+
| rope_hang | Rebalance a suspended chain |
|
|
287
|
+
| pan_flip | Flip food in a pan |
|
|
288
|
+
| laptop_into_drawer | Place a laptop in a drawer |
|
|
289
|
+
| find_object_in_drawer2 | Find an object in drawers |
|
|
290
|
+
| tilte_maze | Control a tilting maze |
|
|
291
|
+
|
|
292
|
+
Button episodes clamp the final score to [0, 100], including truncation. Running totals and signed ±20 rewards remain unchanged; `raw_score` retains the signed sum. Exam averages use individually clamped episode scores.
|
|
293
|
+
|
|
294
|
+
The phone table is 1.6 × 1.4 m, covering the arm base and mounting plate. Small supports span about 3.0–4.6 cm at their largest dimension.
|
|
295
|
+
|
|
296
|
+
Each `phone_lean` Task selects exactly two large and two small supports and varies only their initial positions between Episodes. Its three fixed candidate seeds each contain at least one bowl or bottle. No candidate or Episode seed is replaced to guarantee solvability; all four selected supports may score, and the phone angle must remain within 45–75 degrees for ten seconds.
|
|
297
|
+
|
|
298
|
+
Phone instances are maintained only in the main bank, `react_manip/suites/piperx_candidates_v1/bank.json`. For phone debugging, copy all three existing candidates and all 45 Episodes using the command below, then evaluate the resulting manifest. Selection copies existing records without resampling. `--draw-seed` remains in provenance, but this task-specific command does not use it to discard candidates. Retired banks and their old generator have been removed; historical versions remain available in Git history. Evaluation selection snapshots remain under `outputs/` for reproducibility.
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
python scripts/select_task_instances.py --task phone_lean --draw-seed 42 \
|
|
302
|
+
--out outputs/phone_selection
|
|
303
|
+
python scripts/evaluate_policy.py --manifest outputs/phone_selection/manifest.json \
|
|
304
|
+
--policy my_policy:build --out outputs/phone_results.json
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The phone has a black screen, a light-blue back, and a circular Home button on the lower half of the front. Keep the Home-button end down, back against the support, screen outward, and rounded bottom on the table. Upside-down, sideways, load-bearing screen contact, and angles above 75 degrees are rejected. After release with grasp assist disabled, angle, speed, and drift limits must hold continuously for ten seconds. Language rules come exclusively from the environment runtime interface; JSON contains no language copy.
|
|
308
|
+
|
|
309
|
+
For all 16 tasks, the versioned `task_spec.json`, `instance_contract.json`, and scoring implementation are authoritative for goals, scoring, failure/termination conditions, timing thresholds, and randomization ownership. The English instructions seen by policies come from `env.py` at reset and after every step.
|
|
310
|
+
|
|
311
|
+
The four closed-loop tasks above use the same parameter sampler in saved-bank evaluation and task-default 10/5 evaluation; bare single-scene debugging uses baseline Task parameters. Preserve every Episode's variation and runtime identity in result analysis so adaptation curves can be stratified by physical condition.
|
|
312
|
+
|
|
313
|
+
## Optional manual Pygame control
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# Pygame dependencies are included in requirements.txt.
|
|
317
|
+
python scripts/pygame_demo.py --task phone_lean
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
This tool only replays saved Task Instances and Episodes from the main bank; it does not resample or produce a protocol score. Use `--instance`/`--episode` to select exact records. N/P moves between Episodes and I/O between Task Instances. Arrow keys and PageUp/PageDown control translation; A/D, W/S, and Q/E control rotation. Space toggles the active gripper, Tab switches arms, and 1–9 or square brackets switch cameras. Backspace resets; Esc exits. Headless evaluation does not require Pygame.
|
|
321
|
+
|
|
322
|
+
For a temporary task-default scene selected by seed, a resolved Scenario, or embodiment debugging outside the fixed bank, use the separate development entry point:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
python scripts/pygame_task_debug.py --task phone_lean --seed 0
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
`pygame_task_debug.py` accepts `--robot` and `--scenario`. It constructs an unscored debugging environment rather than replaying saved Task/Episode Instances; use `pygame_demo.py` when inspecting release-bank records or reproducibility.
|
|
329
|
+
|
|
330
|
+
Manual controls default to a target translation speed of 0.06 m/s and rotation speed of 0.3 rad/s (simulation time). Hold Shift for fast mode, or press F to toggle it: initially 1.0 m/s and 1.2 rad/s, useful for pushing or throwing. Use + / - to adjust the fast translation target by 0.05 m/s (0.05–2.0 m/s), or set it at launch with `--fast-speed`. The sidebar shows the active mode and target speed. For curling, approach in FINE mode, then use FAST for the push; adjust speed and release timing to the visible target. Actual speed depends on controller tracking and the task action limits. Releasing a movement key stops advancing that target axis and holds its release position; physical braking is not instantaneous. Losing window focus or switching arms clears movement input and holds the current poses. This tuning applies only to Pygame, not policy evaluation. On MacBook, PageUp/PageDown are Fn+Up/Fn+Down.
|
|
331
|
+
|
|
332
|
+
Run `scripts/verify_curling_reachability.py` to reproduce curling action-interface reachability checks. These use offline-calibrated diagnostic action replays, not learned-policy benchmark scores.
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
## Layout and reproducibility
|
|
336
|
+
|
|
337
|
+
The release keeps only `README.md` and `README.zh-CN.md` as Markdown documentation. Versioned JSON contracts and implementation code are the source of truth for task rules, interfaces, and reproducibility constraints. Diagnostics are exposed directly through `scripts/verify_*.py` and `scripts/audit_task_solvability.py`, so released instructions do not depend on excluded auxiliary Markdown files.
|
|
338
|
+
|
|
339
|
+
- `scripts/evaluate_all_tasks.py`: complete 16-task evaluation entry point. `evaluate_policy.py`: lower-level bank/manifest/task evaluator. `pygame_demo.py`: fixed-bank manual replay. `pygame_task_debug.py`: temporary task-default scene debugging. `build_agilex_assets.py` and its helpers build robot assets.
|
|
340
|
+
- `react_manip/`: runner, protocols, observation filtering, cameras, robot integration, instance replay, and candidate selection.
|
|
341
|
+
- `tasks/<task>/`: environments, scoring/physics helpers, task declarations, and required assets.
|
|
342
|
+
- `configs/`: default profiles needed for task construction and parameter validation; not CLI overrides for the bank.
|
|
343
|
+
- `react_manip/suites/piperx_candidates_v1/`: the only maintained candidate bank, containing task instances and Episodes.
|
|
344
|
+
- `assets/`: scene textures and locally generated robot assets. Generated `provenance.json` records robot source versions and hashes.
|
|
345
|
+
|
|
346
|
+
Fixed instances validate source code, TaskSpecs, parameter contracts, compiled models, controllers, and dependency versions. Changing runtime Python/XML invalidates the recorded identity by design. Do not manually bypass validation by replacing hashes. Verified release migrations are recorded in `generation.json`. Write run outputs to new paths under `outputs/`; development tools and historical outputs are not distributed.
|
|
347
|
+
|
|
348
|
+
`rope_hang` starts with the chain draped over the bar. The task is to catch the slipping chain, redistribute its hanging lengths, release it, and maintain stable suspension. Its three candidates and 45 episodes were regenerated for this scene (TaskSpec 3.0 / contract 2.0). Old table-start selections must be redrawn; scores from the old and new scenes are not directly comparable.
|
|
349
|
+
|
|
350
|
+
Fixed dual PiPER-X `conveyor_grasp` uses two side tables. Bin centers are `(1.25,0.50,0.76)`, `(2.75,0.50,0.76)`, `(1.25,0.90,0.76)`, and `(2.75,0.90,0.76)` meters, using the first two, three, or four bins according to category count. This layout avoids initial arm/base interference. Its three groups and 45 episodes were rebuilt (TaskSpec 3.0 / contract 2.0); do not reuse selections from the previous layout.
|
|
351
|
+
|
|
352
|
+
Python imports now use `react_manip.*` instead of `benchmark.*`, and the bank lives under `react_manip/suites/piperx_candidates_v1/`. There is no compatibility alias for the old package. Update external-policy imports and draw a new selection. The PiPER-X migration reconstructs initial simulation states with each task’s configured robot and camera contract 3.0. pip packaging remains future work.
|
|
353
|
+
|
|
354
|
+
### Rebuild saved instances
|
|
355
|
+
|
|
356
|
+
The single active bank has 48 Task Instances and 720 Episodes, including three candidates and 45 Episodes for `phone_lean`; the four closed-loop parameter-adaptation tasks contribute 180 Episodes with explicit variations. Rebuilding compiles each Episode's resolved model, captures a fresh initial state, verifies its model/controller/source identity, restores the state exactly, and advances one zero-action step. This verifies replay compatibility, not robot task solvability. IDs and round plans are retained. Existing variations are preserved on subsequent rebuilds; old records without variations are migrated by the sampler. Generation reports record language samples and task-specific physical evidence.
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
python scripts/regenerate_instance_bank.py \
|
|
360
|
+
--source react_manip/suites/piperx_candidates_v1/bank.json \
|
|
361
|
+
--out outputs/rebuilt_piperx_bank
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Use a new output directory. The script rebuilds task/episode records and the candidate manifest with linked digests. Evaluate its `bank.json` to draw a fresh 16-task manifest; do not reuse old selected manifests.
|
|
365
|
+
|
|
366
|
+
Language is owned by each task’s `env.py` through `get_episode_language_prompt()`. The adapter refreshes it after reset and every step and supplies `info["language_prompt"]` and `info["language_prompt_structured"]` to the policy. Structured fields separate `task_instruction` from `round_instruction` and `round_index` (zero-based, or null when no round is active). Missing runtime interfaces fail explicitly; task JSON is not a language fallback.
|
|
367
|
+
|
|
368
|
+
The drawer search task (`find_object_in_drawer2`) accepts either arm or both arms together. Both pose commands and both grippers are active. Its fixed rules, current-round instructions, constraints and end statuses are English-only; all five ordered placements still share 600 seconds and earn 20 points each.
|
|
369
|
+
|
|
370
|
+
## Geometry ground-truth Feature interface (debugging only)
|
|
371
|
+
|
|
372
|
+
Geometry Features are an internal, read-only channel used only for local debugging and diagnostics. They are obtained through [`GeometryFeatureAdapter`](react_manip/core/geometry.py), separately from public policy observations. Do not expose these privileged Features to a benchmark policy or use them for benchmark evaluation or scoring.
|
|
373
|
+
|
|
374
|
+
Adapters read the compiled MuJoCo model, simulation data, and task-owned read-only state. Extraction must not advance physics, change `qpos`/`qvel`, or alter scoring and dwell timers. Body poses use world coordinates, meters, and MuJoCo `(w, x, y, z)` quaternions. Velocity fields use SI units; matrices, local coordinates, and fields explicitly suffixed `_deg` retain their task-defined conventions. Check field definitions instead of treating every numeric array as a pose.
|
|
375
|
+
|
|
376
|
+
The stable top-level schema is:
|
|
377
|
+
|
|
378
|
+
```text
|
|
379
|
+
{
|
|
380
|
+
"schema_version": "geometry.v1",
|
|
381
|
+
"entities": {"<entity name>": ...},
|
|
382
|
+
"relations": {"<relation name>": ...},
|
|
383
|
+
"task_state": {...},
|
|
384
|
+
"validity_mask": {...}
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Entity contents and array sizes vary by task; some entries are lists of objects. The validity mask describes the adapter's reported entities, not a universal sensor-quality certificate. Geometry diagnostic fields are not the scoring authority: use the task's declared final `info[score_key]` and terminal feedback for evaluation.
|
|
389
|
+
|
|
390
|
+
### Debugging example
|
|
391
|
+
|
|
392
|
+
Keep the returned environment wrapper for `reset()` and `step()`, and unwrap it only to select the task's geometry adapter. This minimal internal debugging example uses the button task and one zero-action transition; it is not a solving policy or a scored evaluation:
|
|
393
|
+
|
|
394
|
+
```python
|
|
395
|
+
import numpy as np
|
|
396
|
+
from react_manip.builtin import discover_task_definitions
|
|
397
|
+
from react_manip.core import GeometryFeatureAdapter, normalize_reset, normalize_step
|
|
398
|
+
from react_manip.core.compatibility import resolve_task_robot
|
|
399
|
+
|
|
400
|
+
spec, factory = next(
|
|
401
|
+
(spec, factory) for spec, factory in discover_task_definitions()
|
|
402
|
+
if spec.task_id == "button_indicator_matching"
|
|
403
|
+
)
|
|
404
|
+
robot_id = resolve_task_robot(spec)
|
|
405
|
+
env = factory(seed=0, robot_id=robot_id,
|
|
406
|
+
has_offscreen_renderer=False, use_camera_obs=False)
|
|
407
|
+
try:
|
|
408
|
+
observation, info = normalize_reset(env.reset())
|
|
409
|
+
task_env = getattr(env, "env", env)
|
|
410
|
+
adapter = GeometryFeatureAdapter.for_task(task_env)
|
|
411
|
+
before = adapter.extract()
|
|
412
|
+
transition = normalize_step(env.step(np.zeros(env.action_dim)))
|
|
413
|
+
after = adapter.extract()
|
|
414
|
+
record = {
|
|
415
|
+
"task_id": spec.task_id,
|
|
416
|
+
"robot_id": robot_id,
|
|
417
|
+
"scenario_id": getattr(getattr(env, "scenario", None), "scenario_id", None),
|
|
418
|
+
"simulation_time_s": float(task_env.sim.data.time),
|
|
419
|
+
"features": after,
|
|
420
|
+
"reward": transition.reward,
|
|
421
|
+
"terminated": transition.terminated,
|
|
422
|
+
"truncated": transition.truncated,
|
|
423
|
+
}
|
|
424
|
+
finally:
|
|
425
|
+
env.close()
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
Extract a fresh snapshot after each step and align it with that transition's action, public observation, language, feedback, and simulation timestamp. For reproducible debugging, also record Task/Episode IDs, scenario and runtime digests, phase, step index, schema version, and camera IDs when images are enabled. NumPy arrays require an array-capable storage format or explicit conversion before JSON serialization. The example disables RGB; enable the documented camera interface on the same environment when debugging with images.
|
|
429
|
+
|
|
430
|
+
Keep privileged Features in a separate debugging record. Do not use robosuite's concatenated `object-state` as a cross-task schema, and do not pass an unfiltered raw observation directly to a public policy. The runner applies [`policy_observation` and `policy_info`](react_manip/core/observation.py); declared legacy privileged keys are filtered, and geometry truth requires an explicit internal opt-in that must be used only for debugging. Public candidate-bank evaluation rejects `requires_geometry_truth=True`. `--trace-dir` records the public evaluation stream; use this interface only for separate local diagnostics. The current contracts remain task-specific, so debugging code must check which additional state fields are public.
|
|
431
|
+
|
|
432
|
+
### Available adapter entry points
|
|
433
|
+
|
|
434
|
+
These are the adapters currently implemented in this release, not a claim that all 16 tasks expose geometry Features. Most live in [`react_manip/core/geometry.py`](react_manip/core/geometry.py); the drawer-search adapter registers from its task module when that environment is imported.
|
|
435
|
+
|
|
436
|
+
| Task | Adapter | Feature contents |
|
|
437
|
+
| --- | --- | --- |
|
|
438
|
+
| `box_insertion` | `BoxInsertionGeometry` | Block and end-effector geometry, slot bounds, clearance, contact force, and insertion state |
|
|
439
|
+
| `laptop_into_drawer` | `LaptopIntoDrawerGeometry` | Laptop, drawer, handle, and end-effector geometry; containment bounds and relative distances |
|
|
440
|
+
| `find_object_in_drawer2` | `FindObjectInDrawer2Geometry` | Object poses and drawer membership, drawer slides, destination-box bounds, current target, and placement state |
|
|
441
|
+
| `conveyor_grasp` | `ConveyorGraspGeometry` | Object poses, velocities, categories, bins, examples, assignments, and sorting state |
|
|
442
|
+
| `phone_lean` | `PhoneLeanGeometry` | Phone, selected supports, and end-effector poses; relative positions and diagnostic distance/height fields |
|
|
443
|
+
| `pitch_pot` | `PitchPotGeometry` | Projectile pose/velocity, pot and tray geometry, relative position, and hit/attempt state |
|
|
444
|
+
| `button_indicator_matching` | `ButtonIndicatorMatchingGeometry` | Buttons, indicator labels and states, hidden wiring, current target, raw score, and events |
|
|
445
|
+
|
|
446
|
+
For a new task, subclass `GeometryFeatureAdapter`, register its task ID with `@GeometryFeatureAdapter.register("my_task")`, implement `extract()` using `_result(...)`, and declare the field semantics and visibility in TaskSpec. Add reset/step checks for shapes, validity, and read-only behavior. Debugging code must report a missing adapter explicitly rather than inventing a generic geometry view. Existing registration does not require a task-specific branch in the runner or Pygame frontend.
|