reachy-mini 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reachy-mini might be problematic. Click here for more details.
- reachy_mini/__init__.py +4 -0
- reachy_mini/apps/__init__.py +24 -0
- reachy_mini/apps/app.py +121 -0
- reachy_mini/apps/manager.py +183 -0
- reachy_mini/apps/sources/__init__.py +4 -0
- reachy_mini/apps/sources/hf_space.py +25 -0
- reachy_mini/apps/sources/local_common_venv.py +44 -0
- reachy_mini/apps/templates/README.md.j2 +1 -0
- reachy_mini/apps/templates/main.py.j2 +46 -0
- reachy_mini/apps/templates/pyproject.toml.j2 +18 -0
- reachy_mini/apps/utils.py +30 -0
- reachy_mini/assets/config/hardware_config.yaml +119 -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/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/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
- reachy_mini/daemon/app/dashboard/static/js/apps.js +304 -0
- reachy_mini/daemon/app/dashboard/static/js/appstore.js +150 -0
- reachy_mini/daemon/app/dashboard/static/js/daemon.js +163 -0
- reachy_mini/daemon/app/dashboard/static/js/move_player.js +132 -0
- reachy_mini/daemon/app/dashboard/static/js/setup_wifi.js +94 -0
- reachy_mini/daemon/app/dashboard/static/js/update.js +80 -0
- reachy_mini/daemon/app/dashboard/static/style.css +83 -0
- reachy_mini/daemon/app/dashboard/templates/base.html +23 -0
- reachy_mini/daemon/app/dashboard/templates/index.html +17 -0
- reachy_mini/daemon/app/dashboard/templates/sections/apps.html +8 -0
- reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +29 -0
- reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +36 -0
- reachy_mini/daemon/app/dashboard/templates/sections/move_player.html +27 -0
- reachy_mini/daemon/app/dashboard/update.html +22 -0
- reachy_mini/daemon/app/dashboard/wifi_config.html +41 -0
- reachy_mini/daemon/app/dependencies.py +41 -0
- reachy_mini/daemon/app/main.py +262 -0
- reachy_mini/daemon/app/models.py +147 -0
- reachy_mini/daemon/app/routers/apps.py +114 -0
- reachy_mini/daemon/app/routers/daemon.py +80 -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 +257 -0
- reachy_mini/daemon/app/routers/state.py +146 -0
- reachy_mini/daemon/backend/__init__.py +1 -0
- reachy_mini/daemon/backend/abstract.py +750 -0
- reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
- reachy_mini/daemon/backend/mujoco/backend.py +304 -0
- reachy_mini/daemon/backend/mujoco/utils.py +59 -0
- reachy_mini/daemon/backend/mujoco/video_udp.py +53 -0
- reachy_mini/daemon/backend/robot/__init__.py +8 -0
- reachy_mini/daemon/backend/robot/backend.py +535 -0
- reachy_mini/daemon/daemon.py +444 -0
- reachy_mini/daemon/utils.py +114 -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/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 +613 -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 +131 -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/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/io/__init__.py +1 -0
- reachy_mini/io/abstract.py +70 -0
- reachy_mini/io/protocol.py +44 -0
- reachy_mini/io/zenoh_client.py +258 -0
- reachy_mini/io/zenoh_server.py +183 -0
- reachy_mini/kinematics/__init__.py +68 -0
- reachy_mini/kinematics/analytical_kinematics.py +102 -0
- reachy_mini/kinematics/nn_kinematics.py +100 -0
- reachy_mini/kinematics/placo_kinematics.py +666 -0
- reachy_mini/media/__init__.py +1 -0
- reachy_mini/media/audio_base.py +163 -0
- reachy_mini/media/audio_gstreamer.py +195 -0
- reachy_mini/media/audio_sounddevice.py +226 -0
- reachy_mini/media/audio_utils.py +27 -0
- reachy_mini/media/camera_base.py +63 -0
- reachy_mini/media/camera_constants.py +13 -0
- reachy_mini/media/camera_gstreamer.py +162 -0
- reachy_mini/media/camera_opencv.py +61 -0
- reachy_mini/media/camera_utils.py +60 -0
- reachy_mini/media/media_manager.py +194 -0
- reachy_mini/motion/__init__.py +4 -0
- reachy_mini/motion/goto.py +71 -0
- reachy_mini/motion/move.py +36 -0
- reachy_mini/motion/recorded_move.py +132 -0
- reachy_mini/reachy_mini.py +705 -0
- reachy_mini/utils/__init__.py +46 -0
- reachy_mini/utils/constants.py +9 -0
- reachy_mini/utils/interpolation.py +227 -0
- reachy_mini/utils/parse_urdf_for_kinematics.py +110 -0
- reachy_mini/utils/rerun.py +546 -0
- reachy_mini-1.0.0.dist-info/METADATA +286 -0
- reachy_mini-1.0.0.dist-info/RECORD +385 -0
- reachy_mini-1.0.0.dist-info/WHEEL +5 -0
- reachy_mini-1.0.0.dist-info/entry_points.txt +3 -0
- reachy_mini-1.0.0.dist-info/licenses/LICENSE +201 -0
- reachy_mini-1.0.0.dist-info/top_level.txt +1 -0
reachy_mini/__init__.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Metadata about apps."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Any, Dict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SourceKind(str, Enum):
|
|
9
|
+
"""Kinds of app source."""
|
|
10
|
+
|
|
11
|
+
HF_SPACE = "hf_space"
|
|
12
|
+
LOCAL = "local"
|
|
13
|
+
INSTALLED = "installed"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class AppInfo:
|
|
18
|
+
"""Metadata about an app."""
|
|
19
|
+
|
|
20
|
+
name: str
|
|
21
|
+
source_kind: SourceKind
|
|
22
|
+
description: str = ""
|
|
23
|
+
url: str | None = None
|
|
24
|
+
extra: Dict[str, Any] = field(default_factory=dict)
|
reachy_mini/apps/app.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Reachy Mini Application Base Class.
|
|
2
|
+
|
|
3
|
+
This module provides a base class for creating Reachy Mini applications.
|
|
4
|
+
It includes methods for running the application, stopping it gracefully,
|
|
5
|
+
and creating a new app project with a specified name and path.
|
|
6
|
+
|
|
7
|
+
It uses Jinja2 templates to generate the necessary files for the app project.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import threading
|
|
11
|
+
import traceback
|
|
12
|
+
from abc import ABC, abstractmethod
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any, Dict
|
|
15
|
+
|
|
16
|
+
from jinja2 import Environment, FileSystemLoader
|
|
17
|
+
|
|
18
|
+
from reachy_mini.reachy_mini import ReachyMini
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ReachyMiniApp(ABC):
|
|
22
|
+
"""Base class for Reachy Mini applications."""
|
|
23
|
+
|
|
24
|
+
def __init__(self) -> None:
|
|
25
|
+
"""Initialize the Reachy Mini app."""
|
|
26
|
+
self.stop_event = threading.Event()
|
|
27
|
+
self.error: str = ""
|
|
28
|
+
|
|
29
|
+
def wrapped_run(self, *args: Any, **kwargs: Any) -> None:
|
|
30
|
+
"""Wrap the run method with Reachy Mini context management."""
|
|
31
|
+
try:
|
|
32
|
+
with ReachyMini(*args, **kwargs) as reachy_mini:
|
|
33
|
+
self.run(reachy_mini, self.stop_event)
|
|
34
|
+
except Exception:
|
|
35
|
+
self.error = traceback.format_exc()
|
|
36
|
+
raise
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def run(self, reachy_mini: ReachyMini, stop_event: threading.Event) -> None:
|
|
40
|
+
"""Run the main logic of the app.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
reachy_mini (ReachyMini): The Reachy Mini instance to interact with.
|
|
44
|
+
stop_event (threading.Event): An event that can be set to stop the app gracefully.
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
def stop(self) -> None:
|
|
50
|
+
"""Stop the app gracefully."""
|
|
51
|
+
self.stop_event.set()
|
|
52
|
+
print("App is stopping...")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def make_app_project(app_name: str, path: Path) -> None:
|
|
56
|
+
"""Create a new Reachy Mini app project with the given name at the specified path.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
app_name (str): The name of the app to create.
|
|
60
|
+
path (Path): The directory where the app project will be created.
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
TEMPLATE_DIR = Path(__file__).parent / "templates"
|
|
64
|
+
env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
|
|
65
|
+
|
|
66
|
+
def render_template(filename: str, context: Dict[str, str]) -> str:
|
|
67
|
+
template = env.get_template(filename)
|
|
68
|
+
return template.render(context)
|
|
69
|
+
|
|
70
|
+
base_path = Path(path).resolve() / app_name
|
|
71
|
+
if base_path.exists():
|
|
72
|
+
print(f"❌ Folder {base_path} already exists.")
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
module_name = app_name.replace("-", "_")
|
|
76
|
+
class_name = "".join(word.capitalize() for word in module_name.split("_"))
|
|
77
|
+
|
|
78
|
+
base_path.mkdir()
|
|
79
|
+
(base_path / module_name).mkdir()
|
|
80
|
+
|
|
81
|
+
# Generate files
|
|
82
|
+
context = {
|
|
83
|
+
"app_name": app_name,
|
|
84
|
+
"package_name": app_name,
|
|
85
|
+
"module_name": module_name,
|
|
86
|
+
"class_name": class_name,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
(base_path / module_name / "__init__.py").touch()
|
|
90
|
+
(base_path / module_name / "main.py").write_text(
|
|
91
|
+
render_template("main.py.j2", context)
|
|
92
|
+
)
|
|
93
|
+
(base_path / "pyproject.toml").write_text(
|
|
94
|
+
render_template("pyproject.toml.j2", context)
|
|
95
|
+
)
|
|
96
|
+
(base_path / "README.md").write_text(render_template("README.md.j2", context))
|
|
97
|
+
|
|
98
|
+
print(f"✅ Created app in {base_path}/")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def main() -> None:
|
|
102
|
+
"""Run the command line interface to create a new Reachy Mini app project."""
|
|
103
|
+
import argparse
|
|
104
|
+
|
|
105
|
+
parser = argparse.ArgumentParser(
|
|
106
|
+
description="Create a new Reachy Mini app project."
|
|
107
|
+
)
|
|
108
|
+
parser.add_argument("app_name", type=str, help="Name of the app to create.")
|
|
109
|
+
parser.add_argument(
|
|
110
|
+
"--path",
|
|
111
|
+
type=Path,
|
|
112
|
+
default=Path.cwd(),
|
|
113
|
+
help="Path where the app project will be created.",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
args = parser.parse_args()
|
|
117
|
+
make_app_project(args.app_name, args.path)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if __name__ == "__main__":
|
|
121
|
+
main()
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""App management for Reachy Mini."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from importlib.metadata import entry_points
|
|
8
|
+
from threading import Thread
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from . import AppInfo, SourceKind
|
|
14
|
+
from .sources import hf_space, local_common_venv
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .app import ReachyMiniApp
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AppState(str, Enum):
|
|
21
|
+
"""Status of a running app."""
|
|
22
|
+
|
|
23
|
+
STARTING = "starting"
|
|
24
|
+
RUNNING = "running"
|
|
25
|
+
DONE = "done"
|
|
26
|
+
STOPPING = "stopping"
|
|
27
|
+
ERROR = "error"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AppStatus(BaseModel):
|
|
31
|
+
"""Status of an app."""
|
|
32
|
+
|
|
33
|
+
info: AppInfo
|
|
34
|
+
state: AppState
|
|
35
|
+
error: str | None = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class RunningApp:
|
|
40
|
+
"""Information about a running app."""
|
|
41
|
+
|
|
42
|
+
app: "ReachyMiniApp"
|
|
43
|
+
thread: Thread
|
|
44
|
+
status: AppStatus
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class AppManager:
|
|
48
|
+
"""Manager for Reachy Mini apps."""
|
|
49
|
+
|
|
50
|
+
def __init__(self) -> None:
|
|
51
|
+
"""Initialize the AppManager."""
|
|
52
|
+
self.current_app = None # type: RunningApp | None
|
|
53
|
+
self.logger = logging.getLogger("reachy_mini.apps.manager")
|
|
54
|
+
|
|
55
|
+
async def close(self) -> None:
|
|
56
|
+
"""Clean up the AppManager, stopping any running app."""
|
|
57
|
+
if self.is_app_running():
|
|
58
|
+
await self.stop_current_app()
|
|
59
|
+
|
|
60
|
+
# App lifecycle management
|
|
61
|
+
# Only one app can be started at a time for now
|
|
62
|
+
def is_app_running(self) -> bool:
|
|
63
|
+
"""Check if an app is currently running."""
|
|
64
|
+
return self.current_app is not None and self.current_app.status.state in (
|
|
65
|
+
AppState.STARTING,
|
|
66
|
+
AppState.RUNNING,
|
|
67
|
+
AppState.ERROR,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
async def start_app(self, app_name: str, *args: Any, **kwargs: Any) -> AppStatus:
|
|
71
|
+
"""Start the app, raises RuntimeError if an app is already running."""
|
|
72
|
+
if self.is_app_running():
|
|
73
|
+
raise RuntimeError("An app is already running")
|
|
74
|
+
|
|
75
|
+
(ep,) = entry_points(group="reachy_mini_apps", name=app_name)
|
|
76
|
+
app = ep.load()()
|
|
77
|
+
|
|
78
|
+
def wrapped_run() -> None:
|
|
79
|
+
assert self.current_app is not None
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
self.current_app.status.state = AppState.RUNNING
|
|
83
|
+
self.logger.getChild("runner").info(f"App {app_name} is running")
|
|
84
|
+
app.wrapped_run(*args, **kwargs)
|
|
85
|
+
self.current_app.status.state = AppState.DONE
|
|
86
|
+
self.logger.getChild("runner").info(f"App {app_name} finished")
|
|
87
|
+
except Exception as e:
|
|
88
|
+
self.logger.getChild("runner").error(
|
|
89
|
+
f"An error occurred in the app {app_name}: {e}"
|
|
90
|
+
)
|
|
91
|
+
self.logger.getChild("runner").error(
|
|
92
|
+
f"Exception details: '{app.error}'",
|
|
93
|
+
)
|
|
94
|
+
self.current_app.status.state = AppState.ERROR
|
|
95
|
+
self.current_app.status.error = str(app.error)
|
|
96
|
+
|
|
97
|
+
self.current_app = RunningApp(
|
|
98
|
+
status=AppStatus(
|
|
99
|
+
info=AppInfo(name=app_name, source_kind=SourceKind.INSTALLED),
|
|
100
|
+
state=AppState.STARTING,
|
|
101
|
+
error=None,
|
|
102
|
+
),
|
|
103
|
+
app=app,
|
|
104
|
+
thread=Thread(target=wrapped_run),
|
|
105
|
+
)
|
|
106
|
+
self.logger.getChild("runner").info(f"Starting app {app_name}")
|
|
107
|
+
self.current_app.thread.start()
|
|
108
|
+
|
|
109
|
+
return self.current_app.status
|
|
110
|
+
|
|
111
|
+
async def stop_current_app(self, timeout: float | None = 5.0) -> None:
|
|
112
|
+
"""Stop the current app."""
|
|
113
|
+
if not self.is_app_running():
|
|
114
|
+
raise RuntimeError("No app is currently running")
|
|
115
|
+
|
|
116
|
+
assert self.current_app is not None
|
|
117
|
+
|
|
118
|
+
self.current_app.status.state = AppState.STOPPING
|
|
119
|
+
self.logger.getChild("runner").info(
|
|
120
|
+
f"Stopping app {self.current_app.status.info.name}"
|
|
121
|
+
)
|
|
122
|
+
self.current_app.app.stop()
|
|
123
|
+
self.current_app.thread.join(timeout)
|
|
124
|
+
|
|
125
|
+
if self.current_app.thread.is_alive():
|
|
126
|
+
self.logger.getChild("runner").warning(
|
|
127
|
+
"The app did not stop within the timeout"
|
|
128
|
+
)
|
|
129
|
+
else:
|
|
130
|
+
self.logger.getChild("runner").info("App stopped successfully")
|
|
131
|
+
|
|
132
|
+
self.current_app = None
|
|
133
|
+
|
|
134
|
+
async def restart_current_app(self) -> AppStatus:
|
|
135
|
+
"""Restart the current app."""
|
|
136
|
+
if not self.is_app_running():
|
|
137
|
+
raise RuntimeError("No app is currently running")
|
|
138
|
+
|
|
139
|
+
assert self.current_app is not None
|
|
140
|
+
|
|
141
|
+
app_info = self.current_app.status.info
|
|
142
|
+
|
|
143
|
+
await self.stop_current_app()
|
|
144
|
+
await self.start_app(app_info.name)
|
|
145
|
+
|
|
146
|
+
return self.current_app.status
|
|
147
|
+
|
|
148
|
+
async def current_app_status(self) -> Optional[AppStatus]:
|
|
149
|
+
"""Get the current status of the app."""
|
|
150
|
+
if self.current_app is not None:
|
|
151
|
+
return self.current_app.status
|
|
152
|
+
return None
|
|
153
|
+
|
|
154
|
+
# Apps management interface
|
|
155
|
+
async def list_all_available_apps(self) -> list[AppInfo]:
|
|
156
|
+
"""List available apps (parallel async)."""
|
|
157
|
+
results = await asyncio.gather(
|
|
158
|
+
*[self.list_available_apps(kind) for kind in SourceKind]
|
|
159
|
+
)
|
|
160
|
+
return sum(results, [])
|
|
161
|
+
|
|
162
|
+
async def list_available_apps(self, source: SourceKind) -> list[AppInfo]:
|
|
163
|
+
"""List available apps for given source kind."""
|
|
164
|
+
if source == SourceKind.HF_SPACE:
|
|
165
|
+
return await hf_space.list_available_apps()
|
|
166
|
+
elif source == SourceKind.INSTALLED:
|
|
167
|
+
return await local_common_venv.list_available_apps()
|
|
168
|
+
elif source == SourceKind.LOCAL:
|
|
169
|
+
return []
|
|
170
|
+
else:
|
|
171
|
+
raise NotImplementedError(f"Unknown source kind: {source}")
|
|
172
|
+
|
|
173
|
+
async def install_new_app(self, app: AppInfo, logger: logging.Logger) -> None:
|
|
174
|
+
"""Install a new app by name."""
|
|
175
|
+
success = await local_common_venv.install_package(app, logger)
|
|
176
|
+
if success != 0:
|
|
177
|
+
raise RuntimeError(f"Failed to install app '{app.name}'")
|
|
178
|
+
|
|
179
|
+
async def remove_app(self, app_name: str, logger: logging.Logger) -> None:
|
|
180
|
+
"""Remove an installed app by name."""
|
|
181
|
+
success = await local_common_venv.uninstall_package(app_name, logger)
|
|
182
|
+
if success != 0:
|
|
183
|
+
raise RuntimeError(f"Failed to uninstall app '{app_name}'")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Hugging Face Spaces app source."""
|
|
2
|
+
|
|
3
|
+
import aiohttp
|
|
4
|
+
|
|
5
|
+
from .. import AppInfo, SourceKind
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def list_available_apps() -> list[AppInfo]:
|
|
9
|
+
"""List apps available on Hugging Face Spaces."""
|
|
10
|
+
url = "https://huggingface.co/api/spaces?filter=reachy_mini&sort=likes&direction=-1&limit=50&full=true"
|
|
11
|
+
async with aiohttp.ClientSession() as session:
|
|
12
|
+
async with session.get(url) as response:
|
|
13
|
+
data = await response.json()
|
|
14
|
+
apps = []
|
|
15
|
+
for item in data:
|
|
16
|
+
apps.append(
|
|
17
|
+
AppInfo(
|
|
18
|
+
name=item["id"].split("/")[-1],
|
|
19
|
+
description=item["cardData"].get("short_description", ""),
|
|
20
|
+
url=f"https://huggingface.co/spaces/{item['id']}",
|
|
21
|
+
source_kind=SourceKind.HF_SPACE,
|
|
22
|
+
extra=item,
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
return apps
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Utilities for local common venv apps source."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
from importlib.metadata import entry_points
|
|
6
|
+
|
|
7
|
+
from .. import AppInfo, SourceKind
|
|
8
|
+
from ..utils import running_command
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async def list_available_apps() -> list[AppInfo]:
|
|
12
|
+
"""List apps available from entry points."""
|
|
13
|
+
entry_point_apps = list(entry_points(group="reachy_mini_apps"))
|
|
14
|
+
return [
|
|
15
|
+
AppInfo(name=ep.name, source_kind=SourceKind.INSTALLED)
|
|
16
|
+
for ep in entry_point_apps
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def install_package(app: AppInfo, logger: logging.Logger) -> int:
|
|
21
|
+
"""Install a package given an AppInfo object, streaming logs."""
|
|
22
|
+
if app.source_kind == SourceKind.HF_SPACE:
|
|
23
|
+
target = f"git+{app.url}" if app.url is not None else app.name
|
|
24
|
+
elif app.source_kind == SourceKind.LOCAL:
|
|
25
|
+
target = app.extra.get("path", app.name)
|
|
26
|
+
else:
|
|
27
|
+
raise ValueError(f"Cannot install app from source kind '{app.source_kind}'")
|
|
28
|
+
|
|
29
|
+
return await running_command(
|
|
30
|
+
[sys.executable, "-m", "pip", "install", target],
|
|
31
|
+
logger=logger,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
async def uninstall_package(app_name: str, logger: logging.Logger) -> int:
|
|
36
|
+
"""Uninstall a package given an app name."""
|
|
37
|
+
existing_apps = await list_available_apps()
|
|
38
|
+
if app_name not in [app.name for app in existing_apps]:
|
|
39
|
+
raise ValueError(f"Cannot uninstall app '{app_name}': it is not installed")
|
|
40
|
+
|
|
41
|
+
return await running_command(
|
|
42
|
+
[sys.executable, "-m", "pip", "uninstall", "-y", app_name],
|
|
43
|
+
logger=logger,
|
|
44
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# {{ app_name }} - A ReachyMini application
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
|
|
3
|
+
from reachy_mini import ReachyMini, ReachyMiniApp
|
|
4
|
+
from reachy_mini.utils import create_head_pose
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class {{ class_name }}(ReachyMiniApp):
|
|
8
|
+
def run(self, reachy_mini: ReachyMini, stop_event: threading.Event):
|
|
9
|
+
# Write your code here
|
|
10
|
+
# ReachyMini is already initialized and connected
|
|
11
|
+
# Check the stop_event to gracefully exit the loop
|
|
12
|
+
# Example:
|
|
13
|
+
# import time
|
|
14
|
+
# import numpy as np
|
|
15
|
+
#
|
|
16
|
+
# t0 = time.time()
|
|
17
|
+
#
|
|
18
|
+
# while not stop_event.is_set():
|
|
19
|
+
# t = time.time() - t0
|
|
20
|
+
#
|
|
21
|
+
# yaw = 30 * np.sin(2 * np.pi * 0.5 * t)
|
|
22
|
+
# head_pose = create_head_pose(yaw=yaw, degrees=True)
|
|
23
|
+
#
|
|
24
|
+
# reachy_mini.set_target(head=head_pose)
|
|
25
|
+
#
|
|
26
|
+
# time.sleep(0.01)
|
|
27
|
+
|
|
28
|
+
print("This is a placeholder for your app logic.")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
# You can run the app directly from this script
|
|
33
|
+
with ReachyMini() as mini:
|
|
34
|
+
app = {{ class_name }}()
|
|
35
|
+
|
|
36
|
+
stop = threading.Event()
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
print("Running '{{ app_name }}' a ReachyMiniApp...")
|
|
40
|
+
print("Press Ctrl+C to stop the app.")
|
|
41
|
+
app.run(mini, stop)
|
|
42
|
+
print("App has stopped.")
|
|
43
|
+
|
|
44
|
+
except KeyboardInterrupt:
|
|
45
|
+
print("Stopping the app...")
|
|
46
|
+
stop.set()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "{{ app_name }}"
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
description = "Add your description here"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"reachy-mini"
|
|
14
|
+
]
|
|
15
|
+
keywords = ["reachy-mini-app"]
|
|
16
|
+
|
|
17
|
+
[project.entry-points."reachy_mini_apps"]
|
|
18
|
+
{{ app_name }} = "{{ module_name }}.main:{{ class_name }}"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Utility functions for Reachy Mini apps manager."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
async def running_command(command: list[str], logger: logging.Logger) -> int:
|
|
8
|
+
"""Run a shell command and stream its output to the provided logger."""
|
|
9
|
+
logger.info(f"Running command: {' '.join(command)}")
|
|
10
|
+
|
|
11
|
+
proc = await asyncio.create_subprocess_exec(
|
|
12
|
+
*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
assert proc.stdout is not None # for mypy
|
|
16
|
+
assert proc.stderr is not None # for mypy
|
|
17
|
+
|
|
18
|
+
# Stream output line by line
|
|
19
|
+
while True:
|
|
20
|
+
line = await proc.stdout.readline()
|
|
21
|
+
if not line:
|
|
22
|
+
break
|
|
23
|
+
logger.info(line.decode().rstrip())
|
|
24
|
+
|
|
25
|
+
# Also log any remaining stderr
|
|
26
|
+
err = await proc.stderr.read()
|
|
27
|
+
if err:
|
|
28
|
+
logger.error(err.decode().rstrip())
|
|
29
|
+
|
|
30
|
+
return await proc.wait()
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
version: beta
|
|
2
|
+
|
|
3
|
+
serial:
|
|
4
|
+
baudrate: 1000000
|
|
5
|
+
|
|
6
|
+
# Limits measured on the robot (in degrees)
|
|
7
|
+
# s1
|
|
8
|
+
# lower : -48° : -546
|
|
9
|
+
# upper : +80° : 910
|
|
10
|
+
|
|
11
|
+
# s2
|
|
12
|
+
# lower: +70° : 796
|
|
13
|
+
# upper: -80° : -910
|
|
14
|
+
|
|
15
|
+
# s3
|
|
16
|
+
# lower: -48° : -546
|
|
17
|
+
# upper: +80° : 910
|
|
18
|
+
|
|
19
|
+
# s4
|
|
20
|
+
# lower: +48° : 546
|
|
21
|
+
# upper: -80° : -910
|
|
22
|
+
|
|
23
|
+
# s5
|
|
24
|
+
# lower: -70° : -796
|
|
25
|
+
# upper: +80° : 910
|
|
26
|
+
|
|
27
|
+
# s6
|
|
28
|
+
# lower : +48° : 546
|
|
29
|
+
# upper : -80° : -910
|
|
30
|
+
|
|
31
|
+
# s1:
|
|
32
|
+
# lower: 2048 - 546 : 1502
|
|
33
|
+
# upper: 2048 + 910 : 2958
|
|
34
|
+
|
|
35
|
+
# s2:
|
|
36
|
+
# lower: 2048 - 910 : 1138
|
|
37
|
+
# upper: 2048 + 796 : 2844
|
|
38
|
+
|
|
39
|
+
# s3:
|
|
40
|
+
# lower: 2048 - 546 : 1502
|
|
41
|
+
# upper: 2048 + 910 : 2958
|
|
42
|
+
|
|
43
|
+
# s4:
|
|
44
|
+
# lower: 2048 - 910 : 1138
|
|
45
|
+
# upper: 2048 + 546 : 2594
|
|
46
|
+
|
|
47
|
+
# s5:
|
|
48
|
+
# lower: 2048 - 796 : 1252
|
|
49
|
+
# upper: 2048 + 910 : 2958
|
|
50
|
+
|
|
51
|
+
# s6:
|
|
52
|
+
# lower: 2048 - 910 : 1138
|
|
53
|
+
# upper: 2048 + 546 : 2594
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
motors:
|
|
57
|
+
- body_yaw:
|
|
58
|
+
id: 10
|
|
59
|
+
offset: 0
|
|
60
|
+
lower_limit: 0
|
|
61
|
+
upper_limit: 4095
|
|
62
|
+
return_delay_time: 0
|
|
63
|
+
shutdown_error: 52
|
|
64
|
+
- stewart_platform_1:
|
|
65
|
+
id: 11
|
|
66
|
+
offset: 1024
|
|
67
|
+
lower_limit: 1502
|
|
68
|
+
upper_limit: 2958
|
|
69
|
+
return_delay_time: 0
|
|
70
|
+
shutdown_error: 52
|
|
71
|
+
- stewart_platform_2:
|
|
72
|
+
id: 12
|
|
73
|
+
offset: -1024
|
|
74
|
+
lower_limit: 1138
|
|
75
|
+
upper_limit: 2844
|
|
76
|
+
return_delay_time: 0
|
|
77
|
+
shutdown_error: 52
|
|
78
|
+
- stewart_platform_3:
|
|
79
|
+
id: 13
|
|
80
|
+
offset: 1024
|
|
81
|
+
lower_limit: 1502
|
|
82
|
+
upper_limit: 2958
|
|
83
|
+
return_delay_time: 0
|
|
84
|
+
shutdown_error: 52
|
|
85
|
+
- stewart_platform_4:
|
|
86
|
+
id: 14
|
|
87
|
+
offset: -1024
|
|
88
|
+
lower_limit: 1138
|
|
89
|
+
upper_limit: 2594
|
|
90
|
+
return_delay_time: 0
|
|
91
|
+
shutdown_error: 52
|
|
92
|
+
- stewart_platform_5:
|
|
93
|
+
id: 15
|
|
94
|
+
offset: 1024
|
|
95
|
+
lower_limit: 1252
|
|
96
|
+
upper_limit: 2958
|
|
97
|
+
return_delay_time: 0
|
|
98
|
+
shutdown_error: 52
|
|
99
|
+
- stewart_platform_6:
|
|
100
|
+
id: 16
|
|
101
|
+
offset: -1024
|
|
102
|
+
lower_limit: 1138
|
|
103
|
+
upper_limit: 2594
|
|
104
|
+
return_delay_time: 0
|
|
105
|
+
shutdown_error: 52
|
|
106
|
+
- right_antenna:
|
|
107
|
+
id: 17
|
|
108
|
+
offset: 0
|
|
109
|
+
lower_limit: 0
|
|
110
|
+
upper_limit: 4095
|
|
111
|
+
return_delay_time: 0
|
|
112
|
+
shutdown_error: 52
|
|
113
|
+
- left_antenna:
|
|
114
|
+
id: 18
|
|
115
|
+
offset: 0
|
|
116
|
+
lower_limit: 0
|
|
117
|
+
upper_limit: 4095
|
|
118
|
+
return_delay_time: 0
|
|
119
|
+
shutdown_error: 52
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|