sim2bot 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,226 @@
1
+ Metadata-Version: 2.4
2
+ Name: sim2bot
3
+ Version: 0.1.0
4
+ Summary: Python client for the Sim2Bot browser robot simulator
5
+ Author-email: Source Robotics <info@source-robotics.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://sim2bot.com/
8
+ Project-URL: Documentation, https://docs.sim2bot.com/
9
+ Project-URL: Source, https://github.com/Source-Robotics/sim2bot-python
10
+ Project-URL: Issues, https://github.com/Source-Robotics/sim2bot-python/issues
11
+ Project-URL: Changelog, https://github.com/Source-Robotics/sim2bot-python/blob/main/CHANGELOG.md
12
+ Keywords: robotics,simulation,mujoco,bridge,sdk
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Scientific/Engineering
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Requires-Python: >=3.9
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: fastapi>=0.110
30
+ Requires-Dist: uvicorn[standard]>=0.29
31
+ Requires-Dist: websockets>=12.0
32
+ Provides-Extra: cv2
33
+ Requires-Dist: opencv-python>=4.5; extra == "cv2"
34
+ Requires-Dist: numpy>=1.21; extra == "cv2"
35
+ Provides-Extra: av
36
+ Requires-Dist: av>=11; extra == "av"
37
+ Requires-Dist: numpy>=1.21; extra == "av"
38
+ Provides-Extra: dev
39
+ Requires-Dist: build>=1.2; extra == "dev"
40
+ Requires-Dist: pytest>=8; extra == "dev"
41
+ Requires-Dist: twine>=5; extra == "dev"
42
+ Dynamic: license-file
43
+
44
+ # sim2bot — Python client for the Sim2Bot simulator
45
+
46
+ [![CI](https://github.com/Source-Robotics/sim2bot-python/actions/workflows/ci.yml/badge.svg)](https://github.com/Source-Robotics/sim2bot-python/actions/workflows/ci.yml)
47
+ [![PyPI](https://img.shields.io/pypi/v/sim2bot.svg)](https://pypi.org/project/sim2bot/)
48
+ [![Python versions](https://img.shields.io/pypi/pyversions/sim2bot.svg)](https://pypi.org/project/sim2bot/)
49
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
50
+
51
+ Control a robot in [Sim2Bot](https://sim2bot.com/) from Python, the same way you
52
+ would talk to a real one: send joint or Cartesian targets, read telemetry, open
53
+ and close a gripper, subscribe to camera feeds.
54
+
55
+ ```python
56
+ from sim2bot import Robot
57
+
58
+ with Robot(auto_bridge=True, wait_for_sim=True) as robot:
59
+ arm = robot.describe()[0]
60
+ robot.move_to(arm.home)
61
+ robot.wait_until_reached(arm.home)
62
+ print(robot.state().q)
63
+ ```
64
+
65
+ ## How the pieces fit
66
+
67
+ Sim2Bot runs the physics (MuJoCo, compiled to WebAssembly) **in your browser**.
68
+ This package talks to that tab through a small local relay — the *bridge* — that
69
+ ships inside the package itself:
70
+
71
+ ```
72
+ your Python script ──► sim2bot bridge (localhost) ──► Sim2Bot tab in your browser
73
+ commands relay only MuJoCo physics
74
+ telemetry ◄── ◄── cameras, sensors
75
+ ```
76
+
77
+ The bridge forwards messages and holds no robot state of its own. Nothing about
78
+ your scene leaves your machine.
79
+
80
+ ## Install
81
+
82
+ ```sh
83
+ pip install sim2bot # control + telemetry
84
+ pip install "sim2bot[cv2]" # + camera frames decoded to numpy images
85
+ ```
86
+
87
+ Python 3.9 or newer.
88
+
89
+ ## First run
90
+
91
+ 1. Run your script. `auto_bridge=True` starts the local bridge if it is not
92
+ already running, and `wait_for_sim=True` waits for the browser.
93
+ 2. Open [app.sim2bot.com](https://app.sim2bot.com/), load a robot, and click
94
+ **Tools → Bridge → Connect**.
95
+
96
+ ```python
97
+ from sim2bot import Robot
98
+
99
+ with Robot(auto_bridge=True, wait_for_sim=True) as robot:
100
+ for info in robot.describe():
101
+ print(f"[{info.index}] {info.name} id={info.id} dof={info.dof}")
102
+ ```
103
+
104
+ `wait_for_sim=True` blocks until a simulator announces at least one robot; pass
105
+ `wait_for_sim_timeout=30` for a finite wait.
106
+
107
+ ## What you can do
108
+
109
+ ```python
110
+ from sim2bot import Robot
111
+
112
+ with Robot() as robot: # ws://localhost:8765/ws
113
+ info = robot.describe() # dof, home, limits, gripper, cameras, ...
114
+ print(info[0].index, info[0].id, info[0].name, info[0].dof)
115
+
116
+ robot.move_to(info[0].home) # joint position target
117
+ robot.set_velocity([0.1] * info[0].dof) # joint velocity target
118
+ robot.move_to_pose([0.45, 0.0, 0.35]) # Cartesian target, solved by browser IK
119
+ robot.move_trajectory([(0.0, q0), (1.5, q1)]) # timed joint trajectory
120
+ robot.stop()
121
+
122
+ state = robot.state()
123
+ print(state.q, state.qd, state.qdd, state.qddd) # position ... jerk
124
+ print(state.tcp, state.tcp_orientation) # TCP position + quaternion
125
+ print(state.tcp_linear_velocity, state.tcp_angular_velocity)
126
+
127
+ if info[0].has_gripper:
128
+ robot.gripper(1.0) # 0.0 closed .. 1.0 open
129
+
130
+ robot.base_velocity(vx=0.4, omega=0.35) # mobile / aerial bases
131
+
132
+ robot.marker("goal", "sphere", position=[0.45, 0, 0.35], scale=0.06)
133
+
134
+ for device in robot.room_devices(): # doors and windows in the scene
135
+ if device.motion == "actuated":
136
+ robot.set_room_opening(device.id, 1.0)
137
+
138
+ for cam in robot.cameras():
139
+ print(cam["id"], cam["label"])
140
+
141
+ with robot.camera("model:0", fps=30) as feed: # codec="raw" for lowest latency
142
+ frame = feed.read(timeout=2.0)
143
+ image = frame.image() # numpy BGR — needs the [cv2] extra
144
+ ```
145
+
146
+ Telemetry and camera reads are **latest-value, drop-don't-queue**: they return
147
+ the present, never a backlog.
148
+
149
+ Robot discovery gives you both `index` and `id`. Address commands by `index`
150
+ (`robot.move_to(q, robot=info.index)`); use `id` to recognise the same scene
151
+ robot across the app and your script.
152
+
153
+ Camera parameters you leave unset (`fps`, `width`, `height`, `quality`, `codec`)
154
+ inherit that camera's setting in the app, so your script overrides the GUI only
155
+ where it says so.
156
+
157
+ Runnable versions of all of this are in [`examples/`](examples/).
158
+
159
+ ## Command line
160
+
161
+ ```sh
162
+ sim2bot bridge # run the local bridge explicitly
163
+ sim2bot doctor # check bridge, browser, TCP/UDP, video, OpenCV
164
+ sim2bot list-robots # wait for the simulator and print index / id / name
165
+ sim2bot open # open the app (override with SIM2BOT_APP_URL)
166
+ ```
167
+
168
+ ## Transport
169
+
170
+ WebSocket by default. For a lower-latency control path with no TCP
171
+ head-of-line blocking:
172
+
173
+ ```python
174
+ Robot(transport="udp") # control + telemetry over UDP (8771)
175
+ ```
176
+
177
+ Camera frames always use the binary video WebSocket, because one frame is far
178
+ larger than a datagram. On localhost the two transports perform about the same;
179
+ UDP's advantage shows over a real network.
180
+
181
+ ## More than one simulator, and other machines
182
+
183
+ Use a room to pair one script with one browser tab:
184
+
185
+ ```python
186
+ Robot(room="bench-a") # or SIM2BOT_BRIDGE_ROOM=bench-a
187
+ ```
188
+
189
+ Without a room, commands go to the most recently connected tab.
190
+
191
+ Scripts on the same machine need no credentials. To drive the bridge from
192
+ another machine on the LAN, bind it to a LAN interface **with a token** — the
193
+ bridge refuses non-loopback clients otherwise:
194
+
195
+ ```sh
196
+ SIM2BOT_BRIDGE_TOKEN=choose-a-secret sim2bot bridge --host 0.0.0.0
197
+ ```
198
+
199
+ ```python
200
+ Robot(url="ws://192.168.1.42:8765/ws", api_key="choose-a-secret")
201
+ ```
202
+
203
+ ## Protocol
204
+
205
+ The wire format is documented in [`docs/protocol.md`](docs/protocol.md), and
206
+ [`fixtures/v1/`](fixtures/v1/) holds one example message per type. Those
207
+ fixtures are the contract: the tests here check this SDK against them, and the
208
+ Sim2Bot app checks its own implementation against the same files. If you are
209
+ writing a client in another language, implement against the fixtures.
210
+
211
+ ## Versions
212
+
213
+ The package version is the version to quote in a bug report. Each release says
214
+ which Sim2Bot app versions it is verified against in
215
+ [`CHANGELOG.md`](CHANGELOG.md).
216
+
217
+ ## Contributing
218
+
219
+ Issues and pull requests are welcome — see [`CONTRIBUTING.md`](CONTRIBUTING.md).
220
+ This repository holds the Python client, the relay and the protocol fixtures.
221
+ The Sim2Bot application itself is closed source, so bugs in the simulator, the
222
+ GUI or rendering are reported here but fixed there.
223
+
224
+ ## Licence
225
+
226
+ MIT — see [`LICENSE`](LICENSE).
@@ -0,0 +1,11 @@
1
+ sim2bot/__init__.py,sha256=8HP5eBZZ7zH6oE5G5r6q8zsU6JM0C0oxGZ0SpFh5vGc,1073
2
+ sim2bot/bridge.py,sha256=fDteFET7nZbnjhw7LJhaNL-e8q-PSXbbYGBagampsXo,7007
3
+ sim2bot/bridge_server.py,sha256=NDP2tFlvbtHdJP8NyRivXUH46lWryan-LWgz5b5GkvQ,16193
4
+ sim2bot/cli.py,sha256=TjFgM6lr1EbGT_xK2o0zk53bDVChOPh4ywb69B2HYnU,9967
5
+ sim2bot/client.py,sha256=g-hbhLH2J0-a_rJ6UP1AODGYorf7cW7iQ05HMesT5cg,62555
6
+ sim2bot-0.1.0.dist-info/licenses/LICENSE,sha256=0H-cPZ7IbBed-ETQPtv4Sp0Mnj3qg7hNofHzi6lRx_c,1079
7
+ sim2bot-0.1.0.dist-info/METADATA,sha256=UBoi6LWCYLmpXpacMFKIQU3EY-yLTbq35I50EKPMGh8,8453
8
+ sim2bot-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
9
+ sim2bot-0.1.0.dist-info/entry_points.txt,sha256=155w-gkvcKvkmeKb_dhF6cKqk-qSi63bdybfocQUXsI,45
10
+ sim2bot-0.1.0.dist-info/top_level.txt,sha256=hkTHuzJ3EXe94ceGBHHzbPUeZnbMwoSJ-J5r57AsgMU,8
11
+ sim2bot-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ sim2bot = sim2bot.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Source Robotics d.o.o.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ sim2bot