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,36 @@
|
|
|
1
|
+
"""MuJoCo Backend for Reachy Mini Daemon."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import mujoco # noqa: F401
|
|
7
|
+
|
|
8
|
+
from reachy_mini.daemon.backend.mujoco.backend import (
|
|
9
|
+
MujocoBackend,
|
|
10
|
+
MujocoBackendStatus,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
except ImportError:
|
|
14
|
+
|
|
15
|
+
class MujocoMockupBackend:
|
|
16
|
+
"""Mockup class to avoid import errors when MuJoCo is not installed."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
|
|
19
|
+
"""Raise ImportError when trying to instantiate the class."""
|
|
20
|
+
raise ImportError(
|
|
21
|
+
"MuJoCo is not installed. MuJoCo backend is not available."
|
|
22
|
+
" To use MuJoCo backend, please install the 'mujoco' extra dependencies"
|
|
23
|
+
" with 'pip install reachy_mini[mujoco]'."
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
MujocoBackend = MujocoMockupBackend # type: ignore[assignment, misc]
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class MujocoMockupBackendStatus:
|
|
30
|
+
"""Mockup class to avoid import errors when MuJoCo is not installed."""
|
|
31
|
+
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
MujocoBackendStatus = MujocoMockupBackendStatus # type: ignore[assignment, misc]
|
|
35
|
+
|
|
36
|
+
__all__ = ["MujocoBackend", "MujocoBackendStatus"]
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"""Mujoco Backend for Reachy Mini.
|
|
2
|
+
|
|
3
|
+
This module provides the MujocoBackend class for simulating the Reachy Mini robot using the MuJoCo physics engine.
|
|
4
|
+
|
|
5
|
+
It includes methods for running the simulation, getting joint positions, and controlling the robot's joints.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import time
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from importlib.resources import files
|
|
13
|
+
from threading import Thread
|
|
14
|
+
from typing import Annotated
|
|
15
|
+
|
|
16
|
+
import log_throttling
|
|
17
|
+
import mujoco
|
|
18
|
+
import mujoco.viewer
|
|
19
|
+
import numpy as np
|
|
20
|
+
import numpy.typing as npt
|
|
21
|
+
|
|
22
|
+
import reachy_mini
|
|
23
|
+
|
|
24
|
+
from ..abstract import Backend, MotorControlMode
|
|
25
|
+
from .utils import (
|
|
26
|
+
get_actuator_names,
|
|
27
|
+
get_joint_addr_from_name,
|
|
28
|
+
get_joint_id_from_name,
|
|
29
|
+
)
|
|
30
|
+
from .video_udp import UDPJPEGFrameSender
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MujocoBackend(Backend):
|
|
34
|
+
"""Simulated Reachy Mini using MuJoCo."""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
scene: str = "empty",
|
|
39
|
+
check_collision: bool = False,
|
|
40
|
+
kinematics_engine: str = "AnalyticalKinematics",
|
|
41
|
+
headless: bool = False,
|
|
42
|
+
) -> None:
|
|
43
|
+
"""Initialize the MujocoBackend with a specified scene.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
scene (str): The name of the scene to load. Default is "empty".
|
|
47
|
+
check_collision (bool): If True, enable collision checking. Default is False.
|
|
48
|
+
kinematics_engine (str): Kinematics engine to use. Defaults to "AnalyticalKinematics".
|
|
49
|
+
headless (bool): If True, run Mujoco in headless mode (no GUI). Default is False.
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
super().__init__(
|
|
53
|
+
check_collision=check_collision, kinematics_engine=kinematics_engine
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
self.headless = headless
|
|
57
|
+
|
|
58
|
+
from reachy_mini.reachy_mini import (
|
|
59
|
+
SLEEP_ANTENNAS_JOINT_POSITIONS,
|
|
60
|
+
SLEEP_HEAD_JOINT_POSITIONS,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Real robot convention for the order of the antennas joints is [right, left], but in mujoco it's [left, right]
|
|
64
|
+
self._SLEEP_ANTENNAS_JOINT_POSITIONS = [
|
|
65
|
+
SLEEP_ANTENNAS_JOINT_POSITIONS[1],
|
|
66
|
+
SLEEP_ANTENNAS_JOINT_POSITIONS[0],
|
|
67
|
+
]
|
|
68
|
+
self._SLEEP_HEAD_JOINT_POSITIONS = SLEEP_HEAD_JOINT_POSITIONS
|
|
69
|
+
|
|
70
|
+
mjcf_root_path = str(
|
|
71
|
+
files(reachy_mini).joinpath("descriptions/reachy_mini/mjcf/")
|
|
72
|
+
)
|
|
73
|
+
self.model = mujoco.MjModel.from_xml_path(
|
|
74
|
+
f"{mjcf_root_path}/scenes/{scene}.xml"
|
|
75
|
+
)
|
|
76
|
+
self.data = mujoco.MjData(self.model)
|
|
77
|
+
self.model.opt.timestep = 0.002 # s, simulation timestep, 500hz
|
|
78
|
+
self.decimation = 10 # -> 50hz control loop
|
|
79
|
+
self.rendering_timestep = 0.04 # s, rendering loop # 25Hz
|
|
80
|
+
|
|
81
|
+
self.camera_id = mujoco.mj_name2id(
|
|
82
|
+
self.model,
|
|
83
|
+
mujoco.mjtObj.mjOBJ_CAMERA,
|
|
84
|
+
"eye_camera",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
self.head_site_id = mujoco.mj_name2id(
|
|
88
|
+
self.model,
|
|
89
|
+
mujoco.mjtObj.mjOBJ_SITE,
|
|
90
|
+
"head",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
self.current_head_pose = np.eye(4)
|
|
94
|
+
|
|
95
|
+
# print("Joints in the model:")
|
|
96
|
+
# for i in range(self.model.njoint):
|
|
97
|
+
# name = mujoco.mj_id2joint(self.model, i)
|
|
98
|
+
# print(f" {i}: {name}")
|
|
99
|
+
|
|
100
|
+
self.joint_names = get_actuator_names(self.model)
|
|
101
|
+
|
|
102
|
+
self.joint_ids = [
|
|
103
|
+
get_joint_id_from_name(self.model, n) for n in self.joint_names
|
|
104
|
+
]
|
|
105
|
+
self.joint_qpos_addr = [
|
|
106
|
+
get_joint_addr_from_name(self.model, n) for n in self.joint_names
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
def rendering_loop(self) -> None:
|
|
110
|
+
"""Offline Rendering loop for the Mujoco simulation.
|
|
111
|
+
|
|
112
|
+
Capture the image from the virtual Reachy's camera and send it over UDP.
|
|
113
|
+
"""
|
|
114
|
+
streamer_udp = UDPJPEGFrameSender()
|
|
115
|
+
camera_size = (1280, 720)
|
|
116
|
+
offscreen_renderer = mujoco.Renderer(
|
|
117
|
+
self.model, height=camera_size[1], width=camera_size[0]
|
|
118
|
+
)
|
|
119
|
+
while not self.should_stop.is_set():
|
|
120
|
+
start_t = time.time()
|
|
121
|
+
offscreen_renderer.update_scene(self.data, self.camera_id)
|
|
122
|
+
im = offscreen_renderer.render()
|
|
123
|
+
streamer_udp.send_frame(im)
|
|
124
|
+
|
|
125
|
+
took = time.time() - start_t
|
|
126
|
+
time.sleep(max(0, self.rendering_timestep - took))
|
|
127
|
+
|
|
128
|
+
def run(self) -> None:
|
|
129
|
+
"""Run the Mujoco simulation with a viewer.
|
|
130
|
+
|
|
131
|
+
This method initializes the viewer and enters the main simulation loop.
|
|
132
|
+
It updates the joint positions at a rate and publishes the joint positions.
|
|
133
|
+
"""
|
|
134
|
+
step = 1
|
|
135
|
+
if not self.headless:
|
|
136
|
+
viewer = mujoco.viewer.launch_passive(
|
|
137
|
+
self.model, self.data, show_left_ui=False, show_right_ui=False
|
|
138
|
+
)
|
|
139
|
+
with viewer.lock():
|
|
140
|
+
viewer.cam.type = mujoco.mjtCamera.mjCAMERA_FREE
|
|
141
|
+
viewer.cam.distance = 0.8 # ≃ ||pos - lookat||
|
|
142
|
+
viewer.cam.azimuth = 160 # degrees
|
|
143
|
+
viewer.cam.elevation = -20 # degrees
|
|
144
|
+
viewer.cam.lookat[:] = [0, 0, 0.15]
|
|
145
|
+
|
|
146
|
+
# force one render with your new camera
|
|
147
|
+
mujoco.mj_step(self.model, self.data)
|
|
148
|
+
viewer.sync()
|
|
149
|
+
|
|
150
|
+
# im = self.get_camera()
|
|
151
|
+
# self.streamer_udp.send_frame(im)
|
|
152
|
+
|
|
153
|
+
self.data.qpos[self.joint_qpos_addr] = np.array(
|
|
154
|
+
self._SLEEP_HEAD_JOINT_POSITIONS
|
|
155
|
+
+ self._SLEEP_ANTENNAS_JOINT_POSITIONS
|
|
156
|
+
).reshape(-1, 1)
|
|
157
|
+
self.data.ctrl[:] = np.array(
|
|
158
|
+
self._SLEEP_HEAD_JOINT_POSITIONS
|
|
159
|
+
+ self._SLEEP_ANTENNAS_JOINT_POSITIONS
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# recompute all kinematics, collisions, etc.
|
|
163
|
+
mujoco.mj_forward(self.model, self.data)
|
|
164
|
+
|
|
165
|
+
# one more frame so the viewer shows your startup pose
|
|
166
|
+
mujoco.mj_step(self.model, self.data)
|
|
167
|
+
if not self.headless:
|
|
168
|
+
viewer.sync()
|
|
169
|
+
|
|
170
|
+
rendering_thread = Thread(target=self.rendering_loop, daemon=True)
|
|
171
|
+
rendering_thread.start()
|
|
172
|
+
|
|
173
|
+
# 3) now enter your normal loop
|
|
174
|
+
while not self.should_stop.is_set():
|
|
175
|
+
start_t = time.time()
|
|
176
|
+
|
|
177
|
+
if step % self.decimation == 0:
|
|
178
|
+
# update the current states
|
|
179
|
+
self.current_head_joint_positions = (
|
|
180
|
+
self.get_present_head_joint_positions()
|
|
181
|
+
)
|
|
182
|
+
self.current_antenna_joint_positions = (
|
|
183
|
+
self.get_present_antenna_joint_positions()
|
|
184
|
+
)
|
|
185
|
+
self.current_head_pose = self.get_mj_present_head_pose()
|
|
186
|
+
|
|
187
|
+
# Update the target head joint positions from IK if necessary
|
|
188
|
+
# - does nothing if the targets did not change
|
|
189
|
+
if self.ik_required:
|
|
190
|
+
try:
|
|
191
|
+
self.update_target_head_joints_from_ik(
|
|
192
|
+
self.target_head_pose, self.target_body_yaw
|
|
193
|
+
)
|
|
194
|
+
except ValueError as e:
|
|
195
|
+
log_throttling.by_time(self.logger, interval=0.5).warning(
|
|
196
|
+
f"IK error: {e}"
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
if self.target_head_joint_positions is not None:
|
|
200
|
+
self.data.ctrl[:7] = self.target_head_joint_positions
|
|
201
|
+
if self.target_antenna_joint_positions is not None:
|
|
202
|
+
self.data.ctrl[-2:] = -self.target_antenna_joint_positions
|
|
203
|
+
|
|
204
|
+
if (
|
|
205
|
+
self.joint_positions_publisher is not None
|
|
206
|
+
and self.pose_publisher is not None
|
|
207
|
+
):
|
|
208
|
+
if not self.is_shutting_down:
|
|
209
|
+
self.joint_positions_publisher.put(
|
|
210
|
+
json.dumps(
|
|
211
|
+
{
|
|
212
|
+
"head_joint_positions": self.current_head_joint_positions.tolist(),
|
|
213
|
+
"antennas_joint_positions": self.current_antenna_joint_positions.tolist(),
|
|
214
|
+
}
|
|
215
|
+
).encode("utf-8")
|
|
216
|
+
)
|
|
217
|
+
self.pose_publisher.put(
|
|
218
|
+
json.dumps(
|
|
219
|
+
{
|
|
220
|
+
"head_pose": self.get_present_head_pose().tolist(),
|
|
221
|
+
}
|
|
222
|
+
).encode("utf-8")
|
|
223
|
+
)
|
|
224
|
+
self.ready.set()
|
|
225
|
+
|
|
226
|
+
if not self.headless:
|
|
227
|
+
viewer.sync()
|
|
228
|
+
|
|
229
|
+
mujoco.mj_step(self.model, self.data)
|
|
230
|
+
|
|
231
|
+
took = time.time() - start_t
|
|
232
|
+
time.sleep(max(0, self.model.opt.timestep - took))
|
|
233
|
+
# print(f"Step {step}: took {took*1000:.1f}ms")
|
|
234
|
+
step += 1
|
|
235
|
+
|
|
236
|
+
if not self.headless:
|
|
237
|
+
viewer.close()
|
|
238
|
+
|
|
239
|
+
def get_mj_present_head_pose(self) -> Annotated[npt.NDArray[np.float64], (4, 4)]:
|
|
240
|
+
"""Get the current head pose from the Mujoco simulation.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
np.ndarray: The current head pose as a 4x4 transformation matrix.
|
|
244
|
+
|
|
245
|
+
"""
|
|
246
|
+
mj_current_head_pose = np.eye(4)
|
|
247
|
+
|
|
248
|
+
mj_current_head_pose[:3, :3] = self.data.site_xmat[self.head_site_id].reshape(
|
|
249
|
+
3, 3
|
|
250
|
+
)
|
|
251
|
+
mj_current_head_pose[:3, 3] = self.data.site_xpos[self.head_site_id]
|
|
252
|
+
mj_current_head_pose[2, 3] -= 0.177
|
|
253
|
+
return mj_current_head_pose
|
|
254
|
+
|
|
255
|
+
def close(self) -> None:
|
|
256
|
+
"""Close the Mujoco backend."""
|
|
257
|
+
# TODO Do something in mujoco here ?
|
|
258
|
+
pass
|
|
259
|
+
|
|
260
|
+
def get_status(self) -> "MujocoBackendStatus":
|
|
261
|
+
"""Get the status of the Mujoco backend.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
dict: An empty dictionary as the Mujoco backend does not have a specific status to report.
|
|
265
|
+
|
|
266
|
+
"""
|
|
267
|
+
return MujocoBackendStatus(motor_control_mode=self.get_motor_control_mode())
|
|
268
|
+
|
|
269
|
+
def get_present_head_joint_positions(
|
|
270
|
+
self,
|
|
271
|
+
) -> Annotated[npt.NDArray[np.float64], (7,)]:
|
|
272
|
+
"""Get the current joint positions of the head."""
|
|
273
|
+
pos: npt.NDArray[np.float64] = self.data.qpos[
|
|
274
|
+
self.joint_qpos_addr[:7]
|
|
275
|
+
].flatten()
|
|
276
|
+
return pos
|
|
277
|
+
|
|
278
|
+
def get_present_antenna_joint_positions(
|
|
279
|
+
self,
|
|
280
|
+
) -> Annotated[npt.NDArray[np.float64], (2,)]:
|
|
281
|
+
"""Get the current joint positions of the antennas."""
|
|
282
|
+
pos: npt.NDArray[np.float64] = self.data.qpos[
|
|
283
|
+
self.joint_qpos_addr[-2:]
|
|
284
|
+
].flatten()
|
|
285
|
+
return -pos
|
|
286
|
+
|
|
287
|
+
def get_motor_control_mode(self) -> MotorControlMode:
|
|
288
|
+
"""Get the motor control mode."""
|
|
289
|
+
return MotorControlMode.Enabled
|
|
290
|
+
|
|
291
|
+
def set_motor_control_mode(self, mode: MotorControlMode) -> None:
|
|
292
|
+
"""Set the motor control mode."""
|
|
293
|
+
pass
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@dataclass
|
|
297
|
+
class MujocoBackendStatus:
|
|
298
|
+
"""Dataclass to represent the status of the Mujoco backend.
|
|
299
|
+
|
|
300
|
+
Empty for now, as the Mujoco backend does not have a specific status to report.
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
motor_control_mode: MotorControlMode
|
|
304
|
+
error: str | None = None
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Mujoco utilities for Reachy Mini.
|
|
2
|
+
|
|
3
|
+
This module provides utility functions for working with MuJoCo models, including
|
|
4
|
+
homogeneous transformation matrices, joint positions, and actuator names.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import mujoco
|
|
10
|
+
import numpy as np
|
|
11
|
+
import numpy.typing as npt
|
|
12
|
+
from mujoco._structs import MjData, MjModel
|
|
13
|
+
from scipy.spatial.transform import Rotation as R
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_homogeneous_matrix_from_euler(
|
|
17
|
+
position: tuple[float, float, float] = (0, 0, 0), # (x, y, z) meters
|
|
18
|
+
euler_angles: tuple[float, float, float] = (0, 0, 0), # (roll, pitch, yaw)
|
|
19
|
+
degrees: bool = False,
|
|
20
|
+
) -> Annotated[npt.NDArray[np.float64], (4, 4)]:
|
|
21
|
+
"""Return a homogeneous transformation matrix from position and Euler angles."""
|
|
22
|
+
homogeneous_matrix = np.eye(4)
|
|
23
|
+
homogeneous_matrix[:3, :3] = R.from_euler(
|
|
24
|
+
"xyz", euler_angles, degrees=degrees
|
|
25
|
+
).as_matrix()
|
|
26
|
+
homogeneous_matrix[:3, 3] = position
|
|
27
|
+
return homogeneous_matrix
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_joint_qpos(model: MjModel, data: MjData, joint_name: str) -> float:
|
|
31
|
+
"""Return the qpos (rad) of a specified joint in the model."""
|
|
32
|
+
# Get the joint id
|
|
33
|
+
joint_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, joint_name)
|
|
34
|
+
if joint_id == -1:
|
|
35
|
+
raise ValueError(f"Joint '{joint_name}' not found.")
|
|
36
|
+
|
|
37
|
+
# Get the address of the joint's qpos in the qpos array
|
|
38
|
+
qpos_addr = model.jnt_qposadr[joint_id]
|
|
39
|
+
|
|
40
|
+
# Get the qpos value
|
|
41
|
+
qpos: float = data.qpos[qpos_addr]
|
|
42
|
+
return qpos
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_joint_id_from_name(model: MjModel, name: str) -> int:
|
|
46
|
+
"""Return the id of a specified joint."""
|
|
47
|
+
return mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, name) # type: ignore
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_joint_addr_from_name(model: MjModel, name: str) -> int:
|
|
51
|
+
"""Return the address of a specified joint."""
|
|
52
|
+
addr: int = model.joint(name).qposadr
|
|
53
|
+
return addr
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_actuator_names(model: MjModel) -> list[str]:
|
|
57
|
+
"""Return the list of the actuators names from the MuJoCo model."""
|
|
58
|
+
actuator_names = [model.actuator(k).name for k in range(0, model.nu)]
|
|
59
|
+
return actuator_names
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""UDP JPEG Frame Sender.
|
|
2
|
+
|
|
3
|
+
This module provides a class to send JPEG frames over UDP. It encodes the frames as JPEG images and splits them into chunks to fit within the maximum packet size for UDP transmission.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import socket
|
|
7
|
+
import struct
|
|
8
|
+
|
|
9
|
+
import cv2
|
|
10
|
+
import numpy as np
|
|
11
|
+
import numpy.typing as npt
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class UDPJPEGFrameSender:
|
|
15
|
+
"""A class to send JPEG frames over UDP."""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
dest_ip: str = "127.0.0.1",
|
|
20
|
+
dest_port: int = 5005,
|
|
21
|
+
max_packet_size: int = 1400,
|
|
22
|
+
) -> None:
|
|
23
|
+
"""Initialize the UDPJPEGFrameSender.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
dest_ip (str): Destination IP address.
|
|
27
|
+
dest_port (int): Destination port number.
|
|
28
|
+
max_packet_size (int): Maximum size of each UDP packet.
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
self.addr = (dest_ip, dest_port)
|
|
32
|
+
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
33
|
+
self.max_packet_size = max_packet_size
|
|
34
|
+
|
|
35
|
+
def send_frame(self, frame: npt.NDArray[np.uint8]) -> None:
|
|
36
|
+
"""Send a frame as a JPEG image over UDP.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
frame (np.ndarray): The frame to be sent, in RGB format.
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
frame_cvt = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
|
|
43
|
+
ret, jpeg_bytes = cv2.imencode(
|
|
44
|
+
".jpg", frame_cvt, [int(cv2.IMWRITE_JPEG_QUALITY), 80]
|
|
45
|
+
)
|
|
46
|
+
data = jpeg_bytes.tobytes()
|
|
47
|
+
total_size = len(data)
|
|
48
|
+
n_chunks = (total_size + self.max_packet_size - 1) // self.max_packet_size
|
|
49
|
+
self.sock.sendto(struct.pack("!II", n_chunks, total_size), self.addr)
|
|
50
|
+
for i in range(n_chunks):
|
|
51
|
+
start = i * self.max_packet_size
|
|
52
|
+
end = min(start + self.max_packet_size, total_size)
|
|
53
|
+
self.sock.sendto(data[start:end], self.addr)
|