reachy-mini 1.2.5rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reachy_mini/__init__.py +4 -0
- reachy_mini/apps/__init__.py +25 -0
- reachy_mini/apps/app.py +258 -0
- reachy_mini/apps/assistant.py +787 -0
- reachy_mini/apps/manager.py +312 -0
- reachy_mini/apps/sources/__init__.py +4 -0
- reachy_mini/apps/sources/hf_space.py +106 -0
- reachy_mini/apps/sources/local_common_venv.py +567 -0
- reachy_mini/apps/templates/README.md.j2 +12 -0
- reachy_mini/apps/templates/gitignore.j2 +3 -0
- reachy_mini/apps/templates/index.html.j2 +40 -0
- reachy_mini/apps/templates/main.py.j2 +74 -0
- reachy_mini/apps/templates/pyproject.toml.j2 +28 -0
- reachy_mini/apps/templates/static/index.html.j2 +27 -0
- reachy_mini/apps/templates/static/main.js.j2 +47 -0
- reachy_mini/apps/templates/static/style.css.j2 +25 -0
- reachy_mini/apps/templates/style.css.j2 +411 -0
- reachy_mini/apps/utils.py +30 -0
- reachy_mini/assets/config/hardware_config.yaml +164 -0
- reachy_mini/assets/confused1.wav +0 -0
- reachy_mini/assets/count.wav +0 -0
- reachy_mini/assets/dance1.wav +0 -0
- reachy_mini/assets/firmware/CHANGELOG.md +15 -0
- reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.2.bin +0 -0
- reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.3.bin +0 -0
- reachy_mini/assets/firmware/update.sh +9 -0
- reachy_mini/assets/go_sleep.wav +0 -0
- reachy_mini/assets/impatient1.wav +0 -0
- reachy_mini/assets/kinematics_data.json +253 -0
- reachy_mini/assets/models/fknetwork.dynamic.onnx +0 -0
- reachy_mini/assets/models/fknetwork.onnx +0 -0
- reachy_mini/assets/models/fknetwork_int8.onnx +0 -0
- reachy_mini/assets/models/iknetwork.onnx +0 -0
- reachy_mini/assets/wake_up.wav +0 -0
- reachy_mini/daemon/__init__.py +1 -0
- reachy_mini/daemon/app/__init__.py +1 -0
- reachy_mini/daemon/app/bg_job_register.py +142 -0
- reachy_mini/daemon/app/dashboard/static/assets/KO-cartoon-static.svg +40 -0
- reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon-static.svg +42 -0
- reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/go-to-sleep-cartoon.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon-static.svg +50 -0
- reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-awake.svg +18 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-connection-lost-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-go-to-sleep-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko.svg +22 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping-static.svg +41 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping.svg +18 -0
- reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-wake-up-animation.svg +6 -0
- reachy_mini/daemon/app/dashboard/static/css/app.css +1433 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Archivo-Italic-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Archivo-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Asap-Italic-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/fonts/Asap-VariableFont_wdth,wght.ttf +0 -0
- reachy_mini/daemon/app/dashboard/static/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
- reachy_mini/daemon/app/dashboard/static/js/apps.js +323 -0
- reachy_mini/daemon/app/dashboard/static/js/appstore.js +167 -0
- reachy_mini/daemon/app/dashboard/static/js/daemon.js +169 -0
- reachy_mini/daemon/app/dashboard/static/js/health_check.js +9 -0
- reachy_mini/daemon/app/dashboard/static/js/move_player.js +132 -0
- reachy_mini/daemon/app/dashboard/static/js/notification.js +41 -0
- reachy_mini/daemon/app/dashboard/static/js/update.js +132 -0
- reachy_mini/daemon/app/dashboard/static/js/volume_control.js +252 -0
- reachy_mini/daemon/app/dashboard/static/js/wifi.js +176 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/README.md +15 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/package-lock.json +1127 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/package.json +6 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/pnpm-lock.yaml +608 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/postcss.config.js +6 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/styles/app.css +185 -0
- reachy_mini/daemon/app/dashboard/tailwindcss/tailwind.config.js +11 -0
- reachy_mini/daemon/app/dashboard/templates/base.html +21 -0
- reachy_mini/daemon/app/dashboard/templates/index.html +20 -0
- reachy_mini/daemon/app/dashboard/templates/sections/apps.html +8 -0
- reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +35 -0
- reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +45 -0
- reachy_mini/daemon/app/dashboard/templates/sections/move_player.html +121 -0
- reachy_mini/daemon/app/dashboard/templates/sections/notification.html +19 -0
- reachy_mini/daemon/app/dashboard/templates/sections/update.html +54 -0
- reachy_mini/daemon/app/dashboard/templates/sections/wifi.html +46 -0
- reachy_mini/daemon/app/dashboard/templates/settings.html +14 -0
- reachy_mini/daemon/app/dependencies.py +41 -0
- reachy_mini/daemon/app/main.py +469 -0
- reachy_mini/daemon/app/models.py +149 -0
- reachy_mini/daemon/app/routers/apps.py +114 -0
- reachy_mini/daemon/app/routers/daemon.py +85 -0
- reachy_mini/daemon/app/routers/kinematics.py +57 -0
- reachy_mini/daemon/app/routers/motors.py +41 -0
- reachy_mini/daemon/app/routers/move.py +265 -0
- reachy_mini/daemon/app/routers/state.py +146 -0
- reachy_mini/daemon/app/routers/update.py +86 -0
- reachy_mini/daemon/app/routers/volume.py +423 -0
- reachy_mini/daemon/app/routers/wifi_config.py +219 -0
- reachy_mini/daemon/app/services/__init__.py +1 -0
- reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py +796 -0
- reachy_mini/daemon/app/services/bluetooth/commands/HOTSPOT.sh +7 -0
- reachy_mini/daemon/app/services/bluetooth/commands/RESTART_DAEMON.sh +4 -0
- reachy_mini/daemon/app/services/bluetooth/commands/SOFTWARE_RESET.sh +7 -0
- reachy_mini/daemon/app/services/bluetooth/install_service_bluetooth.sh +39 -0
- reachy_mini/daemon/app/services/gpio_shutdown/__init__.py +1 -0
- reachy_mini/daemon/app/services/gpio_shutdown/install_service.sh +33 -0
- reachy_mini/daemon/app/services/gpio_shutdown/launcher.sh +3 -0
- reachy_mini/daemon/app/services/gpio_shutdown/shutdown_monitor.py +28 -0
- reachy_mini/daemon/app/services/wireless/generate_asoundrc.sh +70 -0
- reachy_mini/daemon/app/services/wireless/install_service.sh +33 -0
- reachy_mini/daemon/app/services/wireless/launcher.sh +5 -0
- reachy_mini/daemon/backend/__init__.py +1 -0
- reachy_mini/daemon/backend/abstract.py +815 -0
- reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
- reachy_mini/daemon/backend/mujoco/backend.py +395 -0
- reachy_mini/daemon/backend/mujoco/utils.py +59 -0
- reachy_mini/daemon/backend/mujoco/video_udp.py +57 -0
- reachy_mini/daemon/backend/robot/__init__.py +8 -0
- reachy_mini/daemon/backend/robot/backend.py +597 -0
- reachy_mini/daemon/daemon.py +651 -0
- reachy_mini/daemon/utils.py +116 -0
- reachy_mini/descriptions/reachy_mini/mjcf/additional.xml +6 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/README.m +1 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/croissant_1k.obj +5021 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/textures/croissant_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/food_apple_01_1k.obj +18045 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/textures/food_apple_01_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/rubber_duck_toy_1k.obj +8940 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/textures/rubber_duck_toy_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/textures/wooden_table_02_diff_1k.png +0 -0
- reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/wooden_table_02_1k.obj +485 -0
- reachy_mini/descriptions/reachy_mini/mjcf/config.json +21 -0
- reachy_mini/descriptions/reachy_mini/mjcf/joints_properties.xml +29 -0
- reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml +642 -0
- reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml.bak +442 -0
- reachy_mini/descriptions/reachy_mini/mjcf/scene.xml +24 -0
- reachy_mini/descriptions/reachy_mini/mjcf/scenes/empty.xml +27 -0
- reachy_mini/descriptions/reachy_mini/mjcf/scenes/minimal.xml +132 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arm.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/arm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/ball.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/ball.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/README.m +1 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/foot.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/foot.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/shape.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/shape.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.part +13 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.part +14 -0
- reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.stl +0 -0
- reachy_mini/descriptions/reachy_mini/urdf/config.json +18 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot.urdf +3281 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot.urdf.bak +3282 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot_no_collision.urdf +2316 -0
- reachy_mini/descriptions/reachy_mini/urdf/robot_simple_collision.urdf +2399 -0
- reachy_mini/io/__init__.py +15 -0
- reachy_mini/io/abstract.py +70 -0
- reachy_mini/io/audio_ws.py +242 -0
- reachy_mini/io/protocol.py +44 -0
- reachy_mini/io/video_ws.py +135 -0
- reachy_mini/io/ws_controller.py +120 -0
- reachy_mini/io/zenoh_client.py +273 -0
- reachy_mini/io/zenoh_server.py +230 -0
- reachy_mini/kinematics/__init__.py +68 -0
- reachy_mini/kinematics/analytical_kinematics.py +151 -0
- reachy_mini/kinematics/nn_kinematics.py +109 -0
- reachy_mini/kinematics/placo_kinematics.py +656 -0
- reachy_mini/media/__init__.py +1 -0
- reachy_mini/media/audio_base.py +111 -0
- reachy_mini/media/audio_control_utils.py +455 -0
- reachy_mini/media/audio_gstreamer.py +272 -0
- reachy_mini/media/audio_sounddevice.py +321 -0
- reachy_mini/media/audio_utils.py +114 -0
- reachy_mini/media/camera_base.py +100 -0
- reachy_mini/media/camera_constants.py +152 -0
- reachy_mini/media/camera_gstreamer.py +231 -0
- reachy_mini/media/camera_opencv.py +89 -0
- reachy_mini/media/camera_utils.py +111 -0
- reachy_mini/media/media_manager.py +281 -0
- reachy_mini/media/webrtc_client_gstreamer.py +288 -0
- reachy_mini/media/webrtc_daemon.py +334 -0
- reachy_mini/motion/__init__.py +4 -0
- reachy_mini/motion/goto.py +71 -0
- reachy_mini/motion/move.py +43 -0
- reachy_mini/motion/recorded_move.py +146 -0
- reachy_mini/reachy_mini.py +753 -0
- reachy_mini/tools/reflash_motors.py +116 -0
- reachy_mini/tools/setup_motor.py +422 -0
- reachy_mini/tools/setup_motor_rpi.py +108 -0
- reachy_mini/utils/__init__.py +46 -0
- reachy_mini/utils/constants.py +9 -0
- reachy_mini/utils/hardware_config/__init__.py +1 -0
- reachy_mini/utils/hardware_config/parser.py +65 -0
- reachy_mini/utils/interpolation.py +227 -0
- reachy_mini/utils/parse_urdf_for_kinematics.py +110 -0
- reachy_mini/utils/rerun.py +320 -0
- reachy_mini/utils/wireless_version/__init__.py +1 -0
- reachy_mini/utils/wireless_version/startup_check.py +144 -0
- reachy_mini/utils/wireless_version/update.py +20 -0
- reachy_mini/utils/wireless_version/update_available.py +61 -0
- reachy_mini/utils/wireless_version/utils.py +39 -0
- reachy_mini-1.2.5rc1.dist-info/METADATA +161 -0
- reachy_mini-1.2.5rc1.dist-info/RECORD +479 -0
- reachy_mini-1.2.5rc1.dist-info/WHEEL +5 -0
- reachy_mini-1.2.5rc1.dist-info/entry_points.txt +4 -0
- reachy_mini-1.2.5rc1.dist-info/licenses/LICENSE +201 -0
- reachy_mini-1.2.5rc1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,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,395 @@
|
|
|
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, Any, Optional
|
|
15
|
+
|
|
16
|
+
import cv2
|
|
17
|
+
import log_throttling
|
|
18
|
+
import mujoco
|
|
19
|
+
import mujoco.viewer
|
|
20
|
+
import numpy as np
|
|
21
|
+
import numpy.typing as npt
|
|
22
|
+
|
|
23
|
+
import reachy_mini
|
|
24
|
+
from reachy_mini.io.video_ws import AsyncWebSocketFrameSender
|
|
25
|
+
|
|
26
|
+
from ..abstract import Backend, MotorControlMode
|
|
27
|
+
from .utils import (
|
|
28
|
+
get_actuator_names,
|
|
29
|
+
get_joint_addr_from_name,
|
|
30
|
+
get_joint_id_from_name,
|
|
31
|
+
)
|
|
32
|
+
from .video_udp import UDPJPEGFrameSender
|
|
33
|
+
|
|
34
|
+
CAMERA_REACHY = "eye_camera"
|
|
35
|
+
CAMERA_STUDIO_CLOSE = "studio_close"
|
|
36
|
+
CAMERA_SIZES = {CAMERA_REACHY: (1280, 720), CAMERA_STUDIO_CLOSE: (640, 640)}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class MujocoBackend(Backend):
|
|
40
|
+
"""Simulated Reachy Mini using MuJoCo."""
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
scene: str = "empty",
|
|
45
|
+
check_collision: bool = False,
|
|
46
|
+
kinematics_engine: str = "AnalyticalKinematics",
|
|
47
|
+
headless: bool = False,
|
|
48
|
+
use_audio: bool = False,
|
|
49
|
+
websocket_uri: Optional[str] = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Initialize the MujocoBackend with a specified scene.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
scene (str): The name of the scene to load. Default is "empty".
|
|
55
|
+
check_collision (bool): If True, enable collision checking. Default is False.
|
|
56
|
+
kinematics_engine (str): Kinematics engine to use. Defaults to "AnalyticalKinematics".
|
|
57
|
+
headless (bool): If True, run Mujoco in headless mode (no GUI). Default is False.
|
|
58
|
+
use_audio (bool): If True, use audio. Default is False.
|
|
59
|
+
websocket_uri (Optional[str]): If set, allow streaming of the robot view through a WebSocket connection to the specified uri. Defaults to None.
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
super().__init__(
|
|
63
|
+
check_collision=check_collision,
|
|
64
|
+
kinematics_engine=kinematics_engine,
|
|
65
|
+
use_audio=use_audio,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
self.headless = headless
|
|
69
|
+
self.websocket_uri = websocket_uri
|
|
70
|
+
|
|
71
|
+
from reachy_mini.reachy_mini import (
|
|
72
|
+
SLEEP_ANTENNAS_JOINT_POSITIONS,
|
|
73
|
+
SLEEP_HEAD_JOINT_POSITIONS,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Real robot convention for the order of the antennas joints is [right, left], but in mujoco it's [left, right]
|
|
77
|
+
self._SLEEP_ANTENNAS_JOINT_POSITIONS = [
|
|
78
|
+
SLEEP_ANTENNAS_JOINT_POSITIONS[1],
|
|
79
|
+
SLEEP_ANTENNAS_JOINT_POSITIONS[0],
|
|
80
|
+
]
|
|
81
|
+
self._SLEEP_HEAD_JOINT_POSITIONS = SLEEP_HEAD_JOINT_POSITIONS
|
|
82
|
+
|
|
83
|
+
mjcf_root_path = str(
|
|
84
|
+
files(reachy_mini).joinpath("descriptions/reachy_mini/mjcf/")
|
|
85
|
+
)
|
|
86
|
+
self.model = mujoco.MjModel.from_xml_path(
|
|
87
|
+
f"{mjcf_root_path}/scenes/{scene}.xml"
|
|
88
|
+
)
|
|
89
|
+
self.data = mujoco.MjData(self.model)
|
|
90
|
+
self.model.opt.timestep = 0.002 # s, simulation timestep, 500hz
|
|
91
|
+
self.decimation = 10 # -> 50hz control loop
|
|
92
|
+
self.rendering_timestep = 0.04 # s, rendering loop # 25Hz
|
|
93
|
+
self.streaming_timestep = 0.04 # s, streaming loop # 25Hz
|
|
94
|
+
|
|
95
|
+
self.head_site_id = mujoco.mj_name2id(
|
|
96
|
+
self.model,
|
|
97
|
+
mujoco.mjtObj.mjOBJ_SITE,
|
|
98
|
+
"head",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
self.current_head_pose = np.eye(4)
|
|
102
|
+
|
|
103
|
+
self.joint_names = get_actuator_names(self.model)
|
|
104
|
+
|
|
105
|
+
self.joint_ids = [
|
|
106
|
+
get_joint_id_from_name(self.model, n) for n in self.joint_names
|
|
107
|
+
]
|
|
108
|
+
self.joint_qpos_addr = [
|
|
109
|
+
get_joint_addr_from_name(self.model, n) for n in self.joint_names
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
# Disable collisions at the beginning for smoother initialization
|
|
113
|
+
self.col_inds = []
|
|
114
|
+
for i, type in enumerate(self.model.geom_contype):
|
|
115
|
+
if type != 0:
|
|
116
|
+
geom_name = mujoco.mj_id2name(self.model, mujoco.mjtObj.mjOBJ_GEOM, i)
|
|
117
|
+
# monkey-patch: the geoms in the minimal scene are named (duck_geom, table_top_collision ... ).
|
|
118
|
+
# We don't disable the collision for them so that the objects don't fall to the ground at initialization
|
|
119
|
+
if geom_name is None:
|
|
120
|
+
self.col_inds.append(i)
|
|
121
|
+
self.model.geom_contype[i] = 0
|
|
122
|
+
self.model.geom_conaffinity[i] = 0
|
|
123
|
+
|
|
124
|
+
def _get_camera_id(self, camera_name: str) -> Any:
|
|
125
|
+
"""Get the id of the virtual camera."""
|
|
126
|
+
return mujoco.mj_name2id(
|
|
127
|
+
self.model,
|
|
128
|
+
mujoco.mjtObj.mjOBJ_CAMERA,
|
|
129
|
+
camera_name,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def _get_renderer(self, camera_name: str) -> mujoco.Renderer:
|
|
133
|
+
"""Get the renderer for the virtual camera."""
|
|
134
|
+
camera_size = CAMERA_SIZES[camera_name]
|
|
135
|
+
return mujoco.Renderer(self.model, height=camera_size[1], width=camera_size[0])
|
|
136
|
+
|
|
137
|
+
def streaming_loop(self, camera_name: str, ws_uri: str) -> None:
|
|
138
|
+
"""Streaming loop for the Mujoco simulation over WebSocket.
|
|
139
|
+
|
|
140
|
+
Capture the image from the virtual camera and send it over WebSocket to the ws_uri.
|
|
141
|
+
"""
|
|
142
|
+
streamer = AsyncWebSocketFrameSender(ws_uri=ws_uri + "/video_stream")
|
|
143
|
+
offscreen_renderer = self._get_renderer(camera_name)
|
|
144
|
+
camera_id = self._get_camera_id(camera_name)
|
|
145
|
+
|
|
146
|
+
while not self.should_stop.is_set():
|
|
147
|
+
start_t = time.time()
|
|
148
|
+
offscreen_renderer.update_scene(self.data, camera_id)
|
|
149
|
+
|
|
150
|
+
# OPTIMIZATION: Disable expensive rendering effects on the scene
|
|
151
|
+
offscreen_renderer.scene.flags[mujoco.mjtRndFlag.mjRND_SHADOW] = 0
|
|
152
|
+
offscreen_renderer.scene.flags[mujoco.mjtRndFlag.mjRND_REFLECTION] = 0
|
|
153
|
+
|
|
154
|
+
im = offscreen_renderer.render()
|
|
155
|
+
|
|
156
|
+
im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR)
|
|
157
|
+
streamer.send_frame(im)
|
|
158
|
+
|
|
159
|
+
took = time.time() - start_t
|
|
160
|
+
time.sleep(max(0, self.streaming_timestep - took))
|
|
161
|
+
|
|
162
|
+
def rendering_loop(self, camera_name: str, port: int) -> None:
|
|
163
|
+
"""Offline Rendering loop for the Mujoco simulation.
|
|
164
|
+
|
|
165
|
+
Capture the image from the virtual camera_name and send it over UDP to the port or over WebSocket to the ws_uri.
|
|
166
|
+
"""
|
|
167
|
+
streamer = UDPJPEGFrameSender(dest_port=port)
|
|
168
|
+
offscreen_renderer = self._get_renderer(camera_name)
|
|
169
|
+
camera_id = self._get_camera_id(camera_name)
|
|
170
|
+
|
|
171
|
+
while not self.should_stop.is_set():
|
|
172
|
+
start_t = time.time()
|
|
173
|
+
offscreen_renderer.update_scene(self.data, camera_id)
|
|
174
|
+
|
|
175
|
+
im = offscreen_renderer.render()
|
|
176
|
+
streamer.send_frame(im)
|
|
177
|
+
|
|
178
|
+
took = time.time() - start_t
|
|
179
|
+
time.sleep(max(0, self.rendering_timestep - took))
|
|
180
|
+
|
|
181
|
+
def run(self) -> None:
|
|
182
|
+
"""Run the Mujoco simulation with a viewer.
|
|
183
|
+
|
|
184
|
+
This method initializes the viewer and enters the main simulation loop.
|
|
185
|
+
It updates the joint positions at a rate and publishes the joint positions.
|
|
186
|
+
"""
|
|
187
|
+
step = 1
|
|
188
|
+
if self.websocket_uri:
|
|
189
|
+
robot_view_streaming_thread = Thread(
|
|
190
|
+
target=self.streaming_loop,
|
|
191
|
+
args=(CAMERA_STUDIO_CLOSE, self.websocket_uri),
|
|
192
|
+
daemon=True,
|
|
193
|
+
)
|
|
194
|
+
robot_view_streaming_thread.start()
|
|
195
|
+
|
|
196
|
+
if not self.headless:
|
|
197
|
+
viewer = mujoco.viewer.launch_passive(
|
|
198
|
+
self.model, self.data, show_left_ui=False, show_right_ui=False
|
|
199
|
+
)
|
|
200
|
+
with viewer.lock():
|
|
201
|
+
viewer.cam.type = mujoco.mjtCamera.mjCAMERA_FREE
|
|
202
|
+
viewer.cam.distance = 0.8 # ≃ ||pos - lookat||
|
|
203
|
+
viewer.cam.azimuth = 160 # degrees
|
|
204
|
+
viewer.cam.elevation = -20 # degrees
|
|
205
|
+
viewer.cam.lookat[:] = [0, 0, 0.15]
|
|
206
|
+
|
|
207
|
+
# force one render with your new camera
|
|
208
|
+
mujoco.mj_step(self.model, self.data)
|
|
209
|
+
viewer.sync()
|
|
210
|
+
|
|
211
|
+
# im = self.get_camera()
|
|
212
|
+
# self.streamer_udp.send_frame(im)
|
|
213
|
+
|
|
214
|
+
self.data.qpos[self.joint_qpos_addr] = np.array(
|
|
215
|
+
self._SLEEP_HEAD_JOINT_POSITIONS + self._SLEEP_ANTENNAS_JOINT_POSITIONS
|
|
216
|
+
).reshape(-1, 1)
|
|
217
|
+
self.data.ctrl[:] = np.array(
|
|
218
|
+
self._SLEEP_HEAD_JOINT_POSITIONS + self._SLEEP_ANTENNAS_JOINT_POSITIONS
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# recompute all kinematics, collisions, etc.
|
|
222
|
+
mujoco.mj_forward(self.model, self.data)
|
|
223
|
+
|
|
224
|
+
for i in range(100):
|
|
225
|
+
mujoco.mj_step(self.model, self.data)
|
|
226
|
+
|
|
227
|
+
# enable collisions
|
|
228
|
+
for i in self.col_inds:
|
|
229
|
+
self.model.geom_contype[i] = 1
|
|
230
|
+
self.model.geom_conaffinity[i] = 1
|
|
231
|
+
|
|
232
|
+
for i in range(100):
|
|
233
|
+
mujoco.mj_step(self.model, self.data)
|
|
234
|
+
|
|
235
|
+
# one more frame so the viewer shows your startup pose
|
|
236
|
+
mujoco.mj_step(self.model, self.data)
|
|
237
|
+
if not self.headless:
|
|
238
|
+
viewer.sync()
|
|
239
|
+
|
|
240
|
+
rendering_thread = Thread(
|
|
241
|
+
target=self.rendering_loop, args=(CAMERA_REACHY, 5005), daemon=True
|
|
242
|
+
)
|
|
243
|
+
rendering_thread.start()
|
|
244
|
+
|
|
245
|
+
# Update the internal states of the IK and FK to the current configuration
|
|
246
|
+
# This is important to avoid jumps when starting the robot (beore wake-up)
|
|
247
|
+
self.head_kinematics.ik(self.get_mj_present_head_pose(), no_iterations=20)
|
|
248
|
+
self.head_kinematics.fk(
|
|
249
|
+
self.get_present_head_joint_positions(), no_iterations=20
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# 3) now enter your normal loop
|
|
253
|
+
while not self.should_stop.is_set():
|
|
254
|
+
start_t = time.time()
|
|
255
|
+
|
|
256
|
+
if step % self.decimation == 0:
|
|
257
|
+
# update the current states
|
|
258
|
+
self.current_head_joint_positions = (
|
|
259
|
+
self.get_present_head_joint_positions()
|
|
260
|
+
)
|
|
261
|
+
self.current_antenna_joint_positions = (
|
|
262
|
+
self.get_present_antenna_joint_positions()
|
|
263
|
+
)
|
|
264
|
+
# Update the Placo kinematics model to recompute passive joints
|
|
265
|
+
self.update_head_kinematics_model(
|
|
266
|
+
self.current_head_joint_positions,
|
|
267
|
+
self.current_antenna_joint_positions,
|
|
268
|
+
)
|
|
269
|
+
self.current_head_pose = self.get_mj_present_head_pose()
|
|
270
|
+
|
|
271
|
+
# Update the target head joint positions from IK if necessary
|
|
272
|
+
# - does nothing if the targets did not change
|
|
273
|
+
if self.ik_required:
|
|
274
|
+
try:
|
|
275
|
+
self.update_target_head_joints_from_ik(
|
|
276
|
+
self.target_head_pose, self.target_body_yaw
|
|
277
|
+
)
|
|
278
|
+
except ValueError as e:
|
|
279
|
+
log_throttling.by_time(self.logger, interval=0.5).warning(
|
|
280
|
+
f"IK error: {e}"
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
if self.target_head_joint_positions is not None:
|
|
284
|
+
self.data.ctrl[:7] = self.target_head_joint_positions
|
|
285
|
+
if self.target_antenna_joint_positions is not None:
|
|
286
|
+
self.data.ctrl[-2:] = -self.target_antenna_joint_positions
|
|
287
|
+
|
|
288
|
+
if (
|
|
289
|
+
self.joint_positions_publisher is not None
|
|
290
|
+
and self.pose_publisher is not None
|
|
291
|
+
):
|
|
292
|
+
if not self.is_shutting_down:
|
|
293
|
+
self.joint_positions_publisher.put(
|
|
294
|
+
json.dumps(
|
|
295
|
+
{
|
|
296
|
+
"head_joint_positions": self.current_head_joint_positions.tolist(),
|
|
297
|
+
"antennas_joint_positions": self.current_antenna_joint_positions.tolist(),
|
|
298
|
+
}
|
|
299
|
+
).encode("utf-8")
|
|
300
|
+
)
|
|
301
|
+
self.pose_publisher.put(
|
|
302
|
+
json.dumps(
|
|
303
|
+
{
|
|
304
|
+
"head_pose": self.get_present_head_pose().tolist(),
|
|
305
|
+
}
|
|
306
|
+
).encode("utf-8")
|
|
307
|
+
)
|
|
308
|
+
self.ready.set()
|
|
309
|
+
|
|
310
|
+
if not self.headless:
|
|
311
|
+
viewer.sync()
|
|
312
|
+
|
|
313
|
+
mujoco.mj_step(self.model, self.data)
|
|
314
|
+
|
|
315
|
+
took = time.time() - start_t
|
|
316
|
+
time.sleep(max(0, self.model.opt.timestep - took))
|
|
317
|
+
# print(f"Step {step}: took {took*1e6:.1f}us")
|
|
318
|
+
step += 1
|
|
319
|
+
|
|
320
|
+
if not self.headless:
|
|
321
|
+
viewer.close()
|
|
322
|
+
rendering_thread.join()
|
|
323
|
+
if self.websocket_uri:
|
|
324
|
+
robot_view_streaming_thread.join()
|
|
325
|
+
|
|
326
|
+
def get_mj_present_head_pose(self) -> Annotated[npt.NDArray[np.float64], (4, 4)]:
|
|
327
|
+
"""Get the current head pose from the Mujoco simulation.
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
np.ndarray: The current head pose as a 4x4 transformation matrix.
|
|
331
|
+
|
|
332
|
+
"""
|
|
333
|
+
mj_current_head_pose = np.eye(4)
|
|
334
|
+
|
|
335
|
+
mj_current_head_pose[:3, :3] = self.data.site_xmat[self.head_site_id].reshape(
|
|
336
|
+
3, 3
|
|
337
|
+
)
|
|
338
|
+
mj_current_head_pose[:3, 3] = self.data.site_xpos[self.head_site_id]
|
|
339
|
+
mj_current_head_pose[2, 3] -= 0.177
|
|
340
|
+
return mj_current_head_pose
|
|
341
|
+
|
|
342
|
+
def close(self) -> None:
|
|
343
|
+
"""Close the Mujoco backend."""
|
|
344
|
+
# TODO Do something in mujoco here ?
|
|
345
|
+
pass
|
|
346
|
+
|
|
347
|
+
def get_status(self) -> "MujocoBackendStatus":
|
|
348
|
+
"""Get the status of the Mujoco backend.
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
dict: An empty dictionary as the Mujoco backend does not have a specific status to report.
|
|
352
|
+
|
|
353
|
+
"""
|
|
354
|
+
return MujocoBackendStatus(motor_control_mode=self.get_motor_control_mode())
|
|
355
|
+
|
|
356
|
+
def get_present_head_joint_positions(
|
|
357
|
+
self,
|
|
358
|
+
) -> Annotated[npt.NDArray[np.float64], (7,)]:
|
|
359
|
+
"""Get the current joint positions of the head."""
|
|
360
|
+
pos: npt.NDArray[np.float64] = self.data.qpos[
|
|
361
|
+
self.joint_qpos_addr[:7]
|
|
362
|
+
].flatten()
|
|
363
|
+
return pos
|
|
364
|
+
|
|
365
|
+
def get_present_antenna_joint_positions(
|
|
366
|
+
self,
|
|
367
|
+
) -> Annotated[npt.NDArray[np.float64], (2,)]:
|
|
368
|
+
"""Get the current joint positions of the antennas."""
|
|
369
|
+
pos: npt.NDArray[np.float64] = self.data.qpos[
|
|
370
|
+
self.joint_qpos_addr[-2:]
|
|
371
|
+
].flatten()
|
|
372
|
+
return -pos
|
|
373
|
+
|
|
374
|
+
def get_motor_control_mode(self) -> MotorControlMode:
|
|
375
|
+
"""Get the motor control mode."""
|
|
376
|
+
return MotorControlMode.Enabled
|
|
377
|
+
|
|
378
|
+
def set_motor_control_mode(self, mode: MotorControlMode) -> None:
|
|
379
|
+
"""Set the motor control mode."""
|
|
380
|
+
pass
|
|
381
|
+
|
|
382
|
+
def set_motor_torque_ids(self, ids: list[str], on: bool) -> None:
|
|
383
|
+
"""Set the motor torque state for specific motor names."""
|
|
384
|
+
pass
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@dataclass
|
|
388
|
+
class MujocoBackendStatus:
|
|
389
|
+
"""Dataclass to represent the status of the Mujoco backend.
|
|
390
|
+
|
|
391
|
+
Empty for now, as the Mujoco backend does not have a specific status to report.
|
|
392
|
+
"""
|
|
393
|
+
|
|
394
|
+
motor_control_mode: MotorControlMode
|
|
395
|
+
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,57 @@
|
|
|
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)
|
|
54
|
+
|
|
55
|
+
def close(self) -> None:
|
|
56
|
+
"""Close the socket."""
|
|
57
|
+
self.sock.close()
|