physicalai-mujoco-so101-plugin 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.
- physicalai_mujoco_so101_plugin-0.1.0/.gitignore +219 -0
- physicalai_mujoco_so101_plugin-0.1.0/PKG-INFO +285 -0
- physicalai_mujoco_so101_plugin-0.1.0/README.md +259 -0
- physicalai_mujoco_so101_plugin-0.1.0/pyproject.toml +56 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/__init__.py +29 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/__main__.py +308 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/_urdf.py +21 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/constants.py +42 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/http_server.py +314 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/mujoco_robot.py +885 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/scene_registry.py +360 -0
- physicalai_mujoco_so101_plugin-0.1.0/src/physicalai_mujoco_so101_plugin/studio_catalog.py +261 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/garment_fold/scene.xml +30 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/garment_fold_mesh/mini.xml +11 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/garment_fold_mesh/scene.xml +30 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/garment_fold_mesh/scene_base.xml +30 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/garment_fold_mesh/scene_e.xml +30 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/garment_fold_mesh/scene_self.xml +30 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/pick_lift/scene.xml +27 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/pick_place/scene.xml +23 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/single_pick_place/scene.xml +23 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/cup.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_atlas.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_cube.obj +88 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_face_1.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_face_2.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_face_3.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_face_4.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_face_5.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/die_face_6.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/wood1.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/wood4.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/wood5.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/assets/wood_floor.png +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/scenes/yahtzee/scene.xml +67 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/base_motor_holder_so101_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/base_motor_holder_so101_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/base_so101_v2.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/base_so101_v2.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/garment_PL_019.obj +1642 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/motor_holder_so101_base_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/motor_holder_so101_base_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/motor_holder_so101_wrist_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/motor_holder_so101_wrist_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/moving_jaw_so101_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/moving_jaw_so101_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/rotation_pitch_so101_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/rotation_pitch_so101_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/sts3215_03a_no_horn_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/sts3215_03a_no_horn_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/sts3215_03a_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/sts3215_03a_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/under_arm_so101_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/under_arm_so101_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/upper_arm_so101_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/upper_arm_so101_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/waveshare_mounting_plate_so101_v2.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/waveshare_mounting_plate_so101_v2.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/wrist_roll_follower_so101_v1.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/wrist_roll_follower_so101_v1.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/wrist_roll_pitch_so101_v2.part +14 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/assets/wrist_roll_pitch_so101_v2.stl +0 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/so101.xml +189 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/so101_dual.urdf +877 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/so101_new_calib.urdf +453 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/so101_robot_bodies.xml +89 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101/so101_robot_config.xml +75 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101_dual/so101_dual_robot_bodies.xml +154 -0
- physicalai_mujoco_so101_plugin-0.1.0/urdf/so101_dual/so101_dual_robot_config.xml +81 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# mkdocs documentation
|
|
162
|
+
/site
|
|
163
|
+
|
|
164
|
+
# mypy
|
|
165
|
+
.mypy_cache/
|
|
166
|
+
.dmypy.json
|
|
167
|
+
dmypy.json
|
|
168
|
+
|
|
169
|
+
# Pyre type checker
|
|
170
|
+
.pyre/
|
|
171
|
+
|
|
172
|
+
# pytype static type analyzer
|
|
173
|
+
.pytype/
|
|
174
|
+
|
|
175
|
+
# Cython debug symbols
|
|
176
|
+
cython_debug/
|
|
177
|
+
|
|
178
|
+
# PyCharm
|
|
179
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
180
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
181
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
182
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
183
|
+
.idea/
|
|
184
|
+
|
|
185
|
+
# Abstra
|
|
186
|
+
# Abstra is an AI-powered process automation framework.
|
|
187
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
188
|
+
# Learn more at https://abstra.io/docs
|
|
189
|
+
.abstra/
|
|
190
|
+
|
|
191
|
+
# Visual Studio Code
|
|
192
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
193
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
194
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
195
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
196
|
+
.vscode/
|
|
197
|
+
|
|
198
|
+
# Ruff stuff:
|
|
199
|
+
.ruff_cache/
|
|
200
|
+
|
|
201
|
+
# PyPI configuration file
|
|
202
|
+
.pypirc
|
|
203
|
+
|
|
204
|
+
# Marimo
|
|
205
|
+
marimo/_static/
|
|
206
|
+
marimo/_lsp/
|
|
207
|
+
__marimo__/
|
|
208
|
+
|
|
209
|
+
# Streamlit
|
|
210
|
+
.streamlit/secrets.toml
|
|
211
|
+
|
|
212
|
+
# Misc
|
|
213
|
+
.DS_Store
|
|
214
|
+
|
|
215
|
+
# MuJoCo runtime logs
|
|
216
|
+
MUJOCO_LOG.TXT
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
tmp/
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: physicalai-mujoco-so101-plugin
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MuJoCo SO-101 simulation plugin for PhysicalAI Studio
|
|
5
|
+
Project-URL: Homepage, https://github.com/MarkRedeman/physicalai-plugins
|
|
6
|
+
Project-URL: Repository, https://github.com/MarkRedeman/physicalai-plugins
|
|
7
|
+
Project-URL: Issues, https://github.com/MarkRedeman/physicalai-plugins/issues
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Requires-Dist: defusedxml>=0.7.1
|
|
11
|
+
Requires-Dist: fastapi>=0.115
|
|
12
|
+
Requires-Dist: loguru>=0.7
|
|
13
|
+
Requires-Dist: mujoco>=3.1.0
|
|
14
|
+
Requires-Dist: numpy>=1.24
|
|
15
|
+
Requires-Dist: opencv-python-headless>=4.10
|
|
16
|
+
Requires-Dist: physicalai-studio-plugin
|
|
17
|
+
Requires-Dist: physicalai[transport]>=0.1.1
|
|
18
|
+
Requires-Dist: pydantic>=2.0
|
|
19
|
+
Requires-Dist: pyfakewebcam>=0.1.0
|
|
20
|
+
Requires-Dist: uvicorn>=0.30
|
|
21
|
+
Provides-Extra: tests
|
|
22
|
+
Requires-Dist: httpx>=0.27; extra == 'tests'
|
|
23
|
+
Requires-Dist: pytest; extra == 'tests'
|
|
24
|
+
Requires-Dist: pytest-asyncio; extra == 'tests'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# PhysicalAI MuJoCo SO-101 Plugin
|
|
28
|
+
|
|
29
|
+
MuJoCo SO-101 simulation plugin for PhysicalAI Studio. Part of the [physicalai-plugins](https://github.com/MarkRedeman/physicalai-plugins) monorepo.
|
|
30
|
+
|
|
31
|
+
This plugin lets you run a virtual SO-101 robot as a PhysicalAI transport owner, then connect to it from Studio exactly like real hardware.
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- Run a virtual SO-101 as a PhysicalAI transport owner
|
|
36
|
+
- MuJoCo interactive viewer
|
|
37
|
+
- Camera streams over HTTP (MJPEG) and optional v4l2loopback
|
|
38
|
+
- REST control server (scenes, reset, shutdown)
|
|
39
|
+
- Built-in task scenes
|
|
40
|
+
|
|
41
|
+
## Screenshots
|
|
42
|
+
|
|
43
|
+
_Placeholder images — replace them with real screenshots._
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
## What this is for
|
|
54
|
+
|
|
55
|
+
- Teleoperating a virtual SO-101 from PhysicalAI Studio.
|
|
56
|
+
- Testing robot setup, task logic, and control flows without physical hardware.
|
|
57
|
+
- Playing back policy/inference outputs in a simulated scene while monitoring robot + camera streams.
|
|
58
|
+
- Developing workflows where Studio, transport, and robot APIs stay identical between sim and real deployments.
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
From the repo root:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv run --no-sync physicalai-mujoco-so101 start
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
By default this starts:
|
|
69
|
+
|
|
70
|
+
- A MuJoCo SO-101 owner named `mujoco-so101`
|
|
71
|
+
- Viewer window enabled
|
|
72
|
+
- Camera streams served over HTTP (MJPEG + REST control server on port `8080`)
|
|
73
|
+
- Control rate `50 Hz`
|
|
74
|
+
- Substeps `10`
|
|
75
|
+
|
|
76
|
+
Then open PhysicalAI Studio and connect to the robot type `MuJoCo SO-101 Follower` with name `mujoco-so101`.
|
|
77
|
+
|
|
78
|
+
### CLI teleoperation (self-relay)
|
|
79
|
+
|
|
80
|
+
With the owner running, you can also relay the simulation back to itself using
|
|
81
|
+
the [PhysicalAI CLI](https://github.com/openvinotoolkit/physicalai):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uv run physicalai run --config packages/physicalai-mujoco-so101-plugin/examples/runtime/teleop.yaml
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Press `Ctrl+C` to stop.
|
|
88
|
+
|
|
89
|
+
View the camera streams in a browser or with `curl`:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
curl http://127.0.0.1:8080/health
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
MJPEG stream URLs are `http://127.0.0.1:8080/cameras/<name>/mjpeg` (e.g. open
|
|
96
|
+
`http://127.0.0.1:8080/cameras/overview/mjpeg` in a browser, or play it in VLC).
|
|
97
|
+
|
|
98
|
+
## CLI options
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run --no-sync physicalai-mujoco-so101 start --help
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Common options:
|
|
105
|
+
|
|
106
|
+
- `--name <robot-name>`: transport name (must match Studio payload)
|
|
107
|
+
- `--model <path>`: custom XML/URDF path (bypasses scene resolution)
|
|
108
|
+
- `--scene <name>`: scene name (`single_pick_place`, `pick_lift`, `pick_place`, or `yahtzee`, default `single_pick_place`)
|
|
109
|
+
- `--no-gui`: disable MuJoCo interactive viewer
|
|
110
|
+
- `--no-cameras`: disable camera rendering entirely (HTTP streams and v4l2loopback)
|
|
111
|
+
- `--http-host <host>`: host for the camera/control HTTP server (default `127.0.0.1`)
|
|
112
|
+
- `--http-port <port>`: port for the camera/control HTTP server (default `8080`)
|
|
113
|
+
- `--no-http`: disable the camera/control HTTP server
|
|
114
|
+
- `--v4l2`: also publish cameras to v4l2loopback devices (requires `modprobe v4l2loopback`)
|
|
115
|
+
- `--rate-hz <float>`: owner loop frequency
|
|
116
|
+
- `--substeps <int>`: MuJoCo steps per control cycle
|
|
117
|
+
- `--idle-timeout <seconds>`: seconds with zero subscribers before self-exit
|
|
118
|
+
(default `10` without HTTP, disabled when HTTP is enabled so stream viewers keep the sim alive)
|
|
119
|
+
- `--allow-remote`: allow non-loopback zenoh connections
|
|
120
|
+
|
|
121
|
+
## Cameras over HTTP (default)
|
|
122
|
+
|
|
123
|
+
The plugin renders two camera feeds and serves them over HTTP:
|
|
124
|
+
|
|
125
|
+
- `wrist` -> `http://127.0.0.1:8080/cameras/wrist/mjpeg`
|
|
126
|
+
- `overview` -> `http://127.0.0.1:8080/cameras/overview/mjpeg`
|
|
127
|
+
|
|
128
|
+
Each camera is also available as a single JPEG snapshot at
|
|
129
|
+
`http://127.0.0.1:8080/cameras/<name>/frame.jpg`.
|
|
130
|
+
|
|
131
|
+
### REST control API
|
|
132
|
+
|
|
133
|
+
The HTTP server exposes control endpoints for resetting and switching scenes:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# List available scenes and the current one
|
|
137
|
+
curl http://127.0.0.1:8080/scenes
|
|
138
|
+
|
|
139
|
+
# Switch to another scene
|
|
140
|
+
curl -X POST http://127.0.0.1:8080/scenes/pick_place
|
|
141
|
+
|
|
142
|
+
# Reset/randomize the current scene
|
|
143
|
+
curl -X POST http://127.0.0.1:8080/reset
|
|
144
|
+
|
|
145
|
+
# Stop the simulation owner
|
|
146
|
+
curl -X POST http://127.0.0.1:8080/shutdown
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Endpoint | Method | Description |
|
|
150
|
+
| --------------------------- | ------ | --------------------------------------------- |
|
|
151
|
+
| `/` | GET | Service info, endpoint index |
|
|
152
|
+
| `/health` | GET | Sim status: connected, current scene, cameras |
|
|
153
|
+
| `/cameras` | GET | Camera list with stream/snapshot URLs |
|
|
154
|
+
| `/cameras/{name}/mjpeg` | GET | MJPEG stream (`multipart/x-mixed-replace`) |
|
|
155
|
+
| `/cameras/{name}/frame.jpg` | GET | Latest frame as a JPEG snapshot |
|
|
156
|
+
| `/scenes` | GET | Current scene and available scene IDs |
|
|
157
|
+
| `/scenes/{scene_id}` | POST | Switch to another registered scene |
|
|
158
|
+
| `/reset` | POST | Reset/randomize the current scene |
|
|
159
|
+
| `/shutdown` | POST | Gracefully stop the simulation owner |
|
|
160
|
+
|
|
161
|
+
Because the owner process is detached, stopping the CLI with `Ctrl+C` does not
|
|
162
|
+
stop the simulation. Use `POST /shutdown`, `--idle-timeout`, or kill the owner
|
|
163
|
+
process directly.
|
|
164
|
+
|
|
165
|
+
## Cameras and v4l2loopback (opt-in)
|
|
166
|
+
|
|
167
|
+
For workflows that need a webcam-visible device, pass `--v4l2` to publish the
|
|
168
|
+
same camera feeds to v4l2loopback devices:
|
|
169
|
+
|
|
170
|
+
- `wrist` -> `/dev/video<wrist-video-id>` (default `/dev/video60`)
|
|
171
|
+
- `overview` -> `/dev/video<overview-video-id>` (default `/dev/video62`)
|
|
172
|
+
|
|
173
|
+
Example with custom IDs:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
uv run --no-sync physicalai-mujoco-so101 start --v4l2 --wrist-video-id 70 --overview-video-id 71
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### One-time setup (Linux)
|
|
180
|
+
|
|
181
|
+
Install and load v4l2loopback:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
sudo modprobe v4l2loopback exclusive_caps=1 video_nr=60,61
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
If you use custom camera IDs, use matching `video_nr` values. Example:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
sudo modprobe v4l2loopback exclusive_caps=1 video_nr=70,71
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
If the module is already loaded with different params, unload and reload:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
sudo rmmod v4l2loopback
|
|
197
|
+
sudo modprobe v4l2loopback exclusive_caps=1 video_nr=60,61
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Verify devices
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
ls /dev/video60 /dev/video61
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
For custom IDs, verify those device nodes instead.
|
|
207
|
+
|
|
208
|
+
Optional sanity checks:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
v4l2-ctl --all -d /dev/video60
|
|
212
|
+
v4l2-ctl --all -d /dev/video61
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Troubleshooting
|
|
216
|
+
|
|
217
|
+
### HTTP server unavailable or port already in use
|
|
218
|
+
|
|
219
|
+
- The camera/control server binds to `--http-host`/`--http-port` (default `127.0.0.1:8080`).
|
|
220
|
+
- If the port is taken the simulation continues without HTTP and logs a warning — pass a different `--http-port`.
|
|
221
|
+
- When running multiple simulations, give each a distinct `--http-port`.
|
|
222
|
+
|
|
223
|
+
### `Camera '<name>' unavailable` or invalid argument on `/dev/video*` (with `--v4l2`)
|
|
224
|
+
|
|
225
|
+
- Ensure v4l2loopback is loaded with `exclusive_caps=1`
|
|
226
|
+
- Ensure the configured video devices exist (default `/dev/video60`, `/dev/video62`)
|
|
227
|
+
- Check permissions on device nodes
|
|
228
|
+
|
|
229
|
+
### Viewer opens but has Wayland warnings (`libdecor`, window position)
|
|
230
|
+
|
|
231
|
+
These warnings are typically non-fatal on Wayland and can be ignored if simulation continues.
|
|
232
|
+
|
|
233
|
+
### Camera/control server is not started
|
|
234
|
+
|
|
235
|
+
- Confirm the sim is running and the port is free: `curl http://127.0.0.1:8080/health`
|
|
236
|
+
- `--no-http` or `--http-port 0` disables the server; `--no-cameras` disables all camera rendering
|
|
237
|
+
|
|
238
|
+
## Using with Studio teleop and inference playback
|
|
239
|
+
|
|
240
|
+
Typical workflow:
|
|
241
|
+
|
|
242
|
+
1. Start simulation owner: `physicalai-mujoco-so101 start`
|
|
243
|
+
2. Connect from PhysicalAI Studio (`MuJoCo SO-101 Follower`)
|
|
244
|
+
3. Teleoperate in Studio and observe state/cameras
|
|
245
|
+
4. Run policy inference and play action outputs into the same simulated robot
|
|
246
|
+
|
|
247
|
+
Because this uses PhysicalAI transport + Studio catalog integration, you can iterate on control and inference loops in simulation before moving to hardware.
|
|
248
|
+
|
|
249
|
+
## Scenes
|
|
250
|
+
|
|
251
|
+
The plugin ships with built-in scenes that provide different environments for the robot:
|
|
252
|
+
|
|
253
|
+
| Scene ID | Description | Free objects | Target |
|
|
254
|
+
| ----------------------------- | ------------------------------------- | --------------- | ----------- |
|
|
255
|
+
| `single_pick_place` (default) | One block and a target disc | 1 cube | target disc |
|
|
256
|
+
| `pick_lift` | Three colored cubes and a target disc | 3 cubes | target disc |
|
|
257
|
+
| `pick_place` | A cube, a cylinder, and a target zone | cube + cylinder | target zone |
|
|
258
|
+
| `yahtzee` | Six dice and a cup | 6 dice | cup |
|
|
259
|
+
|
|
260
|
+
Start with a specific scene:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
uv run --no-sync physicalai-mujoco-so101 start --scene pick_place
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Keyboard shortcut: cycle scenes
|
|
267
|
+
|
|
268
|
+
When the MuJoCo viewer is open, press **`n`** (next scene) to cycle through available scenes. The scene switches at the next control cycle:
|
|
269
|
+
|
|
270
|
+
- Loads the new scene XML
|
|
271
|
+
- Updates the existing viewer with the new environment
|
|
272
|
+
- Resets block joints, target bodies, and spawn parameters
|
|
273
|
+
|
|
274
|
+
`--model` bypasses scene resolution entirely; only the exported scene XML path is loaded, and scene cycling is unavailable.
|
|
275
|
+
|
|
276
|
+
## Current status and future improvements
|
|
277
|
+
|
|
278
|
+
Planned/desired improvements:
|
|
279
|
+
|
|
280
|
+
- More configurable camera presets (pose/FOV/fps via CLI or payload)
|
|
281
|
+
- Scene randomization presets (object layouts, target marker variants, textures)
|
|
282
|
+
- RTSP streaming sink (the frame-buffer plumbing is sink-agnostic; an RTSP
|
|
283
|
+
server such as `aiortsp` or MediaMTX can consume the same buffers later)
|
|
284
|
+
- Optional richer sensor streams (depth/segmentation style outputs)
|
|
285
|
+
- Additional sample tasks and policy playback recipes in this package
|