reachy-mini 1.2.5rc1__py3-none-any.whl → 1.2.11__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.
- reachy_mini/apps/app.py +24 -21
- reachy_mini/apps/manager.py +17 -3
- reachy_mini/apps/sources/hf_auth.py +92 -0
- reachy_mini/apps/sources/hf_space.py +1 -1
- reachy_mini/apps/sources/local_common_venv.py +199 -24
- reachy_mini/apps/templates/main.py.j2 +4 -3
- reachy_mini/daemon/app/dashboard/static/js/apps.js +9 -1
- reachy_mini/daemon/app/dashboard/static/js/appstore.js +228 -0
- reachy_mini/daemon/app/dashboard/static/js/logs.js +148 -0
- reachy_mini/daemon/app/dashboard/templates/logs.html +37 -0
- reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +92 -0
- reachy_mini/daemon/app/dashboard/templates/sections/cache.html +82 -0
- reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +5 -0
- reachy_mini/daemon/app/dashboard/templates/settings.html +1 -0
- reachy_mini/daemon/app/main.py +172 -7
- reachy_mini/daemon/app/models.py +8 -0
- reachy_mini/daemon/app/routers/apps.py +56 -0
- reachy_mini/daemon/app/routers/cache.py +58 -0
- reachy_mini/daemon/app/routers/hf_auth.py +57 -0
- reachy_mini/daemon/app/routers/logs.py +124 -0
- reachy_mini/daemon/app/routers/state.py +25 -1
- reachy_mini/daemon/app/routers/wifi_config.py +75 -0
- reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py +1 -1
- reachy_mini/daemon/app/services/bluetooth/commands/WIFI_RESET.sh +8 -0
- reachy_mini/daemon/app/services/wireless/launcher.sh +8 -2
- reachy_mini/daemon/app/services/wireless/reachy-mini-daemon.service +13 -0
- reachy_mini/daemon/backend/abstract.py +29 -9
- reachy_mini/daemon/backend/mockup_sim/__init__.py +12 -0
- reachy_mini/daemon/backend/mockup_sim/backend.py +176 -0
- reachy_mini/daemon/backend/mujoco/backend.py +0 -5
- reachy_mini/daemon/backend/robot/backend.py +78 -5
- reachy_mini/daemon/daemon.py +46 -7
- reachy_mini/daemon/utils.py +71 -15
- reachy_mini/io/zenoh_client.py +26 -0
- reachy_mini/io/zenoh_server.py +10 -6
- reachy_mini/kinematics/nn_kinematics.py +2 -2
- reachy_mini/kinematics/placo_kinematics.py +15 -15
- reachy_mini/media/__init__.py +55 -1
- reachy_mini/media/audio_base.py +185 -13
- reachy_mini/media/audio_control_utils.py +60 -5
- reachy_mini/media/audio_gstreamer.py +97 -16
- reachy_mini/media/audio_sounddevice.py +120 -19
- reachy_mini/media/audio_utils.py +110 -5
- reachy_mini/media/camera_base.py +182 -11
- reachy_mini/media/camera_constants.py +132 -4
- reachy_mini/media/camera_gstreamer.py +42 -2
- reachy_mini/media/camera_opencv.py +83 -5
- reachy_mini/media/camera_utils.py +95 -7
- reachy_mini/media/media_manager.py +139 -6
- reachy_mini/media/webrtc_client_gstreamer.py +142 -13
- reachy_mini/media/webrtc_daemon.py +72 -7
- reachy_mini/motion/recorded_move.py +76 -2
- reachy_mini/reachy_mini.py +196 -40
- reachy_mini/tools/reflash_motors.py +1 -1
- reachy_mini/tools/scan_motors.py +86 -0
- reachy_mini/tools/setup_motor.py +49 -31
- reachy_mini/utils/interpolation.py +1 -1
- reachy_mini/utils/wireless_version/startup_check.py +278 -21
- reachy_mini/utils/wireless_version/update.py +44 -1
- {reachy_mini-1.2.5rc1.dist-info → reachy_mini-1.2.11.dist-info}/METADATA +7 -6
- {reachy_mini-1.2.5rc1.dist-info → reachy_mini-1.2.11.dist-info}/RECORD +65 -53
- {reachy_mini-1.2.5rc1.dist-info → reachy_mini-1.2.11.dist-info}/WHEEL +0 -0
- {reachy_mini-1.2.5rc1.dist-info → reachy_mini-1.2.11.dist-info}/entry_points.txt +0 -0
- {reachy_mini-1.2.5rc1.dist-info → reachy_mini-1.2.11.dist-info}/licenses/LICENSE +0 -0
- {reachy_mini-1.2.5rc1.dist-info → reachy_mini-1.2.11.dist-info}/top_level.txt +0 -0
|
@@ -7,7 +7,6 @@ Also checks and updates the bluetooth service if needed.
|
|
|
7
7
|
|
|
8
8
|
import filecmp
|
|
9
9
|
import logging
|
|
10
|
-
import pwd
|
|
11
10
|
import subprocess
|
|
12
11
|
from pathlib import Path
|
|
13
12
|
|
|
@@ -18,13 +17,15 @@ USER = "pollen"
|
|
|
18
17
|
def check_and_fix_venvs_ownership(
|
|
19
18
|
venvs_path: str = "/venvs", custom_logger: logging.Logger | None = None
|
|
20
19
|
) -> None:
|
|
21
|
-
"""
|
|
20
|
+
"""For wireless units, check if files under venvs_path are owned by user pollen and fix if needed.
|
|
22
21
|
|
|
23
22
|
Args:
|
|
24
23
|
venvs_path: Path to the virtual environments directory (default: /venvs)
|
|
25
24
|
custom_logger: Optional logger to use instead of the module logger
|
|
26
25
|
|
|
27
26
|
"""
|
|
27
|
+
import pwd
|
|
28
|
+
|
|
28
29
|
try:
|
|
29
30
|
# Get pollen user's UID
|
|
30
31
|
pollen_uid = pwd.getpwnam(USER).pw_uid
|
|
@@ -81,39 +82,71 @@ def check_and_update_bluetooth_service() -> None:
|
|
|
81
82
|
|
|
82
83
|
Compares the source bluetooth_service.py with the installed version at
|
|
83
84
|
/bluetooth/bluetooth_service.py. If they differ, copies the new version
|
|
84
|
-
and restarts the bluetooth service.
|
|
85
|
+
and restarts the bluetooth service. Also syncs the commands/ folder.
|
|
85
86
|
"""
|
|
86
87
|
# This file: src/reachy_mini/utils/wireless_version/startup_check.py
|
|
87
88
|
# Target: src/reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py
|
|
88
89
|
# From parent: ../../daemon/app/services/bluetooth/bluetooth_service.py
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
bluetooth_dir = (
|
|
91
|
+
Path(__file__).parent
|
|
92
|
+
/ ".."
|
|
93
|
+
/ ".."
|
|
94
|
+
/ "daemon"
|
|
95
|
+
/ "app"
|
|
96
|
+
/ "services"
|
|
97
|
+
/ "bluetooth"
|
|
98
|
+
)
|
|
99
|
+
bluetooth_dir = bluetooth_dir.resolve()
|
|
100
|
+
source = bluetooth_dir / "bluetooth_service.py"
|
|
91
101
|
target = Path("/bluetooth/bluetooth_service.py")
|
|
102
|
+
source_commands = bluetooth_dir / "commands"
|
|
103
|
+
target_commands = Path("/bluetooth/commands")
|
|
92
104
|
|
|
93
105
|
if not source.exists():
|
|
94
106
|
print(f"Source bluetooth service not found at {source}")
|
|
95
107
|
return
|
|
96
108
|
|
|
97
|
-
|
|
109
|
+
needs_update = False
|
|
110
|
+
needs_commands_update = False
|
|
111
|
+
|
|
112
|
+
# Check if bluetooth_service.py needs update
|
|
98
113
|
if not target.exists():
|
|
99
114
|
print(f"Bluetooth service not installed at {target}, copying...")
|
|
100
115
|
needs_update = True
|
|
101
116
|
else:
|
|
102
|
-
# Compare files
|
|
103
117
|
try:
|
|
104
|
-
if filecmp.cmp(str(source), str(target), shallow=False):
|
|
105
|
-
print("Bluetooth service is up to date")
|
|
106
|
-
return
|
|
107
|
-
else:
|
|
118
|
+
if not filecmp.cmp(str(source), str(target), shallow=False):
|
|
108
119
|
print("Bluetooth service has changed, updating...")
|
|
109
120
|
needs_update = True
|
|
110
121
|
except Exception as e:
|
|
111
122
|
print(f"Error comparing bluetooth service files: {e}")
|
|
112
|
-
return
|
|
113
123
|
|
|
114
|
-
if
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
# Check if commands folder needs update
|
|
125
|
+
if source_commands.exists():
|
|
126
|
+
if not target_commands.exists():
|
|
127
|
+
print("Commands folder not installed, copying...")
|
|
128
|
+
needs_commands_update = True
|
|
129
|
+
else:
|
|
130
|
+
# Compare each command file
|
|
131
|
+
for cmd_file in source_commands.glob("*.sh"):
|
|
132
|
+
target_cmd = target_commands / cmd_file.name
|
|
133
|
+
if not target_cmd.exists():
|
|
134
|
+
needs_commands_update = True
|
|
135
|
+
break
|
|
136
|
+
try:
|
|
137
|
+
if not filecmp.cmp(str(cmd_file), str(target_cmd), shallow=False):
|
|
138
|
+
needs_commands_update = True
|
|
139
|
+
break
|
|
140
|
+
except Exception:
|
|
141
|
+
needs_commands_update = True
|
|
142
|
+
break
|
|
143
|
+
|
|
144
|
+
if not needs_update and not needs_commands_update:
|
|
145
|
+
print("Bluetooth service and commands are up to date")
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
if needs_update:
|
|
117
150
|
print(f"Copying {source} to {target}")
|
|
118
151
|
subprocess.run(
|
|
119
152
|
["sudo", "cp", str(source), str(target)],
|
|
@@ -123,22 +156,246 @@ def check_and_update_bluetooth_service() -> None:
|
|
|
123
156
|
)
|
|
124
157
|
print("Successfully copied bluetooth service")
|
|
125
158
|
|
|
126
|
-
|
|
127
|
-
print("
|
|
159
|
+
if needs_commands_update:
|
|
160
|
+
print(f"Syncing commands folder to {target_commands}")
|
|
161
|
+
subprocess.run(
|
|
162
|
+
["sudo", "mkdir", "-p", str(target_commands)],
|
|
163
|
+
check=True,
|
|
164
|
+
capture_output=True,
|
|
165
|
+
text=True,
|
|
166
|
+
)
|
|
167
|
+
subprocess.run(
|
|
168
|
+
["sudo", "cp", "-r", f"{source_commands}/.", str(target_commands)],
|
|
169
|
+
check=True,
|
|
170
|
+
capture_output=True,
|
|
171
|
+
text=True,
|
|
172
|
+
)
|
|
173
|
+
print("Successfully synced commands folder")
|
|
174
|
+
|
|
175
|
+
# Restart the bluetooth service
|
|
176
|
+
print("Restarting bluetooth service...")
|
|
177
|
+
subprocess.run(
|
|
178
|
+
["sudo", "systemctl", "restart", "reachy-mini-bluetooth"],
|
|
179
|
+
check=True,
|
|
180
|
+
capture_output=True,
|
|
181
|
+
text=True,
|
|
182
|
+
)
|
|
183
|
+
print("Successfully restarted bluetooth service")
|
|
184
|
+
except subprocess.CalledProcessError as e:
|
|
185
|
+
print(f"Failed to update bluetooth service: {e.stderr}")
|
|
186
|
+
except Exception as e:
|
|
187
|
+
print(f"Unexpected error while updating bluetooth service: {e}")
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def check_and_update_wireless_launcher() -> None:
|
|
191
|
+
"""Check if wireless daemon service needs updating and update if different.
|
|
192
|
+
|
|
193
|
+
Compares the source reachy-mini-daemon.service with the installed version.
|
|
194
|
+
If they differ, copies the new version and reloads systemd.
|
|
195
|
+
"""
|
|
196
|
+
source = (
|
|
197
|
+
Path(__file__).parent
|
|
198
|
+
/ ".."
|
|
199
|
+
/ ".."
|
|
200
|
+
/ "daemon"
|
|
201
|
+
/ "app"
|
|
202
|
+
/ "services"
|
|
203
|
+
/ "wireless"
|
|
204
|
+
/ "reachy-mini-daemon.service"
|
|
205
|
+
)
|
|
206
|
+
source = source.resolve()
|
|
207
|
+
target = Path("/etc/systemd/system/reachy-mini-daemon.service")
|
|
208
|
+
|
|
209
|
+
if not source.exists():
|
|
210
|
+
print(f"Source service file not found at {source}")
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
# Check if target exists
|
|
214
|
+
if not target.exists():
|
|
215
|
+
print(f"Wireless daemon service not installed at {target}")
|
|
216
|
+
return
|
|
217
|
+
|
|
218
|
+
# Compare files
|
|
219
|
+
try:
|
|
220
|
+
if filecmp.cmp(str(source), str(target), shallow=False):
|
|
221
|
+
print("Wireless daemon service is up to date")
|
|
222
|
+
return
|
|
223
|
+
else:
|
|
224
|
+
print("Wireless daemon service has changed, updating...")
|
|
225
|
+
except Exception as e:
|
|
226
|
+
print(f"Error comparing service files: {e}")
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
# Update service file
|
|
230
|
+
try:
|
|
231
|
+
print(f"Copying {source} to {target}")
|
|
232
|
+
subprocess.run(
|
|
233
|
+
["sudo", "cp", str(source), str(target)],
|
|
234
|
+
check=True,
|
|
235
|
+
capture_output=True,
|
|
236
|
+
text=True,
|
|
237
|
+
)
|
|
238
|
+
print("Successfully copied service file")
|
|
239
|
+
|
|
240
|
+
# Reload systemd daemon
|
|
241
|
+
print("Reloading systemd daemon...")
|
|
242
|
+
subprocess.run(
|
|
243
|
+
["sudo", "systemctl", "daemon-reload"],
|
|
244
|
+
check=True,
|
|
245
|
+
capture_output=True,
|
|
246
|
+
text=True,
|
|
247
|
+
)
|
|
248
|
+
print("Successfully reloaded systemd")
|
|
249
|
+
except subprocess.CalledProcessError as e:
|
|
250
|
+
print(f"Failed to update service: {e.stderr}")
|
|
251
|
+
except Exception as e:
|
|
252
|
+
print(f"Unexpected error while updating service: {e}")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def check_and_sync_apps_venv_sdk() -> None:
|
|
256
|
+
"""Check if the apps_venv SDK version matches daemon and update if needed.
|
|
257
|
+
|
|
258
|
+
This ensures that when the daemon is updated, the SDK in the apps_venv
|
|
259
|
+
is also updated to match, so apps get the latest fixes automatically.
|
|
260
|
+
"""
|
|
261
|
+
from importlib.metadata import version
|
|
262
|
+
|
|
263
|
+
# Get daemon venv SDK version
|
|
264
|
+
try:
|
|
265
|
+
daemon_version = version("reachy_mini")
|
|
266
|
+
except Exception as e:
|
|
267
|
+
print(f"Could not get daemon SDK version: {e}")
|
|
268
|
+
return
|
|
269
|
+
|
|
270
|
+
# Path to apps_venv python
|
|
271
|
+
apps_venv_python = Path("/venvs/apps_venv/bin/python")
|
|
272
|
+
if not apps_venv_python.exists():
|
|
273
|
+
print("apps_venv not found, skipping SDK sync")
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
# Get apps_venv SDK version
|
|
277
|
+
try:
|
|
278
|
+
result = subprocess.run(
|
|
279
|
+
[
|
|
280
|
+
str(apps_venv_python),
|
|
281
|
+
"-c",
|
|
282
|
+
"from importlib.metadata import version; print(version('reachy_mini'))",
|
|
283
|
+
],
|
|
284
|
+
capture_output=True,
|
|
285
|
+
text=True,
|
|
286
|
+
timeout=10,
|
|
287
|
+
)
|
|
288
|
+
if result.returncode != 0:
|
|
289
|
+
print(f"Could not get apps_venv SDK version: {result.stderr}")
|
|
290
|
+
return
|
|
291
|
+
apps_version = result.stdout.strip()
|
|
292
|
+
except subprocess.TimeoutExpired:
|
|
293
|
+
print("Timeout getting apps_venv SDK version")
|
|
294
|
+
return
|
|
295
|
+
except Exception as e:
|
|
296
|
+
print(f"Error getting apps_venv SDK version: {e}")
|
|
297
|
+
return
|
|
298
|
+
|
|
299
|
+
print(f"Daemon SDK version: {daemon_version}")
|
|
300
|
+
print(f"Apps venv SDK version: {apps_version}")
|
|
301
|
+
|
|
302
|
+
if daemon_version == apps_version:
|
|
303
|
+
print("Apps venv SDK is up to date")
|
|
304
|
+
return
|
|
305
|
+
|
|
306
|
+
# Versions differ, update apps_venv
|
|
307
|
+
print(f"Updating apps_venv SDK from {apps_version} to {daemon_version}...")
|
|
308
|
+
try:
|
|
309
|
+
# Use uv if available, otherwise pip
|
|
310
|
+
import shutil
|
|
311
|
+
|
|
312
|
+
apps_venv_pip = Path("/venvs/apps_venv/bin/pip")
|
|
313
|
+
use_uv = shutil.which("uv") is not None
|
|
314
|
+
|
|
315
|
+
if use_uv:
|
|
316
|
+
install_cmd = [
|
|
317
|
+
"uv",
|
|
318
|
+
"pip",
|
|
319
|
+
"install",
|
|
320
|
+
"--python",
|
|
321
|
+
str(apps_venv_python),
|
|
322
|
+
f"reachy-mini[gstreamer]=={daemon_version}",
|
|
323
|
+
]
|
|
324
|
+
else:
|
|
325
|
+
install_cmd = [
|
|
326
|
+
str(apps_venv_pip),
|
|
327
|
+
"install",
|
|
328
|
+
f"reachy-mini[gstreamer]=={daemon_version}",
|
|
329
|
+
]
|
|
330
|
+
|
|
331
|
+
result = subprocess.run(
|
|
332
|
+
install_cmd,
|
|
333
|
+
capture_output=True,
|
|
334
|
+
text=True,
|
|
335
|
+
timeout=300, # 5 minute timeout for install
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
if result.returncode == 0:
|
|
339
|
+
print(f"Successfully updated apps_venv SDK to {daemon_version}")
|
|
340
|
+
else:
|
|
341
|
+
print(f"Failed to update apps_venv SDK: {result.stderr}")
|
|
342
|
+
except subprocess.TimeoutExpired:
|
|
343
|
+
print("Timeout updating apps_venv SDK")
|
|
344
|
+
except Exception as e:
|
|
345
|
+
print(f"Error updating apps_venv SDK: {e}")
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def check_and_fix_restore_venv() -> None:
|
|
349
|
+
"""Check if restore venv has editable install and fix if needed.
|
|
350
|
+
|
|
351
|
+
The restore partition at /restore/venvs should have a proper PyPI install,
|
|
352
|
+
not an editable install. If an editable install is detected, reinstall
|
|
353
|
+
from PyPI with a known good version.
|
|
354
|
+
"""
|
|
355
|
+
restore_python = Path("/restore/venvs/mini_daemon/bin/python")
|
|
356
|
+
|
|
357
|
+
if not restore_python.exists():
|
|
358
|
+
print("Restore venv not found, skipping")
|
|
359
|
+
return
|
|
360
|
+
|
|
361
|
+
# Check if editable install
|
|
362
|
+
try:
|
|
363
|
+
result = subprocess.run(
|
|
364
|
+
[str(restore_python), "-m", "pip", "show", "reachy-mini"],
|
|
365
|
+
capture_output=True,
|
|
366
|
+
text=True,
|
|
367
|
+
timeout=30,
|
|
368
|
+
)
|
|
369
|
+
except subprocess.TimeoutExpired:
|
|
370
|
+
print("Timeout checking restore venv")
|
|
371
|
+
return
|
|
372
|
+
except Exception as e:
|
|
373
|
+
print(f"Error checking restore venv: {e}")
|
|
374
|
+
return
|
|
375
|
+
|
|
376
|
+
if "Editable project location" in result.stdout:
|
|
377
|
+
print("Legacy editable install detected in restore venv, reinstalling...")
|
|
378
|
+
try:
|
|
128
379
|
subprocess.run(
|
|
129
|
-
["
|
|
380
|
+
[str(restore_python), "-m", "pip", "install", "reachy-mini==1.2.8"],
|
|
130
381
|
check=True,
|
|
131
382
|
capture_output=True,
|
|
132
383
|
text=True,
|
|
384
|
+
timeout=300,
|
|
133
385
|
)
|
|
134
|
-
print("Successfully
|
|
386
|
+
print("Successfully reinstalled reachy-mini in restore venv")
|
|
135
387
|
except subprocess.CalledProcessError as e:
|
|
136
|
-
print(f"Failed to
|
|
388
|
+
print(f"Failed to reinstall in restore venv: {e.stderr}")
|
|
389
|
+
except subprocess.TimeoutExpired:
|
|
390
|
+
print("Timeout reinstalling in restore venv")
|
|
137
391
|
except Exception as e:
|
|
138
|
-
print(f"
|
|
392
|
+
print(f"Error reinstalling in restore venv: {e}")
|
|
393
|
+
else:
|
|
394
|
+
print("Restore venv install is correct")
|
|
139
395
|
|
|
140
396
|
|
|
141
397
|
if __name__ == "__main__":
|
|
142
398
|
logging.basicConfig(level=logging.INFO)
|
|
143
399
|
check_and_fix_venvs_ownership()
|
|
144
400
|
check_and_update_bluetooth_service()
|
|
401
|
+
check_and_sync_apps_venv_sdk()
|
|
@@ -1,20 +1,63 @@
|
|
|
1
1
|
"""Module to handle software updates for the Reachy Mini wireless."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
4
6
|
|
|
5
7
|
from .utils import call_logger_wrapper
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
async def update_reachy_mini(pre_release: bool, logger: logging.Logger) -> None:
|
|
9
|
-
"""Perform a software update by upgrading the reachy_mini package and restarting the daemon.
|
|
11
|
+
"""Perform a software update by upgrading the reachy_mini package and restarting the daemon.
|
|
12
|
+
|
|
13
|
+
This updates both:
|
|
14
|
+
- The daemon venv (where the daemon runs)
|
|
15
|
+
- The apps_venv (where apps run) - to keep SDK in sync
|
|
16
|
+
"""
|
|
10
17
|
extra_args = []
|
|
11
18
|
if pre_release:
|
|
12
19
|
extra_args.append("--pre")
|
|
13
20
|
|
|
21
|
+
# Update daemon venv
|
|
22
|
+
logger.info("Updating daemon venv...")
|
|
14
23
|
await call_logger_wrapper(
|
|
15
24
|
["pip", "install", "--upgrade", "reachy_mini[wireless-version]"] + extra_args,
|
|
16
25
|
logger,
|
|
17
26
|
)
|
|
27
|
+
|
|
28
|
+
# Update apps_venv if it exists
|
|
29
|
+
apps_venv_python = Path("/venvs/apps_venv/bin/python")
|
|
30
|
+
if apps_venv_python.exists():
|
|
31
|
+
logger.info("Updating apps_venv SDK...")
|
|
32
|
+
|
|
33
|
+
# Use uv if available for faster installs
|
|
34
|
+
use_uv = shutil.which("uv") is not None
|
|
35
|
+
|
|
36
|
+
if use_uv:
|
|
37
|
+
install_cmd = [
|
|
38
|
+
"uv",
|
|
39
|
+
"pip",
|
|
40
|
+
"install",
|
|
41
|
+
"--python",
|
|
42
|
+
str(apps_venv_python),
|
|
43
|
+
"--upgrade",
|
|
44
|
+
"reachy-mini[gstreamer]",
|
|
45
|
+
] + extra_args
|
|
46
|
+
else:
|
|
47
|
+
apps_venv_pip = Path("/venvs/apps_venv/bin/pip")
|
|
48
|
+
install_cmd = [
|
|
49
|
+
str(apps_venv_pip),
|
|
50
|
+
"install",
|
|
51
|
+
"--upgrade",
|
|
52
|
+
"reachy-mini[gstreamer]",
|
|
53
|
+
] + extra_args
|
|
54
|
+
|
|
55
|
+
await call_logger_wrapper(install_cmd, logger)
|
|
56
|
+
logger.info("Apps venv SDK updated successfully")
|
|
57
|
+
else:
|
|
58
|
+
logger.info("apps_venv not found, skipping apps venv update")
|
|
59
|
+
|
|
60
|
+
# Restart daemon to apply updates
|
|
18
61
|
await call_logger_wrapper(
|
|
19
62
|
["sudo", "systemctl", "restart", "reachy-mini-daemon"], logger
|
|
20
63
|
)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reachy_mini
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.11
|
|
4
4
|
Author-email: Pollen Robotics <contact@pollen-robotics.com>
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Dist: numpy>=2.2.5
|
|
9
9
|
Requires-Dist: scipy<2.0.0,>=1.15.3
|
|
10
|
-
Requires-Dist: reachy_mini_motor_controller>=1.
|
|
10
|
+
Requires-Dist: reachy_mini_motor_controller>=1.5.3
|
|
11
11
|
Requires-Dist: eclipse-zenoh~=1.7.0
|
|
12
12
|
Requires-Dist: opencv-python<=5.0
|
|
13
13
|
Requires-Dist: cv2_enumerate_cameras>=1.2.1
|
|
@@ -16,7 +16,7 @@ Requires-Dist: jinja2
|
|
|
16
16
|
Requires-Dist: uvicorn[standard]
|
|
17
17
|
Requires-Dist: fastapi
|
|
18
18
|
Requires-Dist: pyserial
|
|
19
|
-
Requires-Dist: huggingface-hub==
|
|
19
|
+
Requires-Dist: huggingface-hub==1.3.0
|
|
20
20
|
Requires-Dist: sounddevice==0.5.1
|
|
21
21
|
Requires-Dist: soundfile==0.13.1
|
|
22
22
|
Requires-Dist: reachy-mini-rust-kinematics>=1.0.3
|
|
@@ -30,7 +30,9 @@ Requires-Dist: rich
|
|
|
30
30
|
Requires-Dist: questionary
|
|
31
31
|
Requires-Dist: websockets<16,>=12
|
|
32
32
|
Requires-Dist: toml
|
|
33
|
-
Requires-Dist: rustypot
|
|
33
|
+
Requires-Dist: rustypot>=1.4.2
|
|
34
|
+
Requires-Dist: pyyaml>=6.0
|
|
35
|
+
Requires-Dist: requests>=2.28.0
|
|
34
36
|
Provides-Extra: dev
|
|
35
37
|
Requires-Dist: pytest; extra == "dev"
|
|
36
38
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
@@ -40,7 +42,6 @@ Requires-Dist: mujoco==3.3.0; extra == "dev"
|
|
|
40
42
|
Requires-Dist: placo==0.9.14; extra == "dev"
|
|
41
43
|
Requires-Dist: pre-commit; extra == "dev"
|
|
42
44
|
Requires-Dist: mypy==1.18.2; extra == "dev"
|
|
43
|
-
Requires-Dist: rustypot>=1.4.0; extra == "dev"
|
|
44
45
|
Requires-Dist: types-requests; extra == "dev"
|
|
45
46
|
Requires-Dist: types-toml; extra == "dev"
|
|
46
47
|
Requires-Dist: rerun-sdk>=0.27.2; extra == "dev"
|
|
@@ -98,7 +99,7 @@ Dynamic: license-file
|
|
|
98
99
|
Reachy Mini comes with an app store powered by Hugging Face Spaces. You can install these apps directly from your robot's dashboard with one click!
|
|
99
100
|
|
|
100
101
|
* **🗣️ [Conversation App](https://huggingface.co/spaces/pollen-robotics/reachy_mini_conversation_app):** Talk naturally with Reachy Mini (powered by LLMs).
|
|
101
|
-
* **📻 [Radio](https://huggingface.co/spaces/pollen-robotics/reachy_mini_radio):** Listen to the radio with Reachy Mini
|
|
102
|
+
* **📻 [Radio](https://huggingface.co/spaces/pollen-robotics/reachy_mini_radio):** Listen to the radio with Reachy Mini!
|
|
102
103
|
* **👋 [Hand Tracker](https://huggingface.co/spaces/pollen-robotics/hand_tracker_v2):** The robot follows your hand movements in real-time.
|
|
103
104
|
|
|
104
105
|
👉 [**Browse all apps on Hugging Face**](https://hf.co/reachy-mini/#/apps)
|