reachy-mini 1.2.5rc1__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/__init__.py +4 -0
- reachy_mini/apps/__init__.py +25 -0
- reachy_mini/apps/app.py +258 -0
- reachy_mini/apps/assistant.py +787 -0
- reachy_mini/apps/manager.py +312 -0
- reachy_mini/apps/sources/__init__.py +4 -0
- reachy_mini/apps/sources/hf_space.py +106 -0
- reachy_mini/apps/sources/local_common_venv.py +567 -0
- reachy_mini/apps/templates/README.md.j2 +12 -0
- reachy_mini/apps/templates/gitignore.j2 +3 -0
- reachy_mini/apps/templates/index.html.j2 +40 -0
- reachy_mini/apps/templates/main.py.j2 +74 -0
- reachy_mini/apps/templates/pyproject.toml.j2 +28 -0
- reachy_mini/apps/templates/static/index.html.j2 +27 -0
- reachy_mini/apps/templates/static/main.js.j2 +47 -0
- reachy_mini/apps/templates/static/style.css.j2 +25 -0
- reachy_mini/apps/templates/style.css.j2 +411 -0
- reachy_mini/apps/utils.py +30 -0
- reachy_mini/assets/config/hardware_config.yaml +164 -0
- reachy_mini/assets/confused1.wav +0 -0
- reachy_mini/assets/count.wav +0 -0
- reachy_mini/assets/dance1.wav +0 -0
- reachy_mini/assets/firmware/CHANGELOG.md +15 -0
- reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.2.bin +0 -0
- reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.3.bin +0 -0
- reachy_mini/assets/firmware/update.sh +9 -0
- reachy_mini/assets/go_sleep.wav +0 -0
- reachy_mini/assets/impatient1.wav +0 -0
- reachy_mini/assets/kinematics_data.json +253 -0
- reachy_mini/assets/models/fknetwork.dynamic.onnx +0 -0
- reachy_mini/assets/models/fknetwork.onnx +0 -0
- reachy_mini/assets/models/fknetwork_int8.onnx +0 -0
- reachy_mini/assets/models/iknetwork.onnx +0 -0
- reachy_mini/assets/wake_up.wav +0 -0
- reachy_mini/daemon/__init__.py +1 -0
- reachy_mini/daemon/app/__init__.py +1 -0
- reachy_mini/daemon/app/bg_job_register.py +142 -0
- reachy_mini/daemon/app/dashboard/static/assets/KO-cartoon-static.svg +40 -0
- reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon-static.svg +42 -0
- reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/go-to-sleep-cartoon.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon-static.svg +50 -0
- reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-awake.svg +18 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-connection-lost-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-go-to-sleep-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko.svg +22 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping-static.svg +41 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping.svg +18 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-wake-up-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/css/app.css +1433 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Archivo-Italic-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Archivo-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Asap-Italic-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Asap-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
- reachy_mini/daemon/app/dashboard/static/js/apps.js +323 -0
- reachy_mini/daemon/app/dashboard/static/js/appstore.js +167 -0
- reachy_mini/daemon/app/dashboard/static/js/daemon.js +169 -0
- reachy_mini/daemon/app/dashboard/static/js/health_check.js +9 -0
- reachy_mini/daemon/app/dashboard/static/js/move_player.js +132 -0
- reachy_mini/daemon/app/dashboard/static/js/notification.js +41 -0
- reachy_mini/daemon/app/dashboard/static/js/update.js +132 -0
- reachy_mini/daemon/app/dashboard/static/js/volume_control.js +252 -0
- reachy_mini/daemon/app/dashboard/static/js/wifi.js +176 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/README.md +15 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/package-lock.json +1127 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/package.json +6 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/pnpm-lock.yaml +608 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/postcss.config.js +6 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/styles/app.css +185 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/tailwind.config.js +11 -0
- reachy_mini/daemon/app/dashboard/templates/base.html +21 -0
- reachy_mini/daemon/app/dashboard/templates/index.html +20 -0
- reachy_mini/daemon/app/dashboard/templates/sections/apps.html +8 -0
- reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +35 -0
- reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +45 -0
- reachy_mini/daemon/app/dashboard/templates/sections/move_player.html +121 -0
- reachy_mini/daemon/app/dashboard/templates/sections/notification.html +19 -0
- reachy_mini/daemon/app/dashboard/templates/sections/update.html +54 -0
- reachy_mini/daemon/app/dashboard/templates/sections/wifi.html +46 -0
- reachy_mini/daemon/app/dashboard/templates/settings.html +14 -0
- reachy_mini/daemon/app/dependencies.py +41 -0
- reachy_mini/daemon/app/main.py +469 -0
- reachy_mini/daemon/app/models.py +149 -0
- reachy_mini/daemon/app/routers/apps.py +114 -0
- reachy_mini/daemon/app/routers/daemon.py +85 -0
- reachy_mini/daemon/app/routers/kinematics.py +57 -0
- reachy_mini/daemon/app/routers/motors.py +41 -0
- reachy_mini/daemon/app/routers/move.py +265 -0
- reachy_mini/daemon/app/routers/state.py +146 -0
- reachy_mini/daemon/app/routers/update.py +86 -0
- reachy_mini/daemon/app/routers/volume.py +423 -0
- reachy_mini/daemon/app/routers/wifi_config.py +219 -0
- reachy_mini/daemon/app/services/__init__.py +1 -0
- reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py +796 -0
- reachy_mini/daemon/app/services/bluetooth/commands/HOTSPOT.sh +7 -0
- reachy_mini/daemon/app/services/bluetooth/commands/RESTART_DAEMON.sh +4 -0
- reachy_mini/daemon/app/services/bluetooth/commands/SOFTWARE_RESET.sh +7 -0
- reachy_mini/daemon/app/services/bluetooth/install_service_bluetooth.sh +39 -0
- reachy_mini/daemon/app/services/gpio_shutdown/__init__.py +1 -0
- reachy_mini/daemon/app/services/gpio_shutdown/install_service.sh +33 -0
- reachy_mini/daemon/app/services/gpio_shutdown/launcher.sh +3 -0
- reachy_mini/daemon/app/services/gpio_shutdown/shutdown_monitor.py +28 -0
- reachy_mini/daemon/app/services/wireless/generate_asoundrc.sh +70 -0
- reachy_mini/daemon/app/services/wireless/install_service.sh +33 -0
- reachy_mini/daemon/app/services/wireless/launcher.sh +5 -0
- reachy_mini/daemon/backend/__init__.py +1 -0
- reachy_mini/daemon/backend/abstract.py +815 -0
- reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
- reachy_mini/daemon/backend/mujoco/backend.py +395 -0
- reachy_mini/daemon/backend/mujoco/utils.py +59 -0
- reachy_mini/daemon/backend/mujoco/video_udp.py +57 -0
- reachy_mini/daemon/backend/robot/__init__.py +8 -0
- reachy_mini/daemon/backend/robot/backend.py +597 -0
- reachy_mini/daemon/daemon.py +651 -0
- reachy_mini/daemon/utils.py +116 -0
- reachy_mini/descriptions/reachy_mini/mjcf/additional.xml +6 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/README.m +1 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/croissant_1k.obj +5021 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/textures/croissant_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/food_apple_01_1k.obj +18045 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/textures/food_apple_01_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/rubber_duck_toy_1k.obj +8940 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/textures/rubber_duck_toy_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/textures/wooden_table_02_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/wooden_table_02_1k.obj +485 -0
- reachy_mini/descriptions/reachy_mini/mjcf/config.json +21 -0
- reachy_mini/descriptions/reachy_mini/mjcf/joints_properties.xml +29 -0
- reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml +642 -0
- reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml.bak +442 -0
- reachy_mini/descriptions/reachy_mini/mjcf/scene.xml +24 -0
- reachy_mini/descriptions/reachy_mini/mjcf/scenes/empty.xml +27 -0
- reachy_mini/descriptions/reachy_mini/mjcf/scenes/minimal.xml +132 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arm.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/ball.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/ball.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/README.m +1 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/foot.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/foot.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/shape.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/shape.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/config.json +18 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot.urdf +3281 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot.urdf.bak +3282 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot_no_collision.urdf +2316 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot_simple_collision.urdf +2399 -0
- reachy_mini/io/__init__.py +15 -0
- reachy_mini/io/abstract.py +70 -0
- reachy_mini/io/audio_ws.py +242 -0
- reachy_mini/io/protocol.py +44 -0
- reachy_mini/io/video_ws.py +135 -0
- reachy_mini/io/ws_controller.py +120 -0
- reachy_mini/io/zenoh_client.py +273 -0
- reachy_mini/io/zenoh_server.py +230 -0
- reachy_mini/kinematics/__init__.py +68 -0
- reachy_mini/kinematics/analytical_kinematics.py +151 -0
- reachy_mini/kinematics/nn_kinematics.py +109 -0
- reachy_mini/kinematics/placo_kinematics.py +656 -0
- reachy_mini/media/__init__.py +1 -0
- reachy_mini/media/audio_base.py +111 -0
- reachy_mini/media/audio_control_utils.py +455 -0
- reachy_mini/media/audio_gstreamer.py +272 -0
- reachy_mini/media/audio_sounddevice.py +321 -0
- reachy_mini/media/audio_utils.py +114 -0
- reachy_mini/media/camera_base.py +100 -0
- reachy_mini/media/camera_constants.py +152 -0
- reachy_mini/media/camera_gstreamer.py +231 -0
- reachy_mini/media/camera_opencv.py +89 -0
- reachy_mini/media/camera_utils.py +111 -0
- reachy_mini/media/media_manager.py +281 -0
- reachy_mini/media/webrtc_client_gstreamer.py +288 -0
- reachy_mini/media/webrtc_daemon.py +334 -0
- reachy_mini/motion/__init__.py +4 -0
- reachy_mini/motion/goto.py +71 -0
- reachy_mini/motion/move.py +43 -0
- reachy_mini/motion/recorded_move.py +146 -0
- reachy_mini/reachy_mini.py +753 -0
- reachy_mini/tools/reflash_motors.py +116 -0
- reachy_mini/tools/setup_motor.py +422 -0
- reachy_mini/tools/setup_motor_rpi.py +108 -0
- reachy_mini/utils/__init__.py +46 -0
- reachy_mini/utils/constants.py +9 -0
- reachy_mini/utils/hardware_config/__init__.py +1 -0
- reachy_mini/utils/hardware_config/parser.py +65 -0
- reachy_mini/utils/interpolation.py +227 -0
- reachy_mini/utils/parse_urdf_for_kinematics.py +110 -0
- reachy_mini/utils/rerun.py +320 -0
- reachy_mini/utils/wireless_version/__init__.py +1 -0
- reachy_mini/utils/wireless_version/startup_check.py +144 -0
- reachy_mini/utils/wireless_version/update.py +20 -0
- reachy_mini/utils/wireless_version/update_available.py +61 -0
- reachy_mini/utils/wireless_version/utils.py +39 -0
- reachy_mini-1.2.5rc1.dist-info/METADATA +161 -0
- reachy_mini-1.2.5rc1.dist-info/RECORD +479 -0
- reachy_mini-1.2.5rc1.dist-info/WHEEL +5 -0
- reachy_mini-1.2.5rc1.dist-info/entry_points.txt +4 -0
- reachy_mini-1.2.5rc1.dist-info/licenses/LICENSE +201 -0
- reachy_mini-1.2.5rc1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"""Rerun logging for Reachy Mini.
|
|
2
|
+
|
|
3
|
+
This module provides functionality to log the state of the Reachy Mini robot to Rerun,
|
|
4
|
+
a tool for visualizing and debugging robotic systems.
|
|
5
|
+
|
|
6
|
+
It includes methods to log joint positions, camera images, and other relevant data.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
import os
|
|
12
|
+
import tempfile
|
|
13
|
+
import time
|
|
14
|
+
from threading import Event, Thread
|
|
15
|
+
from typing import Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
import numpy as np
|
|
18
|
+
import requests
|
|
19
|
+
import rerun as rr
|
|
20
|
+
from scipy.spatial.transform import Rotation as R
|
|
21
|
+
from urdf_parser_py import urdf
|
|
22
|
+
|
|
23
|
+
from reachy_mini.kinematics.placo_kinematics import PlacoKinematics
|
|
24
|
+
from reachy_mini.media.media_manager import MediaBackend
|
|
25
|
+
from reachy_mini.reachy_mini import ReachyMini
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Rerun:
|
|
29
|
+
"""Rerun logging for Reachy Mini."""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
reachymini: ReachyMini,
|
|
34
|
+
app_id: str = "reachy_mini_rerun",
|
|
35
|
+
spawn: bool = True,
|
|
36
|
+
):
|
|
37
|
+
"""Initialize the Rerun logging for Reachy Mini.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
reachymini (ReachyMini): The Reachy Mini instance to log.
|
|
41
|
+
app_id (str): The application ID for Rerun. Defaults to reachy_mini_daemon.
|
|
42
|
+
spawn (bool): If True, spawn the Rerun server. Defaults to True.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
rr.init(app_id, spawn=spawn)
|
|
46
|
+
self.app_id = app_id
|
|
47
|
+
self._reachymini = reachymini
|
|
48
|
+
self.logger = logging.getLogger(__name__)
|
|
49
|
+
self.logger.setLevel(reachymini.logger.getEffectiveLevel())
|
|
50
|
+
|
|
51
|
+
self._robot_ip = "localhost"
|
|
52
|
+
if self._reachymini.client.get_status()["wireless_version"]:
|
|
53
|
+
self._robot_ip = self._reachymini.client.get_status()["wlan_ip"]
|
|
54
|
+
|
|
55
|
+
self.recording = rr.get_global_data_recording()
|
|
56
|
+
|
|
57
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
58
|
+
|
|
59
|
+
urdf_path = os.path.join(
|
|
60
|
+
script_dir, "../descriptions/reachy_mini/urdf/robot_no_collision.urdf"
|
|
61
|
+
)
|
|
62
|
+
asset_path = os.path.join(script_dir, "../descriptions/reachy_mini/urdf")
|
|
63
|
+
|
|
64
|
+
fixed_urdf = self.set_absolute_path_to_urdf(urdf_path, asset_path)
|
|
65
|
+
self.logger.debug(
|
|
66
|
+
f"Using URDF file: {fixed_urdf} with absolute paths for Rerun."
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
self.head_kinematics = PlacoKinematics(fixed_urdf)
|
|
70
|
+
|
|
71
|
+
self.urdf_model = urdf.URDF.from_xml_file(fixed_urdf)
|
|
72
|
+
self._joints_by_name: Dict[str, urdf.Joint] = {
|
|
73
|
+
joint.name: joint for joint in self.urdf_model.joints
|
|
74
|
+
}
|
|
75
|
+
self._entity_paths = UrdfEntityPaths(self.urdf_model, "ReachyMini")
|
|
76
|
+
|
|
77
|
+
rr.set_time("reachymini", timestamp=time.time(), recording=self.recording)
|
|
78
|
+
|
|
79
|
+
# Use the native URDF loader in Rerun to visualize Reachy Mini's model
|
|
80
|
+
# Logging as non-static to allow updating joint positions
|
|
81
|
+
rr.log_file_from_path(
|
|
82
|
+
fixed_urdf,
|
|
83
|
+
static=False,
|
|
84
|
+
entity_path_prefix=self._entity_paths.prefix,
|
|
85
|
+
recording=self.recording,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
self.running = Event()
|
|
89
|
+
self.thread_log_camera: Optional[Thread] = None
|
|
90
|
+
if (
|
|
91
|
+
reachymini.media.backend == MediaBackend.GSTREAMER
|
|
92
|
+
or reachymini.media.backend == MediaBackend.DEFAULT
|
|
93
|
+
):
|
|
94
|
+
self.thread_log_camera = Thread(target=self.log_camera, daemon=True)
|
|
95
|
+
self.thread_log_movements = Thread(target=self.log_movements, daemon=True)
|
|
96
|
+
|
|
97
|
+
def set_absolute_path_to_urdf(self, urdf_path: str, abs_path: str) -> str:
|
|
98
|
+
"""Set the absolute paths in the URDF file. Rerun cannot read the "package://" paths."""
|
|
99
|
+
with open(urdf_path, "r") as f:
|
|
100
|
+
urdf_content = f.read()
|
|
101
|
+
urdf_content_mod = urdf_content.replace("package://", f"file://{abs_path}/")
|
|
102
|
+
|
|
103
|
+
with tempfile.NamedTemporaryFile("w", delete=False, suffix=".urdf") as tmp_file:
|
|
104
|
+
tmp_file.write(urdf_content_mod)
|
|
105
|
+
return tmp_file.name
|
|
106
|
+
|
|
107
|
+
def start(self) -> None:
|
|
108
|
+
"""Start the Rerun logging thread."""
|
|
109
|
+
if self.thread_log_camera is not None:
|
|
110
|
+
self.thread_log_camera.start()
|
|
111
|
+
self.thread_log_movements.start()
|
|
112
|
+
|
|
113
|
+
def stop(self) -> None:
|
|
114
|
+
"""Stop the Rerun logging thread."""
|
|
115
|
+
self.running.set()
|
|
116
|
+
|
|
117
|
+
def _get_joint(self, joint_name: str) -> urdf.Joint:
|
|
118
|
+
try:
|
|
119
|
+
return self._joints_by_name[joint_name]
|
|
120
|
+
except KeyError as exc:
|
|
121
|
+
raise RuntimeError(f"Invalid joint name: {joint_name}") from exc
|
|
122
|
+
|
|
123
|
+
def _joint_entity_path(self, joint: urdf.Joint) -> str:
|
|
124
|
+
return self._entity_paths.joint_paths[joint.name]
|
|
125
|
+
|
|
126
|
+
def log_camera(self) -> None:
|
|
127
|
+
"""Log the camera image to Rerun."""
|
|
128
|
+
if self._reachymini.media.camera is None:
|
|
129
|
+
self.logger.warning("Camera is not initialized.")
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
self.logger.info("Starting camera logging to Rerun.")
|
|
133
|
+
|
|
134
|
+
while not self.running.is_set():
|
|
135
|
+
rr.set_time("reachymini", timestamp=time.time(), recording=self.recording)
|
|
136
|
+
frame = self._reachymini.media.get_frame()
|
|
137
|
+
if frame is not None:
|
|
138
|
+
if isinstance(frame, bytes):
|
|
139
|
+
self.logger.warning(
|
|
140
|
+
"Received frame is jpeg. Please use default backend."
|
|
141
|
+
)
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
else:
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
K = np.array(
|
|
148
|
+
[
|
|
149
|
+
[550.3564, 0.0, 638.0112],
|
|
150
|
+
[0.0, 549.1653, 364.589],
|
|
151
|
+
[0.0, 0.0, 1.0],
|
|
152
|
+
]
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
cam_joint = self._get_joint("camera_optical_frame")
|
|
156
|
+
cam_path = self._joint_entity_path(cam_joint)
|
|
157
|
+
rr.log(
|
|
158
|
+
f"{cam_path}/image",
|
|
159
|
+
rr.Pinhole(
|
|
160
|
+
image_from_camera=rr.datatypes.Mat3x3(K),
|
|
161
|
+
width=frame.shape[1],
|
|
162
|
+
height=frame.shape[0],
|
|
163
|
+
image_plane_distance=0.8,
|
|
164
|
+
camera_xyz=rr.ViewCoordinates.RDF,
|
|
165
|
+
),
|
|
166
|
+
rr.Image(frame, color_model="bgr").compress(),
|
|
167
|
+
recording=self.recording,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
time.sleep(0.03) # ~30fps
|
|
171
|
+
|
|
172
|
+
def _log_joint_angle(
|
|
173
|
+
self,
|
|
174
|
+
joint_name: str,
|
|
175
|
+
angle: float,
|
|
176
|
+
axis: list[float] | None = None,
|
|
177
|
+
) -> None:
|
|
178
|
+
"""Log the joint angle to Rerun."""
|
|
179
|
+
joint = self._get_joint(joint_name)
|
|
180
|
+
joint_path = self._joint_entity_path(joint)
|
|
181
|
+
|
|
182
|
+
base_euler = joint.origin.rotation or [0.0, 0.0, 0.0]
|
|
183
|
+
|
|
184
|
+
# if we specify an axis override, use it; otherwise, use the joint's defined axis
|
|
185
|
+
effective_axis = (
|
|
186
|
+
np.array(axis)
|
|
187
|
+
if axis is not None
|
|
188
|
+
else np.array(joint.axis or [1.0, 0.0, 0.0])
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
target_euler = np.array(base_euler) + (effective_axis * angle)
|
|
192
|
+
target_translation = joint.origin.xyz or [0.0, 0.0, 0.0]
|
|
193
|
+
|
|
194
|
+
rr.log(
|
|
195
|
+
joint_path,
|
|
196
|
+
rr.Transform3D(
|
|
197
|
+
translation=target_translation,
|
|
198
|
+
quaternion=R.from_euler("xyz", target_euler).as_quat(),
|
|
199
|
+
),
|
|
200
|
+
recording=self.recording,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def log_movements(self) -> None:
|
|
204
|
+
"""Log the movement data to Rerun."""
|
|
205
|
+
url = f"http://{self._robot_ip}:8000/api/state/full"
|
|
206
|
+
|
|
207
|
+
params = {
|
|
208
|
+
"with_control_mode": "false",
|
|
209
|
+
"with_head_pose": "false",
|
|
210
|
+
"with_target_head_pose": "false",
|
|
211
|
+
"with_head_joints": "true",
|
|
212
|
+
"with_target_head_joints": "false",
|
|
213
|
+
"with_body_yaw": "false", # already in head_joints
|
|
214
|
+
"with_target_body_yaw": "false",
|
|
215
|
+
"with_antenna_positions": "true",
|
|
216
|
+
"with_target_antenna_positions": "false",
|
|
217
|
+
"use_pose_matrix": "false",
|
|
218
|
+
"with_passive_joints": "true",
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
while not self.running.is_set():
|
|
222
|
+
msg = requests.get(url, params=params)
|
|
223
|
+
|
|
224
|
+
if msg.status_code != 200:
|
|
225
|
+
self.logger.error(
|
|
226
|
+
f"Request failed with status {msg.status_code}: {msg.text}"
|
|
227
|
+
)
|
|
228
|
+
time.sleep(0.1)
|
|
229
|
+
continue
|
|
230
|
+
try:
|
|
231
|
+
data = json.loads(msg.text)
|
|
232
|
+
self.logger.debug(f"Data: {data}")
|
|
233
|
+
except Exception:
|
|
234
|
+
continue
|
|
235
|
+
|
|
236
|
+
rr.set_time("reachymini", timestamp=time.time(), recording=self.recording)
|
|
237
|
+
|
|
238
|
+
if "antennas_position" in data and data["antennas_position"] is not None:
|
|
239
|
+
antennas = data["antennas_position"]
|
|
240
|
+
if antennas is not None:
|
|
241
|
+
self._log_joint_angle("left_antenna", antennas[0])
|
|
242
|
+
self._log_joint_angle("right_antenna", antennas[1])
|
|
243
|
+
|
|
244
|
+
if "head_joints" in data and data["head_joints"] is not None:
|
|
245
|
+
head_joints = data["head_joints"]
|
|
246
|
+
|
|
247
|
+
# The joint axis definitions in the URDF do not match the real axis of rotation
|
|
248
|
+
# due to URDF not supporting ball joints properly.
|
|
249
|
+
self._log_joint_angle("yaw_body", -head_joints[0], axis=[0, 0, 1])
|
|
250
|
+
self._log_joint_angle("stewart_1", -head_joints[1], axis=[0, 1, 0])
|
|
251
|
+
self._log_joint_angle("stewart_2", head_joints[2], axis=[0, 1, 0])
|
|
252
|
+
self._log_joint_angle("stewart_3", -head_joints[3], axis=[0, 1, 0])
|
|
253
|
+
self._log_joint_angle("stewart_4", head_joints[4], axis=[0, 1, 0])
|
|
254
|
+
self._log_joint_angle("stewart_5", -head_joints[5], axis=[0, 1, 0])
|
|
255
|
+
self._log_joint_angle("stewart_6", head_joints[6], axis=[0, 1, 0])
|
|
256
|
+
|
|
257
|
+
if "passive_joints" in data and data["passive_joints"] is not None:
|
|
258
|
+
passive_joints = data["passive_joints"]
|
|
259
|
+
|
|
260
|
+
for axis_idx, axis in enumerate(["x", "y", "z"]):
|
|
261
|
+
for i in range(1, 8):
|
|
262
|
+
joint_name = f"passive_{i}_{axis}"
|
|
263
|
+
value_index = (i - 1) * 3 + axis_idx
|
|
264
|
+
|
|
265
|
+
override_axis = [0.0, 0.0, 0.0]
|
|
266
|
+
override_axis[axis_idx] = 1.0
|
|
267
|
+
self._log_joint_angle(
|
|
268
|
+
joint_name,
|
|
269
|
+
passive_joints[value_index],
|
|
270
|
+
axis=override_axis,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
time.sleep(0.1)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
class UrdfEntityPaths:
|
|
277
|
+
"""Helper for constructing link/joint entity paths that match the native URDF logger."""
|
|
278
|
+
|
|
279
|
+
def __init__(self, model: urdf.URDF, entity_path_prefix: Optional[str]) -> None:
|
|
280
|
+
"""Construct a new `UrdfEntityPaths` instance.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
model (urdf.URDF): The URDF model.
|
|
284
|
+
entity_path_prefix (Optional[str]): The prefix for entity paths.
|
|
285
|
+
|
|
286
|
+
"""
|
|
287
|
+
self._model = model
|
|
288
|
+
self.prefix = entity_path_prefix
|
|
289
|
+
self.link_paths: Dict[str, str] = {}
|
|
290
|
+
self.joint_paths: Dict[str, str] = {}
|
|
291
|
+
|
|
292
|
+
base_parts = [part for part in (self.prefix, model.name) if part]
|
|
293
|
+
self._base_path = "/".join(base_parts)
|
|
294
|
+
|
|
295
|
+
children_map: Dict[str, List[urdf.Joint]] = {}
|
|
296
|
+
for joint in model.joints:
|
|
297
|
+
children_map.setdefault(joint.parent, []).append(joint)
|
|
298
|
+
|
|
299
|
+
root_link = model.get_root()
|
|
300
|
+
self._build_paths(root_link, self._base_path, children_map)
|
|
301
|
+
|
|
302
|
+
def _build_paths(
|
|
303
|
+
self,
|
|
304
|
+
link_name: str,
|
|
305
|
+
parent_path: str,
|
|
306
|
+
children_map: Dict[str, List[urdf.Joint]],
|
|
307
|
+
) -> None:
|
|
308
|
+
link_path = self._join(parent_path, link_name)
|
|
309
|
+
self.link_paths[link_name] = link_path
|
|
310
|
+
|
|
311
|
+
for joint in children_map.get(link_name, []):
|
|
312
|
+
joint_path = self._join(link_path, joint.name)
|
|
313
|
+
self.joint_paths[joint.name] = joint_path
|
|
314
|
+
self._build_paths(joint.child, joint_path, children_map)
|
|
315
|
+
|
|
316
|
+
@staticmethod
|
|
317
|
+
def _join(parent: str, child: str) -> str:
|
|
318
|
+
if parent:
|
|
319
|
+
return f"{parent}/{child}"
|
|
320
|
+
return child
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Utility functions for working with wireless version."""
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""Check and fix ownership of files under /venvs directory.
|
|
2
|
+
|
|
3
|
+
This module ensures that all files under /venvs are owned by the pollen user.
|
|
4
|
+
If any files are not owned by pollen, it will recursively change ownership.
|
|
5
|
+
Also checks and updates the bluetooth service if needed.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import filecmp
|
|
9
|
+
import logging
|
|
10
|
+
import pwd
|
|
11
|
+
import subprocess
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
USER = "pollen"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def check_and_fix_venvs_ownership(
|
|
19
|
+
venvs_path: str = "/venvs", custom_logger: logging.Logger | None = None
|
|
20
|
+
) -> None:
|
|
21
|
+
"""Check if files under venvs_path are owned by user pollen and fix if needed.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
venvs_path: Path to the virtual environments directory (default: /venvs)
|
|
25
|
+
custom_logger: Optional logger to use instead of the module logger
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
# Get pollen user's UID
|
|
30
|
+
pollen_uid = pwd.getpwnam(USER).pw_uid
|
|
31
|
+
except KeyError:
|
|
32
|
+
print(f"User '{USER}' does not exist on this system")
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
venvs_dir = Path(venvs_path)
|
|
36
|
+
|
|
37
|
+
if not venvs_dir.exists():
|
|
38
|
+
print(f"Directory {venvs_path} does not exist")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
if not venvs_dir.is_dir():
|
|
42
|
+
print(f"{venvs_path} exists but is not a directory")
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
# Check if any files are not owned by pollen
|
|
46
|
+
needs_fix = False
|
|
47
|
+
try:
|
|
48
|
+
for item in venvs_dir.rglob("*"):
|
|
49
|
+
try:
|
|
50
|
+
if item.stat().st_uid != pollen_uid:
|
|
51
|
+
needs_fix = True
|
|
52
|
+
print(f"Found file not owned by {USER}: {item}")
|
|
53
|
+
break
|
|
54
|
+
except (PermissionError, OSError) as e:
|
|
55
|
+
print(f"Cannot check ownership of {item}: {e}")
|
|
56
|
+
except (PermissionError, OSError) as e:
|
|
57
|
+
print(f"Cannot access {venvs_path}: {e}")
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
if needs_fix:
|
|
61
|
+
print(f"Fixing ownership of {venvs_path} to {USER}:{USER}")
|
|
62
|
+
try:
|
|
63
|
+
# Run chown with sudo to fix ownership
|
|
64
|
+
subprocess.run(
|
|
65
|
+
["sudo", "chown", f"{USER}:{USER}", "-R", venvs_path],
|
|
66
|
+
check=True,
|
|
67
|
+
capture_output=True,
|
|
68
|
+
text=True,
|
|
69
|
+
)
|
|
70
|
+
print(f"Successfully fixed ownership of {venvs_path}")
|
|
71
|
+
except subprocess.CalledProcessError as e:
|
|
72
|
+
print(f"Failed to fix ownership: {e.stderr}")
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print(f"Unexpected error while fixing ownership: {e}")
|
|
75
|
+
else:
|
|
76
|
+
print(f"All files under {venvs_path} are owned by {USER}")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def check_and_update_bluetooth_service() -> None:
|
|
80
|
+
"""Check if bluetooth service needs updating and update if different.
|
|
81
|
+
|
|
82
|
+
Compares the source bluetooth_service.py with the installed version at
|
|
83
|
+
/bluetooth/bluetooth_service.py. If they differ, copies the new version
|
|
84
|
+
and restarts the bluetooth service.
|
|
85
|
+
"""
|
|
86
|
+
# This file: src/reachy_mini/utils/wireless_version/startup_check.py
|
|
87
|
+
# Target: src/reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py
|
|
88
|
+
# From parent: ../../daemon/app/services/bluetooth/bluetooth_service.py
|
|
89
|
+
source = Path(__file__).parent / ".." / ".." / "daemon" / "app" / "services" / "bluetooth" / "bluetooth_service.py"
|
|
90
|
+
source = source.resolve()
|
|
91
|
+
target = Path("/bluetooth/bluetooth_service.py")
|
|
92
|
+
|
|
93
|
+
if not source.exists():
|
|
94
|
+
print(f"Source bluetooth service not found at {source}")
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
# Check if target exists
|
|
98
|
+
if not target.exists():
|
|
99
|
+
print(f"Bluetooth service not installed at {target}, copying...")
|
|
100
|
+
needs_update = True
|
|
101
|
+
else:
|
|
102
|
+
# Compare files
|
|
103
|
+
try:
|
|
104
|
+
if filecmp.cmp(str(source), str(target), shallow=False):
|
|
105
|
+
print("Bluetooth service is up to date")
|
|
106
|
+
return
|
|
107
|
+
else:
|
|
108
|
+
print("Bluetooth service has changed, updating...")
|
|
109
|
+
needs_update = True
|
|
110
|
+
except Exception as e:
|
|
111
|
+
print(f"Error comparing bluetooth service files: {e}")
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
if needs_update:
|
|
115
|
+
try:
|
|
116
|
+
# Copy the new version using sudo
|
|
117
|
+
print(f"Copying {source} to {target}")
|
|
118
|
+
subprocess.run(
|
|
119
|
+
["sudo", "cp", str(source), str(target)],
|
|
120
|
+
check=True,
|
|
121
|
+
capture_output=True,
|
|
122
|
+
text=True,
|
|
123
|
+
)
|
|
124
|
+
print("Successfully copied bluetooth service")
|
|
125
|
+
|
|
126
|
+
# Restart the bluetooth service
|
|
127
|
+
print("Restarting bluetooth service...")
|
|
128
|
+
subprocess.run(
|
|
129
|
+
["sudo", "systemctl", "restart", "reachy-mini-bluetooth"],
|
|
130
|
+
check=True,
|
|
131
|
+
capture_output=True,
|
|
132
|
+
text=True,
|
|
133
|
+
)
|
|
134
|
+
print("Successfully restarted bluetooth service")
|
|
135
|
+
except subprocess.CalledProcessError as e:
|
|
136
|
+
print(f"Failed to update bluetooth service: {e.stderr}")
|
|
137
|
+
except Exception as e:
|
|
138
|
+
print(f"Unexpected error while updating bluetooth service: {e}")
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
logging.basicConfig(level=logging.INFO)
|
|
143
|
+
check_and_fix_venvs_ownership()
|
|
144
|
+
check_and_update_bluetooth_service()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Module to handle software updates for the Reachy Mini wireless."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from .utils import call_logger_wrapper
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
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."""
|
|
10
|
+
extra_args = []
|
|
11
|
+
if pre_release:
|
|
12
|
+
extra_args.append("--pre")
|
|
13
|
+
|
|
14
|
+
await call_logger_wrapper(
|
|
15
|
+
["pip", "install", "--upgrade", "reachy_mini[wireless-version]"] + extra_args,
|
|
16
|
+
logger,
|
|
17
|
+
)
|
|
18
|
+
await call_logger_wrapper(
|
|
19
|
+
["sudo", "systemctl", "restart", "reachy-mini-daemon"], logger
|
|
20
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Check if an update is available for Reachy Mini Wireless.
|
|
2
|
+
|
|
3
|
+
For now, this only checks if a new version of "reachy_mini" is available on PyPI.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from importlib.metadata import version
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
import semver
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def is_update_available(package_name: str, pre_release: bool) -> bool:
|
|
13
|
+
"""Check if an update is available for the given package."""
|
|
14
|
+
pypi_version = get_pypi_version(package_name, pre_release)
|
|
15
|
+
local_version = get_local_version(package_name)
|
|
16
|
+
|
|
17
|
+
is_update_available = pypi_version > local_version
|
|
18
|
+
assert isinstance(is_update_available, bool)
|
|
19
|
+
|
|
20
|
+
return is_update_available
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_pypi_version(package_name: str, pre_release: bool) -> semver.Version:
|
|
24
|
+
"""Get the latest version of a package from PyPI."""
|
|
25
|
+
url = f"https://pypi.org/pypi/{package_name}/json"
|
|
26
|
+
response = requests.get(url)
|
|
27
|
+
response.raise_for_status()
|
|
28
|
+
data = response.json()
|
|
29
|
+
|
|
30
|
+
version = data["info"]["version"]
|
|
31
|
+
|
|
32
|
+
if pre_release:
|
|
33
|
+
releases = list(data["releases"].keys())
|
|
34
|
+
pre_version = _semver_version(releases[-1])
|
|
35
|
+
if pre_version > version:
|
|
36
|
+
return pre_version
|
|
37
|
+
|
|
38
|
+
return _semver_version(version)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_local_version(package_name: str) -> semver.Version:
|
|
42
|
+
"""Get the currently installed version of a package."""
|
|
43
|
+
return _semver_version(version(package_name))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _semver_version(v: str) -> semver.Version:
|
|
47
|
+
"""Convert a version string to a semver.Version object, handling pypi pre-release formats."""
|
|
48
|
+
try:
|
|
49
|
+
return semver.Version.parse(v)
|
|
50
|
+
except ValueError:
|
|
51
|
+
version_parts = v.split(".")
|
|
52
|
+
if len(version_parts) < 3:
|
|
53
|
+
raise ValueError(f"Invalid version string: {v}")
|
|
54
|
+
|
|
55
|
+
patch_part = version_parts[2]
|
|
56
|
+
if "rc" in patch_part:
|
|
57
|
+
patch, rc = patch_part.split("rc", 1)
|
|
58
|
+
v_clean = f"{version_parts[0]}.{version_parts[1]}.{patch}-rc.{rc}"
|
|
59
|
+
return semver.Version.parse(v_clean)
|
|
60
|
+
|
|
61
|
+
raise ValueError(f"Invalid version string: {v}")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Utility functions for running shell commands asynchronously with real-time logging."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Callable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def call_logger_wrapper(command: list[str], logger: logging.Logger) -> None:
|
|
9
|
+
"""Run a command asynchronously, streaming stdout and stderr to logger in real time.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
command: list or tuple of command arguments (not a string)
|
|
13
|
+
logger: logger object with .info and .error methods
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
process = await asyncio.create_subprocess_exec(
|
|
17
|
+
*command,
|
|
18
|
+
stdout=asyncio.subprocess.PIPE,
|
|
19
|
+
stderr=asyncio.subprocess.PIPE,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
async def stream_output(
|
|
23
|
+
stream: asyncio.StreamReader,
|
|
24
|
+
log_func: Callable[[str], None],
|
|
25
|
+
) -> None:
|
|
26
|
+
while True:
|
|
27
|
+
line = await stream.readline()
|
|
28
|
+
if not line:
|
|
29
|
+
break
|
|
30
|
+
log_func(line.decode().rstrip())
|
|
31
|
+
|
|
32
|
+
tasks = []
|
|
33
|
+
if process.stdout is not None:
|
|
34
|
+
tasks.append(asyncio.create_task(stream_output(process.stdout, logger.info)))
|
|
35
|
+
if process.stderr is not None:
|
|
36
|
+
tasks.append(asyncio.create_task(stream_output(process.stderr, logger.error)))
|
|
37
|
+
|
|
38
|
+
await asyncio.gather(*tasks)
|
|
39
|
+
await process.wait()
|