luckyrobots 0.1.68__py3-none-any.whl → 0.1.69__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.
- luckyrobots/__init__.py +23 -12
- luckyrobots/client.py +800 -0
- luckyrobots/config/robots.yaml +231 -71
- luckyrobots/engine/__init__.py +23 -0
- luckyrobots/{utils → engine}/check_updates.py +108 -48
- luckyrobots/{utils → engine}/download.py +61 -39
- luckyrobots/engine/manager.py +427 -0
- luckyrobots/grpc/__init__.py +6 -0
- luckyrobots/grpc/generated/__init__.py +18 -0
- luckyrobots/grpc/generated/agent_pb2.py +61 -0
- luckyrobots/grpc/generated/agent_pb2_grpc.py +255 -0
- luckyrobots/grpc/generated/camera_pb2.py +45 -0
- luckyrobots/grpc/generated/camera_pb2_grpc.py +155 -0
- luckyrobots/grpc/generated/common_pb2.py +39 -0
- luckyrobots/grpc/generated/common_pb2_grpc.py +27 -0
- luckyrobots/grpc/generated/media_pb2.py +35 -0
- luckyrobots/grpc/generated/media_pb2_grpc.py +27 -0
- luckyrobots/grpc/generated/mujoco_pb2.py +47 -0
- luckyrobots/grpc/generated/mujoco_pb2_grpc.py +248 -0
- luckyrobots/grpc/generated/scene_pb2.py +54 -0
- luckyrobots/grpc/generated/scene_pb2_grpc.py +248 -0
- luckyrobots/grpc/generated/telemetry_pb2.py +43 -0
- luckyrobots/grpc/generated/telemetry_pb2_grpc.py +154 -0
- luckyrobots/grpc/generated/viewport_pb2.py +48 -0
- luckyrobots/grpc/generated/viewport_pb2_grpc.py +155 -0
- luckyrobots/grpc/proto/agent.proto +152 -0
- luckyrobots/grpc/proto/camera.proto +41 -0
- luckyrobots/grpc/proto/common.proto +36 -0
- luckyrobots/grpc/proto/hazel_rpc.proto +32 -0
- luckyrobots/grpc/proto/media.proto +26 -0
- luckyrobots/grpc/proto/mujoco.proto +64 -0
- luckyrobots/grpc/proto/scene.proto +70 -0
- luckyrobots/grpc/proto/telemetry.proto +43 -0
- luckyrobots/grpc/proto/viewport.proto +45 -0
- luckyrobots/luckyrobots.py +193 -0
- luckyrobots/models/__init__.py +13 -0
- luckyrobots/models/camera.py +97 -0
- luckyrobots/models/observation.py +135 -0
- luckyrobots/{utils/helpers.py → utils.py} +75 -40
- luckyrobots-0.1.69.dist-info/METADATA +262 -0
- luckyrobots-0.1.69.dist-info/RECORD +44 -0
- {luckyrobots-0.1.68.dist-info → luckyrobots-0.1.69.dist-info}/WHEEL +1 -1
- luckyrobots/core/luckyrobots.py +0 -628
- luckyrobots/core/manager.py +0 -236
- luckyrobots/core/models.py +0 -68
- luckyrobots/core/node.py +0 -273
- luckyrobots/message/__init__.py +0 -18
- luckyrobots/message/pubsub.py +0 -145
- luckyrobots/message/srv/client.py +0 -81
- luckyrobots/message/srv/service.py +0 -135
- luckyrobots/message/srv/types.py +0 -83
- luckyrobots/message/transporter.py +0 -427
- luckyrobots/utils/event_loop.py +0 -94
- luckyrobots/utils/sim_manager.py +0 -413
- luckyrobots-0.1.68.dist-info/METADATA +0 -253
- luckyrobots-0.1.68.dist-info/RECORD +0 -24
- {luckyrobots-0.1.68.dist-info → luckyrobots-0.1.69.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,18 +1,87 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
Utility functions and classes for LuckyRobots.
|
|
3
|
+
"""
|
|
4
|
+
|
|
2
5
|
import time
|
|
6
|
+
import yaml
|
|
3
7
|
import importlib.resources
|
|
4
8
|
from collections import deque
|
|
5
9
|
|
|
6
10
|
|
|
11
|
+
class FPS:
|
|
12
|
+
"""Utility for measuring frames per second with a rolling window.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
fps = FPS(frame_window=30)
|
|
16
|
+
while running:
|
|
17
|
+
# ... do work ...
|
|
18
|
+
current_fps = fps.measure()
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, frame_window: int = 30):
|
|
22
|
+
"""Initialize FPS counter.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
frame_window: Number of frames to average over.
|
|
26
|
+
"""
|
|
27
|
+
self.frame_window = frame_window
|
|
28
|
+
self.frame_times: deque[float] = deque(maxlen=frame_window)
|
|
29
|
+
self.last_frame_time = time.perf_counter()
|
|
30
|
+
|
|
31
|
+
def measure(self) -> float:
|
|
32
|
+
"""Record a frame and return current FPS.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Current frames per second (averaged over window).
|
|
36
|
+
"""
|
|
37
|
+
current_time = time.perf_counter()
|
|
38
|
+
frame_delta = current_time - self.last_frame_time
|
|
39
|
+
self.last_frame_time = current_time
|
|
40
|
+
|
|
41
|
+
self.frame_times.append(frame_delta)
|
|
42
|
+
|
|
43
|
+
if len(self.frame_times) >= 2:
|
|
44
|
+
avg_frame_time = sum(self.frame_times) / len(self.frame_times)
|
|
45
|
+
return 1.0 / avg_frame_time if avg_frame_time > 0 else 0.0
|
|
46
|
+
return 0.0
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_robot_config(robot: str = None) -> dict:
|
|
50
|
+
"""Get the configuration for a robot from robots.yaml.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
robot: Robot name. If None, returns entire config.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Robot configuration dict, or full config if robot is None.
|
|
57
|
+
"""
|
|
58
|
+
with importlib.resources.files("luckyrobots").joinpath("config/robots.yaml").open(
|
|
59
|
+
"r"
|
|
60
|
+
) as f:
|
|
61
|
+
config = yaml.safe_load(f)
|
|
62
|
+
if robot is not None:
|
|
63
|
+
return config[robot]
|
|
64
|
+
else:
|
|
65
|
+
return config
|
|
66
|
+
|
|
67
|
+
|
|
7
68
|
def validate_params(
|
|
8
69
|
scene: str = None,
|
|
9
70
|
robot: str = None,
|
|
10
71
|
task: str = None,
|
|
11
72
|
observation_type: str = None,
|
|
12
|
-
) ->
|
|
13
|
-
"""Validate
|
|
14
|
-
|
|
73
|
+
) -> None:
|
|
74
|
+
"""Validate parameters for launching LuckyEngine.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
scene: Scene name.
|
|
78
|
+
robot: Robot name.
|
|
79
|
+
task: Task name.
|
|
80
|
+
observation_type: Observation type.
|
|
15
81
|
|
|
82
|
+
Raises:
|
|
83
|
+
ValueError: If any parameter is invalid.
|
|
84
|
+
"""
|
|
16
85
|
if scene is None:
|
|
17
86
|
raise ValueError("Scene is required")
|
|
18
87
|
if robot is None:
|
|
@@ -22,6 +91,8 @@ def validate_params(
|
|
|
22
91
|
if observation_type is None:
|
|
23
92
|
raise ValueError("Observation type is required")
|
|
24
93
|
|
|
94
|
+
robot_config = get_robot_config(robot)
|
|
95
|
+
|
|
25
96
|
if scene not in robot_config["available_scenes"]:
|
|
26
97
|
raise ValueError(f"Scene {scene} not available in {robot} config")
|
|
27
98
|
if task not in robot_config["available_tasks"]:
|
|
@@ -30,39 +101,3 @@ def validate_params(
|
|
|
30
101
|
raise ValueError(
|
|
31
102
|
f"Observation type {observation_type} not available in {robot} config"
|
|
32
103
|
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def get_robot_config(robot: str = None) -> dict:
|
|
36
|
-
"""Get the configuration for the robot"""
|
|
37
|
-
with importlib.resources.files("luckyrobots").joinpath("config/robots.yaml").open(
|
|
38
|
-
"r"
|
|
39
|
-
) as f:
|
|
40
|
-
config = yaml.safe_load(f)
|
|
41
|
-
if robot is not None:
|
|
42
|
-
return config[robot]
|
|
43
|
-
else:
|
|
44
|
-
return config
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class FPS:
|
|
48
|
-
def __init__(self, frame_window: int = 30):
|
|
49
|
-
self.frame_window = frame_window
|
|
50
|
-
self.frame_times = deque(maxlen=frame_window)
|
|
51
|
-
self.last_frame_time = time.perf_counter()
|
|
52
|
-
|
|
53
|
-
def measure(self) -> float:
|
|
54
|
-
current_time = time.perf_counter()
|
|
55
|
-
frame_delta = current_time - self.last_frame_time
|
|
56
|
-
self.last_frame_time = current_time
|
|
57
|
-
|
|
58
|
-
# Add frame time to rolling window
|
|
59
|
-
self.frame_times.append(frame_delta)
|
|
60
|
-
|
|
61
|
-
# Calculate FPS from average frame time
|
|
62
|
-
if len(self.frame_times) >= 2: # Need at least 2 samples
|
|
63
|
-
avg_frame_time = sum(self.frame_times) / len(self.frame_times)
|
|
64
|
-
fps = 1.0 / avg_frame_time if avg_frame_time > 0 else 0
|
|
65
|
-
else:
|
|
66
|
-
fps = 0
|
|
67
|
-
|
|
68
|
-
print(f"FPS: {fps}")
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: luckyrobots
|
|
3
|
+
Version: 0.1.69
|
|
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,44 @@
|
|
|
1
|
+
luckyrobots/__init__.py,sha256=3hJT7tvGfzU6-PzXICpv4O9SNAiuFhE95o0_dTxLi7Y,739
|
|
2
|
+
luckyrobots/client.py,sha256=D81pk16ZFKP_uYDSJAur_aucRu7eW2JXW0s63HAYWfQ,28935
|
|
3
|
+
luckyrobots/luckyrobots.py,sha256=F68TUhKplLbdkuARGGUer9jSf1QUzLhu1Rfc-vqDZso,6788
|
|
4
|
+
luckyrobots/utils.py,sha256=62BqpSRBFykVRMZ5Ti2F-yKRDoyU3UNHeesDF_PVCFc,2958
|
|
5
|
+
luckyrobots/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
luckyrobots/config/robots.yaml,sha256=Wu2AgwhZxo9F-RLcqPJXHnqzjT8a0wR-rFBcecck_eE,5164
|
|
7
|
+
luckyrobots/engine/__init__.py,sha256=-3r7aLueDF7eyumqIhTvYqS8ZNnVSJUJEHG4ybsKrjc,546
|
|
8
|
+
luckyrobots/engine/check_updates.py,sha256=KGQHrj1LB0_vexktO01xx-ZvPOYKkto4VBb3H1KV7uI,7593
|
|
9
|
+
luckyrobots/engine/download.py,sha256=vIb5T40Jk2BnfjPo0f4KgW14Om6P4_mvPpZ9JAlkVvg,4029
|
|
10
|
+
luckyrobots/engine/manager.py,sha256=8vxSevaoXo-lw2G6y74lVc-Ms8xIELK0yLswydMiOQY,13388
|
|
11
|
+
luckyrobots/grpc/__init__.py,sha256=hPh-X_FEus2sxrfQB2fQjD754X5bMaUFTWm3mZmUhe0,153
|
|
12
|
+
luckyrobots/grpc/generated/__init__.py,sha256=u69M4E_2LwRQSD_n4wvQyMX7dryBCrIdsho59c52Crk,732
|
|
13
|
+
luckyrobots/grpc/generated/agent_pb2.py,sha256=71ILNgwKLNhfiTsU8ocZTasG-hNViF03Cn3-ldBvc9A,5728
|
|
14
|
+
luckyrobots/grpc/generated/agent_pb2_grpc.py,sha256=LAiYHz2UhQNFCKYmm4FeKnSIVXpAoR9CpWiIKTu1Bro,8962
|
|
15
|
+
luckyrobots/grpc/generated/camera_pb2.py,sha256=QGxa8sfMqzzdShyA7RVXLWsfSzXZ0Kg7cPSZYYl6E2c,2664
|
|
16
|
+
luckyrobots/grpc/generated/camera_pb2_grpc.py,sha256=u7jimo_r0ThMmQOl43IXoyWNGIX2T583mv4xcCBciqk,5212
|
|
17
|
+
luckyrobots/grpc/generated/common_pb2.py,sha256=puH7AOneT8K5FjcW2PjnUY6e2u-vobtnS4bpaPl4nhM,2073
|
|
18
|
+
luckyrobots/grpc/generated/common_pb2_grpc.py,sha256=kFXVJY9Ju1lO1ramSeiLiMAZBYWBDrDaON96j2C3rXI,901
|
|
19
|
+
luckyrobots/grpc/generated/media_pb2.py,sha256=FUgow9NoFf9DztuVrrokGXxuJBHFb0AKBQAc3aez7BU,1839
|
|
20
|
+
luckyrobots/grpc/generated/media_pb2_grpc.py,sha256=AqZmnqqFTTxtFC5bsA-YygCMD93BTRSb97RBovHCARo,900
|
|
21
|
+
luckyrobots/grpc/generated/mujoco_pb2.py,sha256=20UVm-fptmjfv17L06HKSTkMyVZwKa-aPzaltAUaNSA,3540
|
|
22
|
+
luckyrobots/grpc/generated/mujoco_pb2_grpc.py,sha256=HDroQ6_HgaG06WxLsMwo6DHze3Or8bGXlhJln8Oqwfo,8442
|
|
23
|
+
luckyrobots/grpc/generated/scene_pb2.py,sha256=ggZ5ZqMoYyWY4MShDG6S7TTH7HIa3_uyddxFEkF4ocw,4067
|
|
24
|
+
luckyrobots/grpc/generated/scene_pb2_grpc.py,sha256=yPWO10jLAL9orTtzG08NDjWVz1uw8i9Yf8zRVtESMHE,8417
|
|
25
|
+
luckyrobots/grpc/generated/telemetry_pb2.py,sha256=RdTlqizfmLBlT3Es0A_gkW0ec4rY3AsMwXkuG8Ds8zU,2840
|
|
26
|
+
luckyrobots/grpc/generated/telemetry_pb2_grpc.py,sha256=Sq6nExNUZe1-rERJceSoSt23Pbx-DeFA3zrOJsOQpxA,5397
|
|
27
|
+
luckyrobots/grpc/generated/viewport_pb2.py,sha256=LO_6MujrgVjm_QgeGjsyBVHal13SXN_6ROGb86WAEso,3147
|
|
28
|
+
luckyrobots/grpc/generated/viewport_pb2_grpc.py,sha256=QIrjDAdE2kU-R6VVzAso3iZDDdurJllXkXwBggFYCcs,5370
|
|
29
|
+
luckyrobots/grpc/proto/agent.proto,sha256=-3MzIKGzDC6QhPYUHuCXZfp6ygXA7c9usWblV55np3s,5694
|
|
30
|
+
luckyrobots/grpc/proto/camera.proto,sha256=fXCaU9TdJk0zHJs0Jbkq9DABOwaPJBHyUKj1RyMoJeQ,1100
|
|
31
|
+
luckyrobots/grpc/proto/common.proto,sha256=6twE6_HQUMd1N6Ko2vUEDWtL07pCflHIfmit66ggvg0,775
|
|
32
|
+
luckyrobots/grpc/proto/hazel_rpc.proto,sha256=a0F_Dl1JgmJdoIe4okL_tHDzIQvL7dETrb634EuWTrg,1232
|
|
33
|
+
luckyrobots/grpc/proto/media.proto,sha256=CNZJTepdS6Gx68d_Cd3ciaPrOsAe3e7yZbgHIGYe1LY,839
|
|
34
|
+
luckyrobots/grpc/proto/mujoco.proto,sha256=nVovXeedm-imERtSVLeBR8dpEDmlFxXhyVujKy9BylU,1876
|
|
35
|
+
luckyrobots/grpc/proto/scene.proto,sha256=9p19X6_IdiarDXHczkxvjO6Uhjltbwnk8lYuZik7Q1s,1828
|
|
36
|
+
luckyrobots/grpc/proto/telemetry.proto,sha256=vD27JPNPhgi36fkJMTLoFNbv5YXEiz1xntsK00OJ6-Q,1484
|
|
37
|
+
luckyrobots/grpc/proto/viewport.proto,sha256=l3BZBho-v0DHLKt3OQhJwodaZMxZfFceAPQQUmW7PVU,1327
|
|
38
|
+
luckyrobots/models/__init__.py,sha256=LsKj7q9fMTqpSC4WThJVlRMmwho5D08OURVCgerEURI,246
|
|
39
|
+
luckyrobots/models/camera.py,sha256=e-CftAndHASfokhtUtU7ujGb2q_kcXZ6-2KKvY42CKg,3682
|
|
40
|
+
luckyrobots/models/observation.py,sha256=jbRiUTjOP2ZiSobsnNcks3aMPAJA6oPoKqiXwvrNQK0,4758
|
|
41
|
+
luckyrobots-0.1.69.dist-info/METADATA,sha256=S9czWJXY1XdNYfp2uPzs96YnxBqeJo9CD8ECBy1lQX0,8379
|
|
42
|
+
luckyrobots-0.1.69.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
43
|
+
luckyrobots-0.1.69.dist-info/licenses/LICENSE,sha256=xsPYvRJPH_fW_sofTUknI_KvZOsD4-BqjSOTZqI6Nmw,1069
|
|
44
|
+
luckyrobots-0.1.69.dist-info/RECORD,,
|