Devin commited on
Commit
f4ec55f
·
1 Parent(s): 33ffc04

Add README.md and config.json with architecture/metadata

Browse files
Files changed (2) hide show
  1. README.md +200 -0
  2. config.json +99 -0
README.md ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ tags:
3
+ - marl
4
+ - multi-agent-reinforcement-learning
5
+ - ppo
6
+ - ipppo
7
+ - isaac-sim
8
+ - world-model
9
+ - cosmos3
10
+ - dreamdojo
11
+ - warehouse-robotics
12
+ - cube-sorting
13
+ - so-101
14
+ - lerobot
15
+ license: apache-2.0
16
+ library_name: custom
17
+ ---
18
+
19
+ # MARL + World Model for Warehouse Cube Sorting in Isaac Sim
20
+
21
+ **Independent PPO (IPPO) multi-agent policies with a pluggable world-model wrapper for color-coded cube sorting in NVIDIA Isaac Sim, with an SO-101 robot bridge and LeRobot export.**
22
+
23
+ This is a research demo that trains 2–4 differential-drive mobile manipulators to pick red, green and blue cubes and place them in matching bins. Each agent has its own on-board RGB camera and a continuous 4-D action space. A learned world model can optionally generate imagined rollouts for data augmentation; on this Windows workstation it falls back to a tiny mock dynamics network when the Cosmos3 / DreamDojo backends are not available.
24
+
25
+ ## What it is
26
+
27
+ - **Scenario:** warehouse floor with colored cubes and matching bins.
28
+ - **Agents:** 2–4 small robots with onboard 128×128 RGB cameras and a sticky gripper.
29
+ - **Algorithm:** Independent Proximal Policy Optimisation (IPPO) — one PPO actor-critic per agent.
30
+ - **World model:** pluggable `mock` / `cosmos3` / `dreamdojo` backend that predicts the next observation + reward.
31
+ - **Sim-to-real bridge:** `so101_bridge.py` extracts one agent’s policy and deploys it on a real SO-101 6-DOF arm.
32
+ - **Dataset export:** `convert_to_lerobot.py` turns rollouts into LeRobot v2.1 format for warm-starting GR00T / SmolVLA policies.
33
+
34
+ ## Model architecture
35
+
36
+ The per-agent policy is a CNN+MLP actor-critic defined in `marl_ippo.py`. Full metadata is in [`config.json`](config.json).
37
+
38
+ | Component | Value |
39
+ |---|---|
40
+ | Number of agents | 2 (configurable up to 4) |
41
+ | Observation image | 128 × 128 RGB, stored as `(C, H, W) = (3, 128, 128)` |
42
+ | State dimension | 12 |
43
+ | State vector | `[x, y, yaw, vx, vy, omega, nearest_cube_dx, nearest_cube_dy, nearest_cube_dist, target_bin_dx, target_bin_dy, target_bin_dist]` |
44
+ | Action space | Continuous 4-D in `[-1, 1]`: `[forward, lateral, angular, gripper]` |
45
+ | Image encoder | 3 stride-2 conv layers `(32, 64, 64)` + `AdaptiveAvgPool2d(4, 4)` |
46
+ | Shared MLP | `conv_flat + state_dim -> 256 -> 256` with ReLU |
47
+ | Value head | `256 -> 1` |
48
+ | Actor head | `256 -> 4` Gaussian mean + log-std (continuous) |
49
+ | Hidden size | 256 |
50
+ | Default PPO | `lr=3e-4, gamma=0.99, gae_lambda=0.95, clip_eps=0.2, update_epochs=4, batch_size=64` |
51
+
52
+ ## Files in this repo
53
+
54
+ | File | Purpose |
55
+ |---|---|
56
+ | `env_multi_agent_isaac.py` | Multi-agent Isaac Sim warehouse scene (robots, cubes, bins, cameras, rewards, headless D3D12). |
57
+ | `marl_ippo.py` | Independent PPO policy and trainer (`SimpleActorCritic`, `PPOAgent`, `IPPOTrainer`). |
58
+ | `world_model.py` | Pluggable world-model wrapper: `mock` tiny network, `cosmos3` (NIM / direct / subprocess) and `dreamdojo` (direct / subprocess) with transparent fallback. |
59
+ | `run_marl.py` | End-to-end training/evaluation runner with CLI for agents, episodes, world model, imagination, and checkpoints. |
60
+ | `so101_bridge.py` | Deploy one agent from a checkpoint to the SO-101 arm, in `--simulate` or `--deploy` mode. |
61
+ | `convert_to_lerobot.py` | Convert saved rollouts or a checkpoint into LeRobot v2.1 parquet+video datasets. |
62
+ | `DESIGN.md` | Original architecture and scenario design document. |
63
+ | `AGENTS.md` | Canonical map of the broader H:\Robotics physical-AI workspace. |
64
+ | `outputs/checkpoints/` | Trained IPPO checkpoints, e.g. `marl_ippo_ep100.pt` (Git-LFS). |
65
+ | `outputs/logs/marl_runs.jsonl` | Per-episode reward and timing logs. |
66
+ | `config.json` | Model-card style metadata (shapes, hyperparameters, backend list). |
67
+ | `README.md` | This file. |
68
+
69
+ ## Installation
70
+
71
+ 1. **Clone this repo**
72
+
73
+ ```bash
74
+ git clone https://huggingface.co/Ryukijano/marl-world-model
75
+ cd marl-world-model
76
+ ```
77
+
78
+ 2. **NVIDIA Isaac Sim**
79
+
80
+ The code is tested with **Isaac Sim 5.1.0** standalone and the **Isaac Sim 6.0.1 pip** environment.
81
+
82
+ - **5.1.0 standalone:** use the bundled `python.bat` (e.g. `H:\Robotics\ISSAC_SIM_5.1.0\python.bat`).
83
+ - **6.0.1 pip:** create/activate the `isaac-sim-601` conda env and set `OMNI_KIT_ACCEPT_EULA=YES`.
84
+
85
+ 3. **General Python deps** (for `so101_bridge.py` and `convert_to_lerobot.py`)
86
+
87
+ ```bash
88
+ pip install torch numpy opencv-python pillow imageio requests pandas
89
+ ```
90
+
91
+ 4. **SO-101 / LeRobot deps** (only for real-robot bridge)
92
+
93
+ ```bash
94
+ pip install lerobot
95
+ ```
96
+
97
+ ## How to run
98
+
99
+ All training and simulation commands below use **Isaac Sim 5.1.0**. For the 6.0.1 pip env, replace `H:\Robotics\ISSAC_SIM_5.1.0\python.bat` with `conda run -n isaac-sim-601 python` (and set `OMNI_KIT_ACCEPT_EULA=YES` before running).
100
+
101
+ ### Smoke test
102
+
103
+ ```batch
104
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --smoke --device cpu
105
+ ```
106
+
107
+ This launches the multi-agent scene, takes random actions for a few steps, and saves frames.
108
+
109
+ ### Short IPPO sanity run
110
+
111
+ ```batch
112
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --num-episodes 2 --max-steps-per-episode 30 --batch-size 16 --device cpu
113
+ ```
114
+
115
+ ### Full 100-episode training
116
+
117
+ ```batch
118
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --num-episodes 100 --max-steps-per-episode 200 --batch-size 64 --device cuda --checkpoint-every 20
119
+ ```
120
+
121
+ Checkpoints are written to `outputs/checkpoints/marl_ippo_ep{N}.pt`.
122
+
123
+ ### IPPO with world-model imagination
124
+
125
+ ```batch
126
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --num-episodes 1 --max-steps-per-episode 20 --batch-size 16 --use-imagination --imagination-horizon 5 --device cpu
127
+ ```
128
+
129
+ ### Cosmos3 / DreamDojo backend
130
+
131
+ ```batch
132
+ :: Will try Cosmos3; on Windows it falls back to mock if the backend is unavailable
133
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --num-episodes 1 --max-steps-per-episode 5 --batch-size 4 --world-model cosmos3 --device cpu
134
+
135
+ :: Same for DreamDojo
136
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --num-episodes 1 --max-steps-per-episode 5 --batch-size 4 --world-model dreamdojo --device cpu
137
+ ```
138
+
139
+ ### 4-agent training
140
+
141
+ ```batch
142
+ H:\Robotics\ISSAC_SIM_5.1.0\python.bat run_marl.py --num-agents 4 --num-episodes 1 --max-steps-per-episode 10 --batch-size 8 --device cpu
143
+ ```
144
+
145
+ ## Using the SO-101 bridge
146
+
147
+ The bridge is not run inside Isaac Sim. It loads a single agent from a `marl_ippo_ep*.pt` checkpoint and runs on the SO-101 (or a dummy robot in simulation).
148
+
149
+ ### Simulation mode (no hardware required)
150
+
151
+ ```batch
152
+ conda run -n gr00t python so101_bridge.py --checkpoint outputs/checkpoints/marl_ippo_ep100.pt --simulate --max-steps 20
153
+ ```
154
+
155
+ ### Real hardware mode
156
+
157
+ ```batch
158
+ conda run -n gr00t python so101_bridge.py --checkpoint outputs/checkpoints/marl_ippo_ep100.pt --deploy --follower-port COM7 --cam-idx 0
159
+ ```
160
+
161
+ The bridge preprocesses the camera frame, runs the IPPO policy, and maps the 4-D continuous action to SO-101 joint commands in `--action-mode delta` (default) or `direct`. The first three action components typically map to shoulder/elbow/wrist joints and the last component maps to the gripper.
162
+
163
+ ## Link to the LeRobot dataset
164
+
165
+ Generated rollouts can be exported to the companion LeRobot dataset repo:
166
+
167
+ **[Ryukijano/marl-world-model-lerobot](https://huggingface.co/datasets/Ryukijano/marl-world-model-lerobot)**
168
+
169
+ Create a local LeRobot v2.1 dataset from the trained policy:
170
+
171
+ ```batch
172
+ conda run -n gr00t python convert_to_lerobot.py --checkpoint outputs/checkpoints/marl_ippo_ep100.pt --num-episodes 10 --episode-length 200 --output-dir so101_marl_dataset --task "pick up the cube"
173
+ ```
174
+
175
+ You can then upload `so101_marl_dataset` to the LeRobot repo above for GR00T / SmolVLA fine-tuning.
176
+
177
+ ## Known limitations
178
+
179
+ - **Cosmos3 / DreamDojo on Windows:** these backends require Linux-native Cosmos / DreamDojo installs or a running NIM HTTP server. On the Windows development workstation they transparently fall back to the `mock` tiny world model.
180
+ - **100 episodes is not enough for full cube sorting:** the runs are intended as a proof-of-concept. Reliable sorting will need far more episodes / curriculum / fine-tuning.
181
+ - **Isaac Sim 5.1.0 headless:** the renderer runs with D3D12 and `vulkan=false` because the local GPU driver is 595.79. GUI mode may crash.
182
+ - **Shutdown workaround:** `run_marl.py` calls `os._exit(0)` after writing outputs to avoid a known `omni.syntheticdata.plugin.dll` shutdown crash during `Py_FinalizeEx`.
183
+ - **SO-101 mapping is heuristic:** the trained agent has a 4-D base action space, while the SO-101 has 6 joints. The bridge pads/maps actions and uses simple delta or direct control.
184
+ - **Sticky gripper:** cube grasping is approximated by a distance threshold and gripper action > 0.5; there is no explicit articulated gripper in the base environment.
185
+ - **Center-cropped camera images:** 128×128 frames are cropped/padded from the raw camera output.
186
+
187
+ ## License and citation
188
+
189
+ This repository is released under the **Apache-2.0 License**. Please check individual third-party dependencies (Isaac Sim, LeRobot, Cosmos, DreamDojo) for their respective licenses.
190
+
191
+ If you use this code in your research, please cite it as:
192
+
193
+ ```bibtex
194
+ @software{ryukijano_marl_world_model,
195
+ title={MARL + World Model for Warehouse Cube Sorting in Isaac Sim},
196
+ author={Ryukijano},
197
+ year={2026},
198
+ url={https://huggingface.co/Ryukijano/marl-world-model}
199
+ }
200
+ ```
config.json ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_type": "marl-ippo-actor-critic",
3
+ "name": "MARL IPPO Warehouse Cube Sorting Policy",
4
+ "description": "Independent PPO policies for 2-4 mobile warehouse robots in NVIDIA Isaac Sim, with optional world-model imagination.",
5
+ "task": "multi-agent-warehouse-cube-sorting",
6
+ "simulator": {
7
+ "name": "NVIDIA Isaac Sim",
8
+ "versions_tested": ["5.1.0", "6.0.1 pip"],
9
+ "headless": true,
10
+ "renderer": "D3D12"
11
+ },
12
+ "num_agents": 2,
13
+ "observation": {
14
+ "image": {
15
+ "shape": [3, 128, 128],
16
+ "dtype": "uint8",
17
+ "description": "RGB camera image per agent, stored/transposed to CHW for the policy network."
18
+ },
19
+ "state": {
20
+ "shape": [12],
21
+ "dtype": "float32",
22
+ "description": "[x, y, yaw, vx, vy, omega, nearest_cube_dx, nearest_cube_dy, nearest_cube_dist, target_bin_dx, target_bin_dy, target_bin_dist]"
23
+ }
24
+ },
25
+ "action_space": {
26
+ "type": "continuous",
27
+ "shape": [4],
28
+ "low": -1.0,
29
+ "high": 1.0,
30
+ "description": "[forward, lateral, angular, gripper]",
31
+ "gripper_threshold": 0.5
32
+ },
33
+ "policy": {
34
+ "algorithm": "IPPO",
35
+ "architecture": {
36
+ "image_encoder": {
37
+ "type": "CNN",
38
+ "input_shape": [3, 128, 128],
39
+ "conv_layers": [
40
+ {"in_channels": 3, "out_channels": 32, "kernel_size": 3, "stride": 2, "padding": 1},
41
+ {"in_channels": 32, "out_channels": 64, "kernel_size": 3, "stride": 2, "padding": 1},
42
+ {"in_channels": 64, "out_channels": 64, "kernel_size": 3, "stride": 2, "padding": 1}
43
+ ],
44
+ "pooling": "AdaptiveAvgPool2d(4, 4)"
45
+ },
46
+ "shared_mlp": {
47
+ "input_dim": "conv_flat + state_dim",
48
+ "hidden_dim": 256,
49
+ "num_layers": 2,
50
+ "activation": "ReLU"
51
+ },
52
+ "value_head": {"input_dim": 256, "output_dim": 1},
53
+ "actor_head": {
54
+ "type": "gaussian",
55
+ "input_dim": 256,
56
+ "output_dim": 4
57
+ },
58
+ "state_dim": 12,
59
+ "hidden_dim": 256,
60
+ "cnn_channels": [32, 64, 64],
61
+ "reduce_spatial": 4
62
+ },
63
+ "hyperparameters": {
64
+ "lr": 3e-4,
65
+ "gamma": 0.99,
66
+ "gae_lambda": 0.95,
67
+ "clip_eps": 0.2,
68
+ "value_loss_coef": 0.5,
69
+ "entropy_coef": 0.01,
70
+ "update_epochs": 4,
71
+ "batch_size": 64,
72
+ "max_grad_norm": 0.5,
73
+ "normalize_advantages": true
74
+ }
75
+ },
76
+ "world_model": {
77
+ "backends": ["mock", "cosmos3", "dreamdojo"],
78
+ "default": "mock",
79
+ "fallback_to_mock": true,
80
+ "imagination_horizon_default": 20
81
+ },
82
+ "so101_bridge": {
83
+ "input_image_size": [128, 128],
84
+ "state_dim_policy": 12,
85
+ "action_mode": "delta",
86
+ "max_delta": 0.05,
87
+ "joint_keys": [
88
+ "shoulder_pan.pos",
89
+ "shoulder_lift.pos",
90
+ "elbow_flex.pos",
91
+ "wrist_flex.pos",
92
+ "wrist_roll.pos",
93
+ "gripper.pos"
94
+ ]
95
+ },
96
+ "lerobot_dataset_repo": "Ryukijano/marl-world-model-lerobot",
97
+ "source_repo": "Ryukijano/marl-world-model",
98
+ "license": "apache-2.0"
99
+ }