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
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"""Daemon entry point for the Reachy Mini robot.
|
|
2
|
+
|
|
3
|
+
This script serves as the command-line interface (CLI) entry point for the Reachy Mini daemon.
|
|
4
|
+
It initializes the daemon with specified parameters such as simulation mode, serial port,
|
|
5
|
+
scene to load, and logging level. The daemon runs indefinitely, handling requests and
|
|
6
|
+
managing the robot's state.
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import logging
|
|
12
|
+
from contextlib import asynccontextmanager
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import AsyncGenerator
|
|
16
|
+
|
|
17
|
+
import uvicorn
|
|
18
|
+
from fastapi import APIRouter, FastAPI, Request
|
|
19
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
20
|
+
from fastapi.responses import HTMLResponse
|
|
21
|
+
from fastapi.staticfiles import StaticFiles
|
|
22
|
+
from fastapi.templating import Jinja2Templates
|
|
23
|
+
|
|
24
|
+
from reachy_mini.apps.manager import AppManager
|
|
25
|
+
from reachy_mini.daemon.app.routers import apps, daemon, kinematics, motors, move, state
|
|
26
|
+
from reachy_mini.daemon.daemon import Daemon
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class Args:
|
|
31
|
+
"""Arguments for configuring the Reachy Mini daemon."""
|
|
32
|
+
|
|
33
|
+
log_level: str = "INFO"
|
|
34
|
+
|
|
35
|
+
wireless_version: bool = False
|
|
36
|
+
|
|
37
|
+
serialport: str = "auto"
|
|
38
|
+
|
|
39
|
+
sim: bool = False
|
|
40
|
+
scene: str = "empty"
|
|
41
|
+
headless: bool = False
|
|
42
|
+
|
|
43
|
+
kinematics_engine: str = "AnalyticalKinematics"
|
|
44
|
+
check_collision: bool = False
|
|
45
|
+
|
|
46
|
+
autostart: bool = True
|
|
47
|
+
|
|
48
|
+
wake_up_on_start: bool = True
|
|
49
|
+
goto_sleep_on_stop: bool = True
|
|
50
|
+
|
|
51
|
+
fastapi_host: str = "0.0.0.0"
|
|
52
|
+
fastapi_port: int = 8000
|
|
53
|
+
|
|
54
|
+
localhost_only: bool | None = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def create_app(args: Args) -> FastAPI:
|
|
58
|
+
"""Create and configure the FastAPI application."""
|
|
59
|
+
localhost_only = (
|
|
60
|
+
args.localhost_only
|
|
61
|
+
if args.localhost_only is not None
|
|
62
|
+
else (False if args.wireless_version else True)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
@asynccontextmanager
|
|
66
|
+
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
|
67
|
+
"""Lifespan context manager for the FastAPI application."""
|
|
68
|
+
args = app.state.args # type: Args
|
|
69
|
+
|
|
70
|
+
if args.autostart:
|
|
71
|
+
await app.state.daemon.start(
|
|
72
|
+
serialport=args.serialport,
|
|
73
|
+
sim=args.sim,
|
|
74
|
+
scene=args.scene,
|
|
75
|
+
headless=args.headless,
|
|
76
|
+
kinematics_engine=args.kinematics_engine,
|
|
77
|
+
check_collision=args.check_collision,
|
|
78
|
+
wake_up_on_start=args.wake_up_on_start,
|
|
79
|
+
localhost_only=localhost_only,
|
|
80
|
+
)
|
|
81
|
+
yield
|
|
82
|
+
await app.state.app_manager.close()
|
|
83
|
+
await app.state.daemon.stop(
|
|
84
|
+
goto_sleep_on_stop=args.goto_sleep_on_stop,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
app = FastAPI(
|
|
88
|
+
lifespan=lifespan,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
app.state.args = args
|
|
92
|
+
app.state.daemon = Daemon(wireless_version=args.wireless_version)
|
|
93
|
+
app.state.app_manager = AppManager()
|
|
94
|
+
|
|
95
|
+
router = APIRouter(prefix="/api")
|
|
96
|
+
router.include_router(apps.router)
|
|
97
|
+
router.include_router(daemon.router)
|
|
98
|
+
router.include_router(kinematics.router)
|
|
99
|
+
router.include_router(motors.router)
|
|
100
|
+
router.include_router(move.router)
|
|
101
|
+
router.include_router(state.router)
|
|
102
|
+
app.include_router(router)
|
|
103
|
+
|
|
104
|
+
app.add_middleware(
|
|
105
|
+
CORSMiddleware,
|
|
106
|
+
allow_origins=["*"], # or restrict to your HF domain
|
|
107
|
+
allow_methods=["*"],
|
|
108
|
+
allow_headers=["*"],
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
STATIC_DIR = Path(__file__).parent / "dashboard" / "static"
|
|
112
|
+
TEMPLATES_DIR = Path(__file__).parent / "dashboard" / "templates"
|
|
113
|
+
|
|
114
|
+
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
|
115
|
+
templates = Jinja2Templates(directory=str(TEMPLATES_DIR))
|
|
116
|
+
|
|
117
|
+
@app.get("/")
|
|
118
|
+
async def dashboard(request: Request) -> HTMLResponse:
|
|
119
|
+
"""Render the dashboard."""
|
|
120
|
+
return templates.TemplateResponse("index.html", {"request": request})
|
|
121
|
+
|
|
122
|
+
return app
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def run_app(args: Args) -> None:
|
|
126
|
+
"""Run the FastAPI app with Uvicorn."""
|
|
127
|
+
logging.basicConfig(level=logging.INFO)
|
|
128
|
+
|
|
129
|
+
app = create_app(args)
|
|
130
|
+
uvicorn.run(app, host=args.fastapi_host, port=args.fastapi_port)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def main() -> None:
|
|
134
|
+
"""Run the FastAPI app with Uvicorn."""
|
|
135
|
+
default_args = Args()
|
|
136
|
+
|
|
137
|
+
parser = argparse.ArgumentParser(description="Run the Reachy Mini daemon.")
|
|
138
|
+
parser.add_argument(
|
|
139
|
+
"--wireless-version",
|
|
140
|
+
action="store_true",
|
|
141
|
+
default=default_args.wireless_version,
|
|
142
|
+
help="Use the wireless version of Reachy Mini (default: False).",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Real robot mode
|
|
146
|
+
parser.add_argument(
|
|
147
|
+
"-p",
|
|
148
|
+
"--serialport",
|
|
149
|
+
type=str,
|
|
150
|
+
default=default_args.serialport,
|
|
151
|
+
help="Serial port for real motors (default: will try to automatically find the port).",
|
|
152
|
+
)
|
|
153
|
+
# Simulation mode
|
|
154
|
+
parser.add_argument(
|
|
155
|
+
"--sim",
|
|
156
|
+
action="store_true",
|
|
157
|
+
default=default_args.sim,
|
|
158
|
+
help="Run in simulation mode using Mujoco.",
|
|
159
|
+
)
|
|
160
|
+
parser.add_argument(
|
|
161
|
+
"--scene",
|
|
162
|
+
type=str,
|
|
163
|
+
default=default_args.scene,
|
|
164
|
+
help="Name of the scene to load (default: empty)",
|
|
165
|
+
)
|
|
166
|
+
parser.add_argument(
|
|
167
|
+
"--headless",
|
|
168
|
+
action="store_true",
|
|
169
|
+
default=default_args.headless,
|
|
170
|
+
help="Run the daemon in headless mode (default: False).",
|
|
171
|
+
)
|
|
172
|
+
# Daemon options
|
|
173
|
+
parser.add_argument(
|
|
174
|
+
"--autostart",
|
|
175
|
+
action="store_true",
|
|
176
|
+
default=default_args.autostart,
|
|
177
|
+
help="Automatically start the daemon on launch (default: True).",
|
|
178
|
+
)
|
|
179
|
+
parser.add_argument(
|
|
180
|
+
"--no-autostart",
|
|
181
|
+
action="store_false",
|
|
182
|
+
dest="autostart",
|
|
183
|
+
help="Do not automatically start the daemon on launch (default: False).",
|
|
184
|
+
)
|
|
185
|
+
parser.add_argument(
|
|
186
|
+
"--wake-up-on-start",
|
|
187
|
+
action="store_true",
|
|
188
|
+
default=default_args.wake_up_on_start,
|
|
189
|
+
help="Wake up the robot on daemon start (default: True).",
|
|
190
|
+
)
|
|
191
|
+
parser.add_argument(
|
|
192
|
+
"--no-wake-up-on-start",
|
|
193
|
+
action="store_false",
|
|
194
|
+
dest="wake_up_on_start",
|
|
195
|
+
help="Do not wake up the robot on daemon start (default: False).",
|
|
196
|
+
)
|
|
197
|
+
parser.add_argument(
|
|
198
|
+
"--goto-sleep-on-stop",
|
|
199
|
+
action="store_true",
|
|
200
|
+
default=default_args.goto_sleep_on_stop,
|
|
201
|
+
help="Put the robot to sleep on daemon stop (default: True).",
|
|
202
|
+
)
|
|
203
|
+
parser.add_argument(
|
|
204
|
+
"--no-goto-sleep-on-stop",
|
|
205
|
+
action="store_false",
|
|
206
|
+
dest="goto_sleep_on_stop",
|
|
207
|
+
help="Do not put the robot to sleep on daemon stop (default: False).",
|
|
208
|
+
)
|
|
209
|
+
# Zenoh server options
|
|
210
|
+
parser.add_argument(
|
|
211
|
+
"--localhost-only",
|
|
212
|
+
action="store_true",
|
|
213
|
+
default=default_args.localhost_only,
|
|
214
|
+
help="Restrict the server to localhost only (default: True).",
|
|
215
|
+
)
|
|
216
|
+
parser.add_argument(
|
|
217
|
+
"--no-localhost-only",
|
|
218
|
+
action="store_false",
|
|
219
|
+
dest="localhost_only",
|
|
220
|
+
help="Allow the server to listen on all interfaces (default: False).",
|
|
221
|
+
)
|
|
222
|
+
# Kinematics options
|
|
223
|
+
parser.add_argument(
|
|
224
|
+
"--check-collision",
|
|
225
|
+
action="store_true",
|
|
226
|
+
default=default_args.check_collision,
|
|
227
|
+
help="Enable collision checking (default: False).",
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
parser.add_argument(
|
|
231
|
+
"--kinematics-engine",
|
|
232
|
+
type=str,
|
|
233
|
+
default=default_args.kinematics_engine,
|
|
234
|
+
choices=["Placo", "NN", "AnalyticalKinematics"],
|
|
235
|
+
help="Set the kinematics engine (default: AnalyticalKinematics).",
|
|
236
|
+
)
|
|
237
|
+
# FastAPI server options
|
|
238
|
+
parser.add_argument(
|
|
239
|
+
"--fastapi-host",
|
|
240
|
+
type=str,
|
|
241
|
+
default=default_args.fastapi_host,
|
|
242
|
+
)
|
|
243
|
+
parser.add_argument(
|
|
244
|
+
"--fastapi-port",
|
|
245
|
+
type=int,
|
|
246
|
+
default=default_args.fastapi_port,
|
|
247
|
+
)
|
|
248
|
+
# Logging options
|
|
249
|
+
parser.add_argument(
|
|
250
|
+
"--log-level",
|
|
251
|
+
type=str,
|
|
252
|
+
default=default_args.log_level,
|
|
253
|
+
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
254
|
+
help="Set the logging level (default: INFO).",
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
args = parser.parse_args()
|
|
258
|
+
run_app(Args(**vars(args)))
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
if __name__ == "__main__":
|
|
262
|
+
main()
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""Common pydantic models definitions."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from numpy.typing import NDArray
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
from scipy.spatial.transform import Rotation as R
|
|
9
|
+
|
|
10
|
+
from reachy_mini.daemon.backend.abstract import MotorControlMode
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Matrix4x4Pose(BaseModel):
|
|
14
|
+
"""Represent a 3D pose by its 4x4 transformation matrix (translation is expressed in meters)."""
|
|
15
|
+
|
|
16
|
+
m: tuple[
|
|
17
|
+
float,
|
|
18
|
+
float,
|
|
19
|
+
float,
|
|
20
|
+
float,
|
|
21
|
+
float,
|
|
22
|
+
float,
|
|
23
|
+
float,
|
|
24
|
+
float,
|
|
25
|
+
float,
|
|
26
|
+
float,
|
|
27
|
+
float,
|
|
28
|
+
float,
|
|
29
|
+
float,
|
|
30
|
+
float,
|
|
31
|
+
float,
|
|
32
|
+
float,
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_pose_array(cls, arr: NDArray[np.float64]) -> "Matrix4x4Pose":
|
|
37
|
+
"""Create a Matrix4x4 pose representation from a 4x4 pose array."""
|
|
38
|
+
assert arr.shape == (4, 4), "Array must be of shape (4, 4)"
|
|
39
|
+
m: tuple[
|
|
40
|
+
float,
|
|
41
|
+
float,
|
|
42
|
+
float,
|
|
43
|
+
float,
|
|
44
|
+
float,
|
|
45
|
+
float,
|
|
46
|
+
float,
|
|
47
|
+
float,
|
|
48
|
+
float,
|
|
49
|
+
float,
|
|
50
|
+
float,
|
|
51
|
+
float,
|
|
52
|
+
float,
|
|
53
|
+
float,
|
|
54
|
+
float,
|
|
55
|
+
float,
|
|
56
|
+
] = tuple(arr.flatten().tolist()) # type: ignore [assignment]
|
|
57
|
+
return cls(m=m)
|
|
58
|
+
|
|
59
|
+
def to_pose_array(self) -> NDArray[np.float64]:
|
|
60
|
+
"""Convert the Matrix4x4Pose to a 4x4 numpy array."""
|
|
61
|
+
return np.array(self.m).reshape((4, 4))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class XYZRPYPose(BaseModel):
|
|
65
|
+
"""Represent a 3D pose using position (x, y, z) in meters and orientation (roll, pitch, yaw) angles in radians."""
|
|
66
|
+
|
|
67
|
+
x: float = 0.0
|
|
68
|
+
y: float = 0.0
|
|
69
|
+
z: float = 0.0
|
|
70
|
+
roll: float = 0.0
|
|
71
|
+
pitch: float = 0.0
|
|
72
|
+
yaw: float = 0.0
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def from_pose_array(cls, arr: NDArray[np.float64]) -> "XYZRPYPose":
|
|
76
|
+
"""Create an XYZRPYPose representation from a 4x4 pose array."""
|
|
77
|
+
assert arr.shape == (4, 4), "Array must be of shape (4, 4)"
|
|
78
|
+
|
|
79
|
+
x, y, z = arr[0, 3], arr[1, 3], arr[2, 3]
|
|
80
|
+
roll, pitch, yaw = R.from_matrix(arr[:3, :3]).as_euler("xyz")
|
|
81
|
+
|
|
82
|
+
return cls(
|
|
83
|
+
x=x,
|
|
84
|
+
y=y,
|
|
85
|
+
z=z,
|
|
86
|
+
roll=roll,
|
|
87
|
+
pitch=pitch,
|
|
88
|
+
yaw=yaw,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def to_pose_array(self) -> NDArray[np.float64]:
|
|
92
|
+
"""Convert the XYZRPYPose to a 4x4 numpy array."""
|
|
93
|
+
rotation = R.from_euler("xyz", [self.roll, self.pitch, self.yaw])
|
|
94
|
+
pose_matrix = np.eye(4)
|
|
95
|
+
pose_matrix[:3, 3] = [self.x, self.y, self.z]
|
|
96
|
+
pose_matrix[:3, :3] = rotation.as_matrix()
|
|
97
|
+
return pose_matrix
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
AnyPose = XYZRPYPose | Matrix4x4Pose
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def as_any_pose(pose: NDArray[np.float64], use_matrix: bool) -> AnyPose:
|
|
104
|
+
"""Convert a numpy array to an AnyPose representation."""
|
|
105
|
+
return (
|
|
106
|
+
Matrix4x4Pose.from_pose_array(pose)
|
|
107
|
+
if use_matrix
|
|
108
|
+
else XYZRPYPose.from_pose_array(pose)
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class FullBodyTarget(BaseModel):
|
|
113
|
+
"""Represent the full body including the head pose and the joints for antennas."""
|
|
114
|
+
|
|
115
|
+
target_head_pose: AnyPose | None = None
|
|
116
|
+
target_antennas: tuple[float, float] | None = None
|
|
117
|
+
timestamp: datetime | None = None
|
|
118
|
+
|
|
119
|
+
model_config = {
|
|
120
|
+
"json_schema_extra": {
|
|
121
|
+
"examples": [
|
|
122
|
+
{
|
|
123
|
+
"target_head_pose": {
|
|
124
|
+
"x": 0.0,
|
|
125
|
+
"y": 0.0,
|
|
126
|
+
"z": 0.0,
|
|
127
|
+
"roll": 0.0,
|
|
128
|
+
"pitch": 0.0,
|
|
129
|
+
"yaw": 0.0,
|
|
130
|
+
},
|
|
131
|
+
"target_antennas": [0.0, 0.0],
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class FullState(BaseModel):
|
|
139
|
+
"""Represent the full state of the robot including all joint positions and poses."""
|
|
140
|
+
|
|
141
|
+
control_mode: MotorControlMode | None = None
|
|
142
|
+
head_pose: AnyPose | None = None
|
|
143
|
+
head_joints: list[float] | None = None
|
|
144
|
+
body_yaw: float | None = None
|
|
145
|
+
antennas_position: list[float] | None = None
|
|
146
|
+
timestamp: datetime | None = None
|
|
147
|
+
passive_joints: list[float] | None = None
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""Apps router for apps management."""
|
|
2
|
+
|
|
3
|
+
from fastapi import (
|
|
4
|
+
APIRouter,
|
|
5
|
+
Depends,
|
|
6
|
+
HTTPException,
|
|
7
|
+
WebSocket,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from reachy_mini.apps import AppInfo, SourceKind
|
|
11
|
+
from reachy_mini.apps.manager import AppManager, AppStatus
|
|
12
|
+
from reachy_mini.daemon.app import bg_job_register
|
|
13
|
+
from reachy_mini.daemon.app.dependencies import get_app_manager
|
|
14
|
+
|
|
15
|
+
router = APIRouter(prefix="/apps")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@router.get("/list-available/{source_kind}")
|
|
19
|
+
async def list_available_apps(
|
|
20
|
+
source_kind: SourceKind,
|
|
21
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
22
|
+
) -> list[AppInfo]:
|
|
23
|
+
"""List available apps (including not installed)."""
|
|
24
|
+
return await app_manager.list_available_apps(source_kind)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@router.get("/list-available")
|
|
28
|
+
async def list_all_available_apps(
|
|
29
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
30
|
+
) -> list[AppInfo]:
|
|
31
|
+
"""List all available apps (including not installed)."""
|
|
32
|
+
return await app_manager.list_all_available_apps()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@router.post("/install")
|
|
36
|
+
async def install_app(
|
|
37
|
+
app_info: AppInfo,
|
|
38
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
39
|
+
) -> dict[str, str]:
|
|
40
|
+
"""Install a new app by its info (background, returns job_id)."""
|
|
41
|
+
job_id = bg_job_register.run_command(
|
|
42
|
+
"install", app_manager.install_new_app, app_info
|
|
43
|
+
)
|
|
44
|
+
return {"job_id": job_id}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@router.post("/remove/{app_name}")
|
|
48
|
+
async def remove_app(
|
|
49
|
+
app_name: str,
|
|
50
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
51
|
+
) -> dict[str, str]:
|
|
52
|
+
"""Remove an installed app by its name (background, returns job_id)."""
|
|
53
|
+
job_id = bg_job_register.run_command("remove", app_manager.remove_app, app_name)
|
|
54
|
+
return {"job_id": job_id}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@router.get("/job-status/{job_id}")
|
|
58
|
+
async def job_status(job_id: str) -> bg_job_register.JobInfo:
|
|
59
|
+
"""Get status/logs for a job."""
|
|
60
|
+
try:
|
|
61
|
+
return bg_job_register.get_info(job_id)
|
|
62
|
+
except Exception as e:
|
|
63
|
+
raise HTTPException(status_code=404, detail=str(e))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# WebSocket route for live job status/logs
|
|
67
|
+
@router.websocket("/ws/apps-manager/{job_id}")
|
|
68
|
+
async def ws_apps_manager(websocket: WebSocket, job_id: str) -> None:
|
|
69
|
+
"""WebSocket route to stream live job status/logs for a job, sending updates as soon as new logs are available."""
|
|
70
|
+
await websocket.accept()
|
|
71
|
+
await bg_job_register.ws_poll_info(websocket, job_id)
|
|
72
|
+
await websocket.close()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@router.post("/start-app/{app_name}")
|
|
76
|
+
async def start_app(
|
|
77
|
+
app_name: str,
|
|
78
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
79
|
+
) -> AppStatus:
|
|
80
|
+
"""Start an app by its name."""
|
|
81
|
+
try:
|
|
82
|
+
return await app_manager.start_app(app_name)
|
|
83
|
+
except RuntimeError as e:
|
|
84
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@router.post("/restart-current-app")
|
|
88
|
+
async def restart_app(
|
|
89
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
90
|
+
) -> AppStatus:
|
|
91
|
+
"""Restart the currently running app."""
|
|
92
|
+
try:
|
|
93
|
+
return await app_manager.restart_current_app()
|
|
94
|
+
except RuntimeError as e:
|
|
95
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@router.post("/stop-current-app")
|
|
99
|
+
async def stop_app(
|
|
100
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
101
|
+
) -> None:
|
|
102
|
+
"""Stop the currently running app."""
|
|
103
|
+
try:
|
|
104
|
+
return await app_manager.stop_current_app()
|
|
105
|
+
except RuntimeError as e:
|
|
106
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@router.get("/current-app-status")
|
|
110
|
+
async def current_app_status(
|
|
111
|
+
app_manager: "AppManager" = Depends(get_app_manager),
|
|
112
|
+
) -> AppStatus | None:
|
|
113
|
+
"""Get the status of the currently running app, if any."""
|
|
114
|
+
return await app_manager.current_app_status()
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Daemon-related API routes."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import threading
|
|
5
|
+
|
|
6
|
+
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
7
|
+
|
|
8
|
+
from reachy_mini.daemon.app import bg_job_register
|
|
9
|
+
|
|
10
|
+
from ...daemon import Daemon, DaemonStatus
|
|
11
|
+
from ..dependencies import get_daemon
|
|
12
|
+
|
|
13
|
+
router = APIRouter(
|
|
14
|
+
prefix="/daemon",
|
|
15
|
+
)
|
|
16
|
+
busy_lock = threading.Lock()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@router.post("/start")
|
|
20
|
+
async def start_daemon(
|
|
21
|
+
request: Request,
|
|
22
|
+
wake_up: bool,
|
|
23
|
+
daemon: Daemon = Depends(get_daemon),
|
|
24
|
+
) -> dict[str, str]:
|
|
25
|
+
"""Start the daemon."""
|
|
26
|
+
if busy_lock.locked():
|
|
27
|
+
raise HTTPException(status_code=409, detail="Daemon is busy.")
|
|
28
|
+
|
|
29
|
+
async def start(logger: logging.Logger) -> None:
|
|
30
|
+
with busy_lock:
|
|
31
|
+
await daemon.start(
|
|
32
|
+
sim=request.app.state.args.sim,
|
|
33
|
+
scene=request.app.state.args.scene,
|
|
34
|
+
headless=request.app.state.args.headless,
|
|
35
|
+
wake_up_on_start=wake_up,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
job_id = bg_job_register.run_command("daemon-start", start)
|
|
39
|
+
return {"job_id": job_id}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@router.post("/stop")
|
|
43
|
+
async def stop_daemon(
|
|
44
|
+
goto_sleep: bool, daemon: Daemon = Depends(get_daemon)
|
|
45
|
+
) -> dict[str, str]:
|
|
46
|
+
"""Stop the daemon, optionally putting the robot to sleep."""
|
|
47
|
+
if busy_lock.locked():
|
|
48
|
+
raise HTTPException(status_code=409, detail="Daemon is busy.")
|
|
49
|
+
|
|
50
|
+
async def stop(logger: logging.Logger) -> None:
|
|
51
|
+
with busy_lock:
|
|
52
|
+
await daemon.stop(goto_sleep_on_stop=goto_sleep)
|
|
53
|
+
|
|
54
|
+
job_id = bg_job_register.run_command("daemon-stop", stop)
|
|
55
|
+
return {"job_id": job_id}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@router.post("/restart")
|
|
59
|
+
async def restart_daemon(
|
|
60
|
+
request: Request, daemon: Daemon = Depends(get_daemon)
|
|
61
|
+
) -> dict[str, str]:
|
|
62
|
+
"""Restart the daemon."""
|
|
63
|
+
if busy_lock.locked():
|
|
64
|
+
raise HTTPException(status_code=409, detail="Daemon is busy.")
|
|
65
|
+
|
|
66
|
+
async def restart(logger: logging.Logger) -> None:
|
|
67
|
+
with busy_lock:
|
|
68
|
+
await daemon.restart(
|
|
69
|
+
sim=request.app.state.args.sim,
|
|
70
|
+
scene=request.app.state.args.scene,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
job_id = bg_job_register.run_command("daemon-restart", restart)
|
|
74
|
+
return {"job_id": job_id}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@router.get("/status")
|
|
78
|
+
async def get_daemon_status(daemon: Daemon = Depends(get_daemon)) -> DaemonStatus:
|
|
79
|
+
"""Get the current status of the daemon."""
|
|
80
|
+
return daemon.status()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Kinematics router for handling kinematics-related requests.
|
|
2
|
+
|
|
3
|
+
This module defines the API endpoints for interacting with the kinematics
|
|
4
|
+
subsystem of the robot. It provides endpoints for retrieving URDF representation,
|
|
5
|
+
and other kinematics-related information.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from fastapi import APIRouter, Depends, HTTPException, Response
|
|
12
|
+
|
|
13
|
+
from ....daemon.backend.abstract import Backend
|
|
14
|
+
from ..dependencies import get_backend
|
|
15
|
+
|
|
16
|
+
router = APIRouter(
|
|
17
|
+
prefix="/kinematics",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
STL_ASSETS_DIR = (
|
|
21
|
+
Path(__file__).parent.parent.parent.parent
|
|
22
|
+
/ "descriptions"
|
|
23
|
+
/ "reachy_mini"
|
|
24
|
+
/ "urdf"
|
|
25
|
+
/ "assets"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@router.get("/info")
|
|
30
|
+
async def get_kinematics_info(
|
|
31
|
+
backend: Backend = Depends(get_backend),
|
|
32
|
+
) -> dict[str, Any]:
|
|
33
|
+
"""Get the current information of the kinematics."""
|
|
34
|
+
return {
|
|
35
|
+
"info": {
|
|
36
|
+
"engine": backend.kinematics_engine,
|
|
37
|
+
"collision check": backend.check_collision,
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@router.get("/urdf")
|
|
43
|
+
async def get_urdf(backend: Backend = Depends(get_backend)) -> dict[str, str]:
|
|
44
|
+
"""Get the URDF representation of the robot."""
|
|
45
|
+
return {"urdf": backend.get_urdf()}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@router.get("/stl/{filename}")
|
|
49
|
+
async def get_stl_file(filename: Path) -> Response:
|
|
50
|
+
"""Get the path to an STL asset file."""
|
|
51
|
+
file_path = STL_ASSETS_DIR / filename
|
|
52
|
+
try:
|
|
53
|
+
with open(file_path, "rb") as file:
|
|
54
|
+
content = file.read()
|
|
55
|
+
return Response(content, media_type="model/stl")
|
|
56
|
+
except FileNotFoundError:
|
|
57
|
+
raise HTTPException(status_code=404, detail=f"STL file not found {file_path}")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Motors router.
|
|
2
|
+
|
|
3
|
+
Provides endpoints to get and set the motor control mode.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from fastapi import APIRouter, Depends
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from ....daemon.backend.abstract import Backend, MotorControlMode
|
|
10
|
+
from ..dependencies import get_backend
|
|
11
|
+
|
|
12
|
+
router = APIRouter(
|
|
13
|
+
prefix="/motors",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MotorStatus(BaseModel):
|
|
18
|
+
"""Represents the status of the motors.
|
|
19
|
+
|
|
20
|
+
Exposes
|
|
21
|
+
- mode: The current motor control mode (enabled, disabled, gravity_compensation).
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
mode: MotorControlMode
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@router.get("/status")
|
|
28
|
+
async def get_motor_status(backend: Backend = Depends(get_backend)) -> MotorStatus:
|
|
29
|
+
"""Get the current status of the motors."""
|
|
30
|
+
return MotorStatus(mode=backend.get_motor_control_mode())
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@router.post("/set_mode/{mode}")
|
|
34
|
+
async def set_motor_mode(
|
|
35
|
+
mode: MotorControlMode,
|
|
36
|
+
backend: Backend = Depends(get_backend),
|
|
37
|
+
) -> dict[str, str]:
|
|
38
|
+
"""Set the motor control mode."""
|
|
39
|
+
backend.set_motor_control_mode(mode)
|
|
40
|
+
|
|
41
|
+
return {"status": f"motors changed to {mode} mode"}
|