luckyrobots 0.1.51__tar.gz → 0.1.70__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.
- luckyrobots-0.1.70/.gitignore +48 -0
- luckyrobots-0.1.70/PKG-INFO +262 -0
- luckyrobots-0.1.70/README.md +230 -0
- luckyrobots-0.1.70/pyproject.toml +81 -0
- luckyrobots-0.1.70/src/luckyrobots/__init__.py +30 -0
- luckyrobots-0.1.70/src/luckyrobots/client.py +800 -0
- luckyrobots-0.1.70/src/luckyrobots/config/robots.yaml +251 -0
- luckyrobots-0.1.70/src/luckyrobots/engine/__init__.py +23 -0
- {luckyrobots-0.1.51/src/luckyrobots/utils → luckyrobots-0.1.70/src/luckyrobots/engine}/check_updates.py +108 -48
- {luckyrobots-0.1.51/src/luckyrobots/utils → luckyrobots-0.1.70/src/luckyrobots/engine}/download.py +61 -39
- luckyrobots-0.1.70/src/luckyrobots/engine/manager.py +427 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/__init__.py +6 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/__init__.py +18 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/agent_pb2.py +61 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/agent_pb2_grpc.py +255 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/camera_pb2.py +45 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/camera_pb2_grpc.py +155 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/common_pb2.py +39 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/common_pb2_grpc.py +27 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/media_pb2.py +35 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/media_pb2_grpc.py +27 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/mujoco_pb2.py +47 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/mujoco_pb2_grpc.py +248 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/scene_pb2.py +54 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/scene_pb2_grpc.py +248 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/telemetry_pb2.py +43 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/telemetry_pb2_grpc.py +154 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/viewport_pb2.py +48 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/generated/viewport_pb2_grpc.py +155 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/agent.proto +152 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/camera.proto +41 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/common.proto +36 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/hazel_rpc.proto +32 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/media.proto +26 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/mujoco.proto +64 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/scene.proto +70 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/telemetry.proto +43 -0
- luckyrobots-0.1.70/src/luckyrobots/grpc/proto/viewport.proto +45 -0
- luckyrobots-0.1.70/src/luckyrobots/luckyrobots.py +212 -0
- luckyrobots-0.1.70/src/luckyrobots/models/__init__.py +13 -0
- luckyrobots-0.1.70/src/luckyrobots/models/camera.py +97 -0
- luckyrobots-0.1.70/src/luckyrobots/models/observation.py +135 -0
- luckyrobots-0.1.70/src/luckyrobots/utils.py +103 -0
- luckyrobots-0.1.51/.gitignore +0 -26
- luckyrobots-0.1.51/.idea/inspectionProfiles/Project_Default.xml +0 -39
- luckyrobots-0.1.51/.idea/inspectionProfiles/profiles_settings.xml +0 -6
- luckyrobots-0.1.51/.idea/luckyrobots-new.iml +0 -6
- luckyrobots-0.1.51/.idea/misc.xml +0 -7
- luckyrobots-0.1.51/.idea/vcs.xml +0 -6
- luckyrobots-0.1.51/.idea/workspace.xml +0 -175
- luckyrobots-0.1.51/.pre-commit-config.yaml +0 -18
- luckyrobots-0.1.51/CNAME +0 -1
- luckyrobots-0.1.51/PKG-INFO +0 -240
- luckyrobots-0.1.51/README.md +0 -205
- luckyrobots-0.1.51/docs/CNAME +0 -1
- luckyrobots-0.1.51/docs/index.md +0 -1
- luckyrobots-0.1.51/examples/controller.py +0 -200
- luckyrobots-0.1.51/pyproject.toml +0 -52
- luckyrobots-0.1.51/scripts/README.md +0 -147
- luckyrobots-0.1.51/scripts/data_crawler.py +0 -433
- luckyrobots-0.1.51/sites/README.MD +0 -1
- luckyrobots-0.1.51/src/luckyrobots/__init__.py +0 -21
- luckyrobots-0.1.51/src/luckyrobots/config/robots.yaml +0 -91
- luckyrobots-0.1.51/src/luckyrobots/core/luckyrobots.py +0 -522
- luckyrobots-0.1.51/src/luckyrobots/core/manager.py +0 -232
- luckyrobots-0.1.51/src/luckyrobots/core/models.py +0 -43
- luckyrobots-0.1.51/src/luckyrobots/core/node.py +0 -270
- luckyrobots-0.1.51/src/luckyrobots/message/__init__.py +0 -18
- luckyrobots-0.1.51/src/luckyrobots/message/pubsub.py +0 -137
- luckyrobots-0.1.51/src/luckyrobots/message/srv/client.py +0 -79
- luckyrobots-0.1.51/src/luckyrobots/message/srv/service.py +0 -139
- luckyrobots-0.1.51/src/luckyrobots/message/srv/types.py +0 -83
- luckyrobots-0.1.51/src/luckyrobots/message/transporter.py +0 -423
- luckyrobots-0.1.51/src/luckyrobots/misc/testserver.py +0 -98
- luckyrobots-0.1.51/src/luckyrobots/misc/testsockets.js +0 -52
- luckyrobots-0.1.51/src/luckyrobots/runtime/builds.py +0 -109
- luckyrobots-0.1.51/src/luckyrobots/runtime/run_executable.py +0 -126
- luckyrobots-0.1.51/src/luckyrobots/runtime/test.py +0 -27
- luckyrobots-0.1.51/src/luckyrobots/utils/event_loop.py +0 -87
- luckyrobots-0.1.51/src/luckyrobots/utils/helpers.py +0 -79
- luckyrobots-0.1.51/src/luckyrobots/utils/library_dev.py +0 -159
- luckyrobots-0.1.51/upload_new_pip_version.sh +0 -33
- luckyrobots-0.1.51/upload_new_pip_version_win.sh +0 -33
- {luckyrobots-0.1.51 → luckyrobots-0.1.70}/LICENSE +0 -0
- {luckyrobots-0.1.51/examples → luckyrobots-0.1.70/src/luckyrobots/config}/__init__.py +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution / packaging
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.eggs/
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
.env
|
|
17
|
+
|
|
18
|
+
# uv
|
|
19
|
+
uv.lock
|
|
20
|
+
|
|
21
|
+
# IDE
|
|
22
|
+
.vscode/
|
|
23
|
+
.idea/
|
|
24
|
+
*.swp
|
|
25
|
+
*~
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Testing
|
|
32
|
+
.pytest_cache/
|
|
33
|
+
.coverage
|
|
34
|
+
.coverage.*
|
|
35
|
+
htmlcov/
|
|
36
|
+
.tox/
|
|
37
|
+
|
|
38
|
+
# Type checking
|
|
39
|
+
.mypy_cache/
|
|
40
|
+
.ruff_cache/
|
|
41
|
+
|
|
42
|
+
# Docs
|
|
43
|
+
docs/_build/
|
|
44
|
+
|
|
45
|
+
# Misc
|
|
46
|
+
*.log
|
|
47
|
+
*.tmp
|
|
48
|
+
repomix-output.xml
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: luckyrobots
|
|
3
|
+
Version: 0.1.70
|
|
4
|
+
Summary: Robotics-AI Training in Hyperrealistic Game Environments
|
|
5
|
+
Project-URL: Homepage, https://github.com/luckyrobots/luckyrobots
|
|
6
|
+
Project-URL: Documentation, https://luckyrobots.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/luckyrobots/luckyrobots
|
|
8
|
+
Project-URL: Issues, https://github.com/luckyrobots/luckyrobots/issues
|
|
9
|
+
Author-email: Devrim Yasar <braces.verbose03@icloud.com>, Ethan Clark <ethan@luckyrobots.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
20
|
+
Requires-Dist: grpcio>=1.60.0
|
|
21
|
+
Requires-Dist: numpy>=1.24.0
|
|
22
|
+
Requires-Dist: opencv-python>=4.8.0
|
|
23
|
+
Requires-Dist: packaging>=23.0
|
|
24
|
+
Requires-Dist: protobuf>=4.25.0
|
|
25
|
+
Requires-Dist: psutil>=5.9.0
|
|
26
|
+
Requires-Dist: pydantic>=2.0.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Requires-Dist: requests>=2.31.0
|
|
29
|
+
Requires-Dist: tqdm>=4.66.0
|
|
30
|
+
Requires-Dist: watchdog>=3.0.0
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img width="384" alt="Default_Logo_Horizontal@2x" src="https://github.com/user-attachments/assets/ae6ad53a-741e-4e7a-94cb-5a46a8e81398" />
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<p align="center">
|
|
38
|
+
Infinite synthetic data generation for embodied AI
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<div align="center">
|
|
42
|
+
|
|
43
|
+
[](https://pypi.org/project/luckyrobots/)
|
|
44
|
+
[](https://luckyrobots.readthedocs.io)
|
|
45
|
+
[](https://opensource.org/licenses/MIT)
|
|
46
|
+
[](https://pypi.org/project/luckyrobots/)
|
|
47
|
+
[](https://pypi.org/project/luckyrobots/)
|
|
48
|
+
[](https://discord.gg/5CH3wx3tAs)
|
|
49
|
+
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
https://github.com/user-attachments/assets/0ab2953d-b188-4af7-a225-71decdd2378c
|
|
53
|
+
|
|
54
|
+
# Lucky Robots
|
|
55
|
+
|
|
56
|
+
Hyperrealistic robotics simulation framework with Python API for embodied AI training and testing.
|
|
57
|
+
|
|
58
|
+
<p align="center">
|
|
59
|
+
<img width="49%" alt="Bedroom environment in LuckyEngine" src="https://github.com/user-attachments/assets/279a7864-9a8b-453e-8567-3a174f5db8ab" />
|
|
60
|
+
<img width="49%" alt="Open floor plan in LuckyEngine" src="https://github.com/user-attachments/assets/68c72b97-98ab-42b0-a065-8a4247b014c7" />
|
|
61
|
+
</p>
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
1. **Download LuckyEngine** from our [releases page](https://github.com/luckyrobots/luckyrobots/releases/latest) and set the path:
|
|
66
|
+
```bash
|
|
67
|
+
# Set environment variable (choose one method):
|
|
68
|
+
|
|
69
|
+
# Method 1: Set LUCKYENGINE_PATH directly to the executable
|
|
70
|
+
export LUCKYENGINE_PATH=/path/to/LuckyEngine # Linux/Mac
|
|
71
|
+
export LUCKYENGINE_PATH=/path/to/LuckyEngine.exe # Windows
|
|
72
|
+
|
|
73
|
+
# Method 2: Set LUCKYENGINE_HOME to the directory containing the executable
|
|
74
|
+
export LUCKYENGINE_HOME=/path/to/luckyengine/directory
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
2. **Install**
|
|
78
|
+
```bash
|
|
79
|
+
pip install luckyrobots
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
3. **Run Example**
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/luckyrobots/luckyrobots.git
|
|
85
|
+
cd luckyrobots/examples
|
|
86
|
+
python controller.py --skip-launch # If LuckyEngine is already running
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Basic Usage
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from luckyrobots import LuckyEngineClient
|
|
93
|
+
|
|
94
|
+
# Connect to LuckyEngine
|
|
95
|
+
client = LuckyEngineClient(
|
|
96
|
+
host="127.0.0.1",
|
|
97
|
+
port=50051,
|
|
98
|
+
robot_name="unitreego1",
|
|
99
|
+
)
|
|
100
|
+
client.wait_for_server()
|
|
101
|
+
|
|
102
|
+
# Optional: Fetch schema for named observation access
|
|
103
|
+
client.fetch_schema()
|
|
104
|
+
|
|
105
|
+
# Get RL observation
|
|
106
|
+
obs = client.get_observation()
|
|
107
|
+
print(f"Observation: {obs.observation[:5]}...") # Flat vector for RL
|
|
108
|
+
print(f"Timestamp: {obs.timestamp_ms}")
|
|
109
|
+
|
|
110
|
+
# Named access (if schema fetched)
|
|
111
|
+
# obs["proj_grav_x"] # Access by name
|
|
112
|
+
# obs.to_dict() # Convert to dict
|
|
113
|
+
|
|
114
|
+
# Send controls
|
|
115
|
+
client.send_control(controls=[0.1, 0.2, -0.1, ...])
|
|
116
|
+
|
|
117
|
+
# Get joint state (separate from RL observation)
|
|
118
|
+
joints = client.get_joint_state()
|
|
119
|
+
print(f"Positions: {joints.positions}")
|
|
120
|
+
print(f"Velocities: {joints.velocities}")
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## API Overview
|
|
124
|
+
|
|
125
|
+
### Core Classes
|
|
126
|
+
|
|
127
|
+
**`LuckyEngineClient`** - Low-level gRPC client
|
|
128
|
+
- `wait_for_server(timeout)` - Wait for LuckyEngine connection
|
|
129
|
+
- `get_observation()` - Get RL observation vector
|
|
130
|
+
- `get_joint_state()` - Get joint positions/velocities
|
|
131
|
+
- `send_control(controls)` - Send actuator commands
|
|
132
|
+
- `get_agent_schema()` - Get observation/action names and sizes
|
|
133
|
+
- `reset_agent()` - Reset agent state
|
|
134
|
+
|
|
135
|
+
**`LuckyRobots`** - High-level wrapper (launches LuckyEngine)
|
|
136
|
+
- `start(scene, robot, task)` - Launch and connect
|
|
137
|
+
- `get_observation()` - Get observation
|
|
138
|
+
- `step(controls)` - Send controls and get next observation
|
|
139
|
+
|
|
140
|
+
### Models
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from luckyrobots import ObservationResponse, StateSnapshot
|
|
144
|
+
|
|
145
|
+
# ObservationResponse - returned by get_observation()
|
|
146
|
+
obs.observation # List[float] - flat RL observation vector
|
|
147
|
+
obs.actions # List[float] - last applied actions
|
|
148
|
+
obs.timestamp_ms # int - wall-clock timestamp
|
|
149
|
+
obs.frame_number # int - monotonic counter
|
|
150
|
+
obs["name"] # Named access (if schema fetched)
|
|
151
|
+
obs.to_dict() # Convert to name->value dict
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Available Robots & Environments
|
|
155
|
+
|
|
156
|
+
### Robots
|
|
157
|
+
- **unitreego1**: Quadruped robot
|
|
158
|
+
- **so100**: 6-DOF manipulator with gripper
|
|
159
|
+
- **stretch_v1**: Mobile manipulator
|
|
160
|
+
|
|
161
|
+
### Scenes
|
|
162
|
+
- **velocity**: Velocity control training
|
|
163
|
+
- **kitchen**: Residential kitchen environment
|
|
164
|
+
|
|
165
|
+
### Tasks
|
|
166
|
+
- **locomotion**: Walking/movement
|
|
167
|
+
- **pickandplace**: Object manipulation
|
|
168
|
+
|
|
169
|
+
## Development
|
|
170
|
+
|
|
171
|
+
### Setup with uv (recommended)
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Clone and enter repo
|
|
175
|
+
git clone https://github.com/luckyrobots/luckyrobots.git
|
|
176
|
+
cd luckyrobots
|
|
177
|
+
|
|
178
|
+
# Install uv if you haven't
|
|
179
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
180
|
+
|
|
181
|
+
# Create venv and install deps
|
|
182
|
+
uv sync
|
|
183
|
+
|
|
184
|
+
# Run tests
|
|
185
|
+
uv run pytest
|
|
186
|
+
|
|
187
|
+
# Run example
|
|
188
|
+
uv run python examples/controller.py --skip-launch
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Setup with pip
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
git clone https://github.com/luckyrobots/luckyrobots.git
|
|
195
|
+
cd luckyrobots
|
|
196
|
+
pip install -e ".[dev]"
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Regenerating gRPC Stubs
|
|
200
|
+
|
|
201
|
+
The Python gRPC stubs are in `src/luckyrobots/grpc/generated/` and are
|
|
202
|
+
generated from protos in `src/luckyrobots/grpc/proto/`.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
python -m grpc_tools.protoc \
|
|
206
|
+
-I "src/luckyrobots/grpc/proto" \
|
|
207
|
+
--python_out="src/luckyrobots/grpc/generated" \
|
|
208
|
+
--grpc_python_out="src/luckyrobots/grpc/generated" \
|
|
209
|
+
src/luckyrobots/grpc/proto/*.proto
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Project Structure
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
src/luckyrobots/
|
|
216
|
+
├── client.py # LuckyEngineClient (main API)
|
|
217
|
+
├── luckyrobots.py # LuckyRobots high-level wrapper
|
|
218
|
+
├── models/ # Pydantic models
|
|
219
|
+
│ ├── observation.py # ObservationResponse, StateSnapshot
|
|
220
|
+
│ └── camera.py # CameraData, CameraShape
|
|
221
|
+
├── engine/ # Engine management
|
|
222
|
+
├── grpc/ # gRPC internals
|
|
223
|
+
│ ├── generated/ # Protobuf stubs
|
|
224
|
+
│ └── proto/ # .proto files
|
|
225
|
+
└── config/ # Robot configurations
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Contributing
|
|
229
|
+
|
|
230
|
+
1. Fork the repository
|
|
231
|
+
2. Create a feature branch
|
|
232
|
+
3. Make changes and add tests
|
|
233
|
+
4. Run `uv run ruff check .` and `uv run ruff format .`
|
|
234
|
+
5. Submit a pull request
|
|
235
|
+
|
|
236
|
+
## Architecture
|
|
237
|
+
|
|
238
|
+
Lucky Robots uses gRPC for communication:
|
|
239
|
+
|
|
240
|
+
- **LuckyEngine**: Physics + rendering backend (Unreal Engine + MuJoCo)
|
|
241
|
+
- **Python client**: Connects via gRPC (default `127.0.0.1:50051`)
|
|
242
|
+
|
|
243
|
+
### gRPC Services
|
|
244
|
+
|
|
245
|
+
| Service | Status | Description |
|
|
246
|
+
|---------|--------|-------------|
|
|
247
|
+
| MujocoService | ✅ Working | Joint state, controls |
|
|
248
|
+
| AgentService | ✅ Working | Observations, reset |
|
|
249
|
+
| SceneService | 🚧 Placeholder | Scene inspection |
|
|
250
|
+
| TelemetryService | 🚧 Placeholder | Telemetry streaming |
|
|
251
|
+
| CameraService | 🚧 Placeholder | Camera frames |
|
|
252
|
+
| ViewportService | 🚧 Placeholder | Viewport pixels |
|
|
253
|
+
|
|
254
|
+
## License
|
|
255
|
+
|
|
256
|
+
MIT License - see [LICENSE](LICENSE) file.
|
|
257
|
+
|
|
258
|
+
## Support
|
|
259
|
+
|
|
260
|
+
- **Issues**: [GitHub Issues](https://github.com/luckyrobots/luckyrobots/issues)
|
|
261
|
+
- **Discussions**: [GitHub Discussions](https://github.com/luckyrobots/luckyrobots/discussions)
|
|
262
|
+
- **Discord**: [Community Server](https://discord.gg/5CH3wx3tAs)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img width="384" alt="Default_Logo_Horizontal@2x" src="https://github.com/user-attachments/assets/ae6ad53a-741e-4e7a-94cb-5a46a8e81398" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
Infinite synthetic data generation for embodied AI
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<div align="center">
|
|
10
|
+
|
|
11
|
+
[](https://pypi.org/project/luckyrobots/)
|
|
12
|
+
[](https://luckyrobots.readthedocs.io)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://pypi.org/project/luckyrobots/)
|
|
15
|
+
[](https://pypi.org/project/luckyrobots/)
|
|
16
|
+
[](https://discord.gg/5CH3wx3tAs)
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
https://github.com/user-attachments/assets/0ab2953d-b188-4af7-a225-71decdd2378c
|
|
21
|
+
|
|
22
|
+
# Lucky Robots
|
|
23
|
+
|
|
24
|
+
Hyperrealistic robotics simulation framework with Python API for embodied AI training and testing.
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<img width="49%" alt="Bedroom environment in LuckyEngine" src="https://github.com/user-attachments/assets/279a7864-9a8b-453e-8567-3a174f5db8ab" />
|
|
28
|
+
<img width="49%" alt="Open floor plan in LuckyEngine" src="https://github.com/user-attachments/assets/68c72b97-98ab-42b0-a065-8a4247b014c7" />
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
1. **Download LuckyEngine** from our [releases page](https://github.com/luckyrobots/luckyrobots/releases/latest) and set the path:
|
|
34
|
+
```bash
|
|
35
|
+
# Set environment variable (choose one method):
|
|
36
|
+
|
|
37
|
+
# Method 1: Set LUCKYENGINE_PATH directly to the executable
|
|
38
|
+
export LUCKYENGINE_PATH=/path/to/LuckyEngine # Linux/Mac
|
|
39
|
+
export LUCKYENGINE_PATH=/path/to/LuckyEngine.exe # Windows
|
|
40
|
+
|
|
41
|
+
# Method 2: Set LUCKYENGINE_HOME to the directory containing the executable
|
|
42
|
+
export LUCKYENGINE_HOME=/path/to/luckyengine/directory
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. **Install**
|
|
46
|
+
```bash
|
|
47
|
+
pip install luckyrobots
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
3. **Run Example**
|
|
51
|
+
```bash
|
|
52
|
+
git clone https://github.com/luckyrobots/luckyrobots.git
|
|
53
|
+
cd luckyrobots/examples
|
|
54
|
+
python controller.py --skip-launch # If LuckyEngine is already running
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Basic Usage
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from luckyrobots import LuckyEngineClient
|
|
61
|
+
|
|
62
|
+
# Connect to LuckyEngine
|
|
63
|
+
client = LuckyEngineClient(
|
|
64
|
+
host="127.0.0.1",
|
|
65
|
+
port=50051,
|
|
66
|
+
robot_name="unitreego1",
|
|
67
|
+
)
|
|
68
|
+
client.wait_for_server()
|
|
69
|
+
|
|
70
|
+
# Optional: Fetch schema for named observation access
|
|
71
|
+
client.fetch_schema()
|
|
72
|
+
|
|
73
|
+
# Get RL observation
|
|
74
|
+
obs = client.get_observation()
|
|
75
|
+
print(f"Observation: {obs.observation[:5]}...") # Flat vector for RL
|
|
76
|
+
print(f"Timestamp: {obs.timestamp_ms}")
|
|
77
|
+
|
|
78
|
+
# Named access (if schema fetched)
|
|
79
|
+
# obs["proj_grav_x"] # Access by name
|
|
80
|
+
# obs.to_dict() # Convert to dict
|
|
81
|
+
|
|
82
|
+
# Send controls
|
|
83
|
+
client.send_control(controls=[0.1, 0.2, -0.1, ...])
|
|
84
|
+
|
|
85
|
+
# Get joint state (separate from RL observation)
|
|
86
|
+
joints = client.get_joint_state()
|
|
87
|
+
print(f"Positions: {joints.positions}")
|
|
88
|
+
print(f"Velocities: {joints.velocities}")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## API Overview
|
|
92
|
+
|
|
93
|
+
### Core Classes
|
|
94
|
+
|
|
95
|
+
**`LuckyEngineClient`** - Low-level gRPC client
|
|
96
|
+
- `wait_for_server(timeout)` - Wait for LuckyEngine connection
|
|
97
|
+
- `get_observation()` - Get RL observation vector
|
|
98
|
+
- `get_joint_state()` - Get joint positions/velocities
|
|
99
|
+
- `send_control(controls)` - Send actuator commands
|
|
100
|
+
- `get_agent_schema()` - Get observation/action names and sizes
|
|
101
|
+
- `reset_agent()` - Reset agent state
|
|
102
|
+
|
|
103
|
+
**`LuckyRobots`** - High-level wrapper (launches LuckyEngine)
|
|
104
|
+
- `start(scene, robot, task)` - Launch and connect
|
|
105
|
+
- `get_observation()` - Get observation
|
|
106
|
+
- `step(controls)` - Send controls and get next observation
|
|
107
|
+
|
|
108
|
+
### Models
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from luckyrobots import ObservationResponse, StateSnapshot
|
|
112
|
+
|
|
113
|
+
# ObservationResponse - returned by get_observation()
|
|
114
|
+
obs.observation # List[float] - flat RL observation vector
|
|
115
|
+
obs.actions # List[float] - last applied actions
|
|
116
|
+
obs.timestamp_ms # int - wall-clock timestamp
|
|
117
|
+
obs.frame_number # int - monotonic counter
|
|
118
|
+
obs["name"] # Named access (if schema fetched)
|
|
119
|
+
obs.to_dict() # Convert to name->value dict
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Available Robots & Environments
|
|
123
|
+
|
|
124
|
+
### Robots
|
|
125
|
+
- **unitreego1**: Quadruped robot
|
|
126
|
+
- **so100**: 6-DOF manipulator with gripper
|
|
127
|
+
- **stretch_v1**: Mobile manipulator
|
|
128
|
+
|
|
129
|
+
### Scenes
|
|
130
|
+
- **velocity**: Velocity control training
|
|
131
|
+
- **kitchen**: Residential kitchen environment
|
|
132
|
+
|
|
133
|
+
### Tasks
|
|
134
|
+
- **locomotion**: Walking/movement
|
|
135
|
+
- **pickandplace**: Object manipulation
|
|
136
|
+
|
|
137
|
+
## Development
|
|
138
|
+
|
|
139
|
+
### Setup with uv (recommended)
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Clone and enter repo
|
|
143
|
+
git clone https://github.com/luckyrobots/luckyrobots.git
|
|
144
|
+
cd luckyrobots
|
|
145
|
+
|
|
146
|
+
# Install uv if you haven't
|
|
147
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
148
|
+
|
|
149
|
+
# Create venv and install deps
|
|
150
|
+
uv sync
|
|
151
|
+
|
|
152
|
+
# Run tests
|
|
153
|
+
uv run pytest
|
|
154
|
+
|
|
155
|
+
# Run example
|
|
156
|
+
uv run python examples/controller.py --skip-launch
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Setup with pip
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
git clone https://github.com/luckyrobots/luckyrobots.git
|
|
163
|
+
cd luckyrobots
|
|
164
|
+
pip install -e ".[dev]"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Regenerating gRPC Stubs
|
|
168
|
+
|
|
169
|
+
The Python gRPC stubs are in `src/luckyrobots/grpc/generated/` and are
|
|
170
|
+
generated from protos in `src/luckyrobots/grpc/proto/`.
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
python -m grpc_tools.protoc \
|
|
174
|
+
-I "src/luckyrobots/grpc/proto" \
|
|
175
|
+
--python_out="src/luckyrobots/grpc/generated" \
|
|
176
|
+
--grpc_python_out="src/luckyrobots/grpc/generated" \
|
|
177
|
+
src/luckyrobots/grpc/proto/*.proto
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Project Structure
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
src/luckyrobots/
|
|
184
|
+
├── client.py # LuckyEngineClient (main API)
|
|
185
|
+
├── luckyrobots.py # LuckyRobots high-level wrapper
|
|
186
|
+
├── models/ # Pydantic models
|
|
187
|
+
│ ├── observation.py # ObservationResponse, StateSnapshot
|
|
188
|
+
│ └── camera.py # CameraData, CameraShape
|
|
189
|
+
├── engine/ # Engine management
|
|
190
|
+
├── grpc/ # gRPC internals
|
|
191
|
+
│ ├── generated/ # Protobuf stubs
|
|
192
|
+
│ └── proto/ # .proto files
|
|
193
|
+
└── config/ # Robot configurations
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Contributing
|
|
197
|
+
|
|
198
|
+
1. Fork the repository
|
|
199
|
+
2. Create a feature branch
|
|
200
|
+
3. Make changes and add tests
|
|
201
|
+
4. Run `uv run ruff check .` and `uv run ruff format .`
|
|
202
|
+
5. Submit a pull request
|
|
203
|
+
|
|
204
|
+
## Architecture
|
|
205
|
+
|
|
206
|
+
Lucky Robots uses gRPC for communication:
|
|
207
|
+
|
|
208
|
+
- **LuckyEngine**: Physics + rendering backend (Unreal Engine + MuJoCo)
|
|
209
|
+
- **Python client**: Connects via gRPC (default `127.0.0.1:50051`)
|
|
210
|
+
|
|
211
|
+
### gRPC Services
|
|
212
|
+
|
|
213
|
+
| Service | Status | Description |
|
|
214
|
+
|---------|--------|-------------|
|
|
215
|
+
| MujocoService | ✅ Working | Joint state, controls |
|
|
216
|
+
| AgentService | ✅ Working | Observations, reset |
|
|
217
|
+
| SceneService | 🚧 Placeholder | Scene inspection |
|
|
218
|
+
| TelemetryService | 🚧 Placeholder | Telemetry streaming |
|
|
219
|
+
| CameraService | 🚧 Placeholder | Camera frames |
|
|
220
|
+
| ViewportService | 🚧 Placeholder | Viewport pixels |
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT License - see [LICENSE](LICENSE) file.
|
|
225
|
+
|
|
226
|
+
## Support
|
|
227
|
+
|
|
228
|
+
- **Issues**: [GitHub Issues](https://github.com/luckyrobots/luckyrobots/issues)
|
|
229
|
+
- **Discussions**: [GitHub Discussions](https://github.com/luckyrobots/luckyrobots/discussions)
|
|
230
|
+
- **Discord**: [Community Server](https://discord.gg/5CH3wx3tAs)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "luckyrobots"
|
|
7
|
+
version = "0.1.70"
|
|
8
|
+
description = "Robotics-AI Training in Hyperrealistic Game Environments"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Devrim Yasar", email = "braces.verbose03@icloud.com"},
|
|
14
|
+
{name = "Ethan Clark", email = "ethan@luckyrobots.com"},
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"grpcio>=1.60.0",
|
|
26
|
+
"protobuf>=4.25.0",
|
|
27
|
+
"pydantic>=2.0.0",
|
|
28
|
+
"numpy>=1.24.0",
|
|
29
|
+
"pyyaml>=6.0",
|
|
30
|
+
"opencv-python>=4.8.0",
|
|
31
|
+
"requests>=2.31.0",
|
|
32
|
+
"tqdm>=4.66.0",
|
|
33
|
+
"psutil>=5.9.0",
|
|
34
|
+
"packaging>=23.0",
|
|
35
|
+
"beautifulsoup4>=4.12.0",
|
|
36
|
+
"watchdog>=3.0.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/luckyrobots/luckyrobots"
|
|
41
|
+
Documentation = "https://luckyrobots.readthedocs.io"
|
|
42
|
+
Repository = "https://github.com/luckyrobots/luckyrobots"
|
|
43
|
+
Issues = "https://github.com/luckyrobots/luckyrobots/issues"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/luckyrobots"]
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.sdist]
|
|
49
|
+
include = [
|
|
50
|
+
"src/luckyrobots/**/*.py",
|
|
51
|
+
"src/luckyrobots/config/*.yaml",
|
|
52
|
+
"src/luckyrobots/grpc/proto/*.proto",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[dependency-groups]
|
|
56
|
+
dev = [
|
|
57
|
+
"pytest>=8.0.0",
|
|
58
|
+
"pytest-cov>=4.1.0",
|
|
59
|
+
"black>=24.0.0",
|
|
60
|
+
"ruff>=0.2.0",
|
|
61
|
+
"grpcio-tools>=1.60.0",
|
|
62
|
+
"build>=1.0.0",
|
|
63
|
+
"twine>=5.0.0",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
testpaths = ["tests"]
|
|
68
|
+
python_files = ["test_*.py"]
|
|
69
|
+
python_functions = ["test_*"]
|
|
70
|
+
|
|
71
|
+
[tool.ruff]
|
|
72
|
+
line-length = 100
|
|
73
|
+
target-version = "py310"
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint]
|
|
76
|
+
select = ["E", "F", "I", "UP"]
|
|
77
|
+
ignore = ["E501"]
|
|
78
|
+
|
|
79
|
+
[tool.black]
|
|
80
|
+
line-length = 100
|
|
81
|
+
target-version = ["py310", "py311", "py312"]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LuckyRobots - Robotics simulation framework with gRPC communication.
|
|
3
|
+
|
|
4
|
+
This package provides a Python API for controlling robots in the LuckyEngine
|
|
5
|
+
simulation environment via gRPC.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .luckyrobots import LuckyRobots
|
|
9
|
+
from .client import LuckyEngineClient, GrpcConnectionError, BenchmarkResult
|
|
10
|
+
from .models import ObservationResponse, StateSnapshot, CameraData, CameraShape
|
|
11
|
+
from .utils import FPS
|
|
12
|
+
from .engine import check_updates
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
# High-level API
|
|
17
|
+
"LuckyRobots",
|
|
18
|
+
# Low-level client
|
|
19
|
+
"LuckyEngineClient",
|
|
20
|
+
"GrpcConnectionError",
|
|
21
|
+
"BenchmarkResult",
|
|
22
|
+
# Models
|
|
23
|
+
"ObservationResponse",
|
|
24
|
+
"StateSnapshot",
|
|
25
|
+
"CameraData",
|
|
26
|
+
"CameraShape",
|
|
27
|
+
# Utilities
|
|
28
|
+
"FPS",
|
|
29
|
+
"check_updates",
|
|
30
|
+
]
|