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,656 @@
|
|
|
1
|
+
"""Placo Kinematics for Reachy Mini.
|
|
2
|
+
|
|
3
|
+
This module provides the PlacoKinematics class for performing inverse and forward kinematics based on the Reachy Mini robot URDF using the Placo library.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Annotated, List, Optional
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import numpy.typing as npt
|
|
11
|
+
import pinocchio as pin
|
|
12
|
+
import placo
|
|
13
|
+
from scipy.spatial.transform import Rotation as R
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PlacoKinematics:
|
|
17
|
+
"""Placo Kinematics class for Reachy Mini.
|
|
18
|
+
|
|
19
|
+
This class provides methods for inverse and forward kinematics using the Placo library and a URDF model of the Reachy Mini robot.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
urdf_path: str,
|
|
25
|
+
dt: float = 0.02,
|
|
26
|
+
automatic_body_yaw: bool = False,
|
|
27
|
+
check_collision: bool = False,
|
|
28
|
+
log_level: str = "INFO",
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Initialize the PlacoKinematics class.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
urdf_path (str): Path to the URDF file of the Reachy Mini robot.
|
|
34
|
+
dt (float): Time step for the kinematics solver. Default is 0.02 seconds.
|
|
35
|
+
automatic_body_yaw (bool): If True, the body yaw will be used to compute the IK and FK. Default is False.
|
|
36
|
+
check_collision (bool): If True, checks for collisions after solving IK. (default: False)
|
|
37
|
+
log_level (str): Logging level for the kinematics computations.
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
self.fk_reached_tol = np.deg2rad(
|
|
41
|
+
0.1
|
|
42
|
+
) # 0.1 degrees tolerance for the FK reached condition
|
|
43
|
+
|
|
44
|
+
if not urdf_path.endswith(".urdf"):
|
|
45
|
+
urdf_path = f"{urdf_path}/{'robot_simple_collision.urdf' if check_collision else 'robot_no_collision.urdf'}"
|
|
46
|
+
|
|
47
|
+
self.robot = placo.RobotWrapper(
|
|
48
|
+
urdf_path, placo.Flags.collision_as_visual + placo.Flags.ignore_collisions
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
flags = (
|
|
52
|
+
0
|
|
53
|
+
if check_collision
|
|
54
|
+
else placo.Flags.ignore_collisions + placo.Flags.collision_as_visual
|
|
55
|
+
)
|
|
56
|
+
self.robot_ik = placo.RobotWrapper(urdf_path, flags)
|
|
57
|
+
|
|
58
|
+
self.ik_solver = placo.KinematicsSolver(self.robot_ik)
|
|
59
|
+
self.ik_solver.mask_fbase(True)
|
|
60
|
+
|
|
61
|
+
self.fk_solver = placo.KinematicsSolver(self.robot)
|
|
62
|
+
self.fk_solver.mask_fbase(True)
|
|
63
|
+
|
|
64
|
+
self.automatic_body_yaw = automatic_body_yaw
|
|
65
|
+
self.check_collision = check_collision
|
|
66
|
+
|
|
67
|
+
self._logger = logging.getLogger(__name__)
|
|
68
|
+
self._logger.setLevel(log_level)
|
|
69
|
+
|
|
70
|
+
# we could go to soft limits to avoid over-constraining the IK
|
|
71
|
+
# but the current implementation works robustly with hard limits
|
|
72
|
+
# so we keep the hard limits for now
|
|
73
|
+
constrant_type = "hard" # "hard" or "soft"
|
|
74
|
+
|
|
75
|
+
# IK closing tasks
|
|
76
|
+
ik_closing_tasks = []
|
|
77
|
+
for i in range(1, 6):
|
|
78
|
+
ik_closing_task = self.ik_solver.add_relative_position_task(
|
|
79
|
+
f"closing_{i}_1", f"closing_{i}_2", np.zeros(3)
|
|
80
|
+
)
|
|
81
|
+
ik_closing_task.configure(f"closing_{i}", constrant_type, 1.0)
|
|
82
|
+
ik_closing_tasks.append(ik_closing_task)
|
|
83
|
+
|
|
84
|
+
# FK closing tasks
|
|
85
|
+
fk_closing_tasks = []
|
|
86
|
+
for i in range(1, 6):
|
|
87
|
+
fk_closing_task = self.fk_solver.add_relative_position_task(
|
|
88
|
+
f"closing_{i}_1", f"closing_{i}_2", np.zeros(3)
|
|
89
|
+
)
|
|
90
|
+
fk_closing_task.configure(f"closing_{i}", constrant_type, 1.0)
|
|
91
|
+
fk_closing_tasks.append(fk_closing_task)
|
|
92
|
+
|
|
93
|
+
# Add the constraint between the rotated torso and the head
|
|
94
|
+
# This will allow independent control of the torso and the head yaw
|
|
95
|
+
# until this constraint is reached
|
|
96
|
+
yaw_constraint = self.ik_solver.add_yaw_constraint(
|
|
97
|
+
"dummy_torso_yaw", "head", np.deg2rad(55.0)
|
|
98
|
+
)
|
|
99
|
+
yaw_constraint.configure("rel_yaw", "hard")
|
|
100
|
+
|
|
101
|
+
# Add the constraint to avoid the head from looking too far behind
|
|
102
|
+
# Mostly due to some numerical problems 180 is always a bit tricky
|
|
103
|
+
# Not really constraining because the this 180 pose is almost not
|
|
104
|
+
# reachable with the real robot anyway
|
|
105
|
+
yaw_constraint_abs = self.ik_solver.add_yaw_constraint(
|
|
106
|
+
"body_foot_3dprint", "head", np.deg2rad(179.0)
|
|
107
|
+
)
|
|
108
|
+
yaw_constraint_abs.configure("abs_yaw", "hard")
|
|
109
|
+
|
|
110
|
+
# Add a cone constraint for the head to not exceed a certain angle
|
|
111
|
+
# This is to avoid the head from looking too far up or down
|
|
112
|
+
self.fk_cone = self.ik_solver.add_cone_constraint(
|
|
113
|
+
"body_foot_3dprint", "head", np.deg2rad(35.0)
|
|
114
|
+
)
|
|
115
|
+
self.fk_cone.configure("cone", "hard")
|
|
116
|
+
self.fk_yaw_constraint = self.fk_solver.add_yaw_constraint(
|
|
117
|
+
"dummy_torso_yaw", "head", np.deg2rad(55.0)
|
|
118
|
+
)
|
|
119
|
+
self.fk_yaw_constraint.configure("rel_yaw", "hard")
|
|
120
|
+
|
|
121
|
+
# Add a cone constraint for the head to not exceed a certain angle
|
|
122
|
+
# This is to avoid the head from looking too far up or down
|
|
123
|
+
fk_cone = self.fk_solver.add_cone_constraint(
|
|
124
|
+
"body_foot_3dprint", "head", np.deg2rad(35.0)
|
|
125
|
+
)
|
|
126
|
+
fk_cone.configure("cone", "hard")
|
|
127
|
+
|
|
128
|
+
# Z offset for the head to make it easier to compute the IK and FK
|
|
129
|
+
# This is the height of the head from the base of the robot
|
|
130
|
+
self.head_z_offset = 0.177 # offset for the head height
|
|
131
|
+
|
|
132
|
+
# IK head task
|
|
133
|
+
self.head_starting_pose = np.eye(4)
|
|
134
|
+
self.head_starting_pose[:3, 3][2] = self.head_z_offset
|
|
135
|
+
self.head_frame = self.ik_solver.add_frame_task("head", self.head_starting_pose)
|
|
136
|
+
# equivalance to ~1cm = 1deg weights
|
|
137
|
+
# set to 5 to be higher than the 1.0 for the body yaw
|
|
138
|
+
self.head_frame.configure(
|
|
139
|
+
"head",
|
|
140
|
+
"soft",
|
|
141
|
+
5.0, # in meters # 1m
|
|
142
|
+
5.0, # in radians # 1rad
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
self.head_frame.T_world_frame = self.head_starting_pose
|
|
146
|
+
|
|
147
|
+
# regularization
|
|
148
|
+
self.ik_yaw_joint_task = self.ik_solver.add_joints_task()
|
|
149
|
+
self.ik_yaw_joint_task.set_joints({"yaw_body": 0})
|
|
150
|
+
if not self.automatic_body_yaw:
|
|
151
|
+
self.ik_yaw_joint_task.configure("joints", "soft", 5e-5)
|
|
152
|
+
else:
|
|
153
|
+
self.ik_yaw_joint_task.configure("joints", "soft", 3.0)
|
|
154
|
+
|
|
155
|
+
# joint limit tasks (values form URDF)
|
|
156
|
+
self.ik_solver.enable_velocity_limits(True)
|
|
157
|
+
self.ik_solver.enable_joint_limits(True)
|
|
158
|
+
self.ik_solver.dt = dt
|
|
159
|
+
|
|
160
|
+
# FK joint task
|
|
161
|
+
self.head_joints_task = self.fk_solver.add_joints_task()
|
|
162
|
+
self.head_joints_task.configure("joints", "soft", 5.0)
|
|
163
|
+
# joint limit tasks (values form URDF)
|
|
164
|
+
self.fk_solver.enable_velocity_limits(True)
|
|
165
|
+
self.fk_solver.enable_joint_limits(True)
|
|
166
|
+
self.fk_solver.dt = dt
|
|
167
|
+
|
|
168
|
+
# Actuated DoFs
|
|
169
|
+
self.joints_names = [
|
|
170
|
+
"yaw_body",
|
|
171
|
+
"stewart_1",
|
|
172
|
+
"stewart_2",
|
|
173
|
+
"stewart_3",
|
|
174
|
+
"stewart_4",
|
|
175
|
+
"stewart_5",
|
|
176
|
+
"stewart_6",
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
# Passive DoFs to eliminate with constraint jacobian
|
|
180
|
+
self.passive_joints_names = [
|
|
181
|
+
"passive_1_x",
|
|
182
|
+
"passive_1_y",
|
|
183
|
+
"passive_2_x",
|
|
184
|
+
"passive_2_y",
|
|
185
|
+
"passive_3_x",
|
|
186
|
+
"passive_3_y",
|
|
187
|
+
"passive_4_x",
|
|
188
|
+
"passive_4_y",
|
|
189
|
+
"passive_5_x",
|
|
190
|
+
"passive_5_y",
|
|
191
|
+
"passive_6_x",
|
|
192
|
+
"passive_6_y",
|
|
193
|
+
"passive_7_x",
|
|
194
|
+
"passive_7_y",
|
|
195
|
+
"passive_7_z",
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
# Retrieving indexes in the jacobian
|
|
199
|
+
self.passives_idx = [
|
|
200
|
+
self.robot.get_joint_v_offset(dof) for dof in self.passive_joints_names
|
|
201
|
+
]
|
|
202
|
+
self.actives_idx = [
|
|
203
|
+
self.robot.get_joint_v_offset(dof)
|
|
204
|
+
for dof in self.robot.joint_names()
|
|
205
|
+
if dof not in self.passive_joints_names
|
|
206
|
+
]
|
|
207
|
+
self.actuated_idx = [
|
|
208
|
+
self.robot.get_joint_v_offset(dof)
|
|
209
|
+
for dof in self.robot.joint_names()
|
|
210
|
+
if dof in self.joints_names
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
# actuated dof indexes in active dofs
|
|
214
|
+
self.actuated_idx_in_active = [
|
|
215
|
+
i for i, idx in enumerate(self.actives_idx) if idx in self.actuated_idx
|
|
216
|
+
]
|
|
217
|
+
|
|
218
|
+
# set velocity limits to be artificially high
|
|
219
|
+
# to enable faster convergence of the IK/FK solver
|
|
220
|
+
max_vel = 13.0 # rad/s
|
|
221
|
+
for joint_name in self.joints_names:
|
|
222
|
+
if joint_name != "yaw_body":
|
|
223
|
+
self.robot.set_velocity_limit(joint_name, max_vel)
|
|
224
|
+
self.robot_ik.set_velocity_limit(joint_name, max_vel)
|
|
225
|
+
|
|
226
|
+
self.robot.set_joint_limits("yaw_body", -2.8, 2.8)
|
|
227
|
+
self.robot_ik.set_joint_limits("yaw_body", -2.8, 2.8)
|
|
228
|
+
|
|
229
|
+
# initial state
|
|
230
|
+
self._inital_q = self.robot.state.q.copy()
|
|
231
|
+
self._inital_qd = np.zeros_like(self.robot.state.qd)
|
|
232
|
+
self._inital_qdd = np.zeros_like(self.robot.state.qdd)
|
|
233
|
+
|
|
234
|
+
# initial FK to set the head pose
|
|
235
|
+
for _ in range(10):
|
|
236
|
+
self.ik_solver.solve(True) # False to not update the kinematics
|
|
237
|
+
self.robot_ik.update_kinematics()
|
|
238
|
+
|
|
239
|
+
# last good q to revert to in case of collision
|
|
240
|
+
self._inital_q = self.robot_ik.state.q.copy()
|
|
241
|
+
self._last_good_q = self.robot_ik.state.q.copy()
|
|
242
|
+
|
|
243
|
+
# update the robot state to the initial state
|
|
244
|
+
self._update_state_to_initial(self.robot) # revert to the inital state
|
|
245
|
+
self.robot.update_kinematics()
|
|
246
|
+
|
|
247
|
+
if self.check_collision:
|
|
248
|
+
ik_col = self.ik_solver.add_avoid_self_collisions_constraint()
|
|
249
|
+
ik_col.self_collisions_margin = 0.001 # 1mm
|
|
250
|
+
ik_col.self_collisions_trigger = 0.002 # 2mm
|
|
251
|
+
ik_col.configure("avoid_self_collisions", "hard")
|
|
252
|
+
|
|
253
|
+
# setup the collision model
|
|
254
|
+
self.config_collision_model()
|
|
255
|
+
|
|
256
|
+
def _update_state_to_initial(self, robot: placo.RobotWrapper) -> None:
|
|
257
|
+
"""Update the robot state to the initial state.
|
|
258
|
+
|
|
259
|
+
It does not call update_kinematics, so the robot state is not updated.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
robot (placo.RobotWrapper): The robot wrapper instance to update.
|
|
263
|
+
|
|
264
|
+
"""
|
|
265
|
+
robot.state.q = self._inital_q
|
|
266
|
+
robot.state.qd = self._inital_qd
|
|
267
|
+
robot.state.qdd = self._inital_qdd
|
|
268
|
+
|
|
269
|
+
def _pose_distance(
|
|
270
|
+
self, pose1: npt.NDArray[np.float64], pose2: npt.NDArray[np.float64]
|
|
271
|
+
) -> tuple[float, float]:
|
|
272
|
+
"""Compute the orientation distance between two poses.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
pose1 (np.ndarray): The first pose (4x4 homogeneous transformation matrix).
|
|
276
|
+
pose2 (np.ndarray): The second pose (4x4 homogeneous transformation matrix).
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
float: The Euler distance between the two poses.
|
|
280
|
+
|
|
281
|
+
"""
|
|
282
|
+
euler1 = R.from_matrix(pose1[:3, :3]).as_euler("xyz")
|
|
283
|
+
euler2 = R.from_matrix(pose2[:3, :3]).as_euler("xyz")
|
|
284
|
+
p1 = pose1[:3, 3]
|
|
285
|
+
p2 = pose2[:3, 3]
|
|
286
|
+
return float(np.linalg.norm(euler1 - euler2)), float(np.linalg.norm(p1 - p2))
|
|
287
|
+
|
|
288
|
+
def _closed_loop_constraints_valid(
|
|
289
|
+
self, robot: placo.RobotWrapper, tol: float = 1e-2
|
|
290
|
+
) -> bool:
|
|
291
|
+
"""Check if all closed-loop constraints are satisfied.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
robot (placo.RobotWrapper): The robot wrapper instance to check.
|
|
295
|
+
tol (float): The tolerance for checking constraints (default: 1e-2).
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
bool: True if all constraints are satisfied, False otherwise.
|
|
299
|
+
|
|
300
|
+
"""
|
|
301
|
+
for i in range(1, 6):
|
|
302
|
+
pos1 = robot.get_T_world_frame(f"closing_{i}_1")[:3, 3]
|
|
303
|
+
pos2 = robot.get_T_world_frame(f"closing_{i}_2")[:3, 3]
|
|
304
|
+
if not np.allclose(pos1, pos2, atol=tol):
|
|
305
|
+
return False
|
|
306
|
+
return True
|
|
307
|
+
|
|
308
|
+
def _get_joint_values(self, robot: placo.RobotWrapper) -> List[float]:
|
|
309
|
+
"""Get the joint values from the robot state.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
robot (placo.RobotWrapper): The robot wrapper instance to get joint values from.
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
List[float]: A list of joint values.
|
|
316
|
+
|
|
317
|
+
"""
|
|
318
|
+
joints = []
|
|
319
|
+
for joint_name in self.joints_names:
|
|
320
|
+
joint = robot.get_joint(joint_name)
|
|
321
|
+
joints.append(joint)
|
|
322
|
+
return joints
|
|
323
|
+
|
|
324
|
+
def ik(
|
|
325
|
+
self,
|
|
326
|
+
pose: npt.NDArray[np.float64],
|
|
327
|
+
body_yaw: float = 0.0,
|
|
328
|
+
no_iterations: int = 2,
|
|
329
|
+
) -> Annotated[npt.NDArray[np.float64], (7,)] | None:
|
|
330
|
+
"""Compute the inverse kinematics for the head for a given pose.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
pose (np.ndarray): A 4x4 homogeneous transformation matrix
|
|
334
|
+
representing the desired position and orientation of the head.
|
|
335
|
+
body_yaw (float): Body yaw angle in radians.
|
|
336
|
+
no_iterations (int): Number of iterations to perform (default: 2). The higher the value, the more accurate the solution.
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
List[float]: A list of joint angles for the head.
|
|
340
|
+
|
|
341
|
+
"""
|
|
342
|
+
_pose = pose.copy()
|
|
343
|
+
# set the head pose
|
|
344
|
+
_pose[:3, 3][2] += self.head_z_offset # offset the height of the head
|
|
345
|
+
self.head_frame.T_world_frame = _pose
|
|
346
|
+
# update the body_yaw task
|
|
347
|
+
self.ik_yaw_joint_task.set_joints({"yaw_body": body_yaw})
|
|
348
|
+
|
|
349
|
+
# check the starting configuration
|
|
350
|
+
# if the poses are too far start from the initial configuration
|
|
351
|
+
_dist_o, _dist_p = self._pose_distance(
|
|
352
|
+
_pose, self.robot_ik.get_T_world_frame("head")
|
|
353
|
+
)
|
|
354
|
+
# if distance too small 0.1mm and 0.1 deg and the QP has converged (almost 0 velocity)
|
|
355
|
+
_dist_by = np.abs(body_yaw - self.robot_ik.get_joint("yaw_body"))
|
|
356
|
+
if (
|
|
357
|
+
_dist_p < 0.1e-4
|
|
358
|
+
and _dist_o < np.deg2rad(0.01)
|
|
359
|
+
and _dist_by < np.deg2rad(0.01)
|
|
360
|
+
and np.linalg.norm(self.robot_ik.state.qd) < 1e-4
|
|
361
|
+
):
|
|
362
|
+
# no need to recalculate - return the current joint values
|
|
363
|
+
return np.array(
|
|
364
|
+
self._get_joint_values(self.robot_ik)
|
|
365
|
+
) # no need to solve IK
|
|
366
|
+
if _dist_o >= np.pi:
|
|
367
|
+
# distance too big between the current and the target pose
|
|
368
|
+
# start the optim from zero position
|
|
369
|
+
#
|
|
370
|
+
# TO INVESTIGATE: Another way to do this would be not to start from 0 but
|
|
371
|
+
# to set the target pose not to the actual target but to some intermediate pose
|
|
372
|
+
self._update_state_to_initial(self.robot_ik)
|
|
373
|
+
self.robot_ik.update_kinematics()
|
|
374
|
+
self._logger.debug("IK: Poses too far, starting from initial configuration")
|
|
375
|
+
|
|
376
|
+
done = True
|
|
377
|
+
# do the inital ik
|
|
378
|
+
for i in range(no_iterations):
|
|
379
|
+
try:
|
|
380
|
+
self.ik_solver.solve(True) # False to not update the kinematics
|
|
381
|
+
except Exception as e:
|
|
382
|
+
self._logger.debug(f"IK solver failed: {e}, retrying...")
|
|
383
|
+
done = False
|
|
384
|
+
break
|
|
385
|
+
self.robot_ik.update_kinematics()
|
|
386
|
+
|
|
387
|
+
# if no problem in solving the IK check for constraint violation
|
|
388
|
+
if done and (not self._closed_loop_constraints_valid(self.robot_ik)):
|
|
389
|
+
self._logger.debug(
|
|
390
|
+
"IK: Not all equality constraints are satisfied in IK, retrying..."
|
|
391
|
+
)
|
|
392
|
+
done = False
|
|
393
|
+
|
|
394
|
+
# if there was an issue start from scratch
|
|
395
|
+
if not done:
|
|
396
|
+
# set the initial pose
|
|
397
|
+
self._update_state_to_initial(self.robot_ik)
|
|
398
|
+
self.robot_ik.update_kinematics()
|
|
399
|
+
|
|
400
|
+
no_iterations += 2 # add a few more iterations
|
|
401
|
+
# do the inital ik with 10 iterations
|
|
402
|
+
for i in range(no_iterations):
|
|
403
|
+
try:
|
|
404
|
+
self.ik_solver.solve(True) # False to not update the kinematics
|
|
405
|
+
except Exception as e:
|
|
406
|
+
self._logger.warning(f"IK solver failed: {e}, no solution found!")
|
|
407
|
+
return None
|
|
408
|
+
self.robot_ik.update_kinematics()
|
|
409
|
+
|
|
410
|
+
# Get the joint angles
|
|
411
|
+
return np.array(self._get_joint_values(self.robot_ik))
|
|
412
|
+
|
|
413
|
+
def fk(
|
|
414
|
+
self,
|
|
415
|
+
joints_angles: Annotated[npt.NDArray[np.float64], (7,)],
|
|
416
|
+
no_iterations: int = 2,
|
|
417
|
+
) -> Optional[npt.NDArray[np.float64]]:
|
|
418
|
+
"""Compute the forward kinematics for the head given joint angles.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
joints_angles (List[float]): A list of joint angles for the head.
|
|
422
|
+
no_iterations (int): The number of iterations to use for the FK solver. (default: 2), the higher the more accurate the result.
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
np.ndarray: A 4x4 homogeneous transformation matrix
|
|
426
|
+
|
|
427
|
+
"""
|
|
428
|
+
# check if we're already there
|
|
429
|
+
_current_joints = self._get_joint_values(self.robot)
|
|
430
|
+
# if the joint angles are the same (tol 1e-4) and teh QP has converged (max speed is 1e-4rad/s)
|
|
431
|
+
# no need to compute the FK
|
|
432
|
+
if (
|
|
433
|
+
np.linalg.norm(np.array(_current_joints) - np.array(joints_angles))
|
|
434
|
+
< self.fk_reached_tol
|
|
435
|
+
and self.robot.state.qd.max() < 1e-4
|
|
436
|
+
):
|
|
437
|
+
# no need to compute FK
|
|
438
|
+
T_world_head: npt.NDArray[np.float64] = self.robot.get_T_world_frame("head")
|
|
439
|
+
T_world_head[:3, 3][2] -= (
|
|
440
|
+
self.head_z_offset
|
|
441
|
+
) # offset the height of the head
|
|
442
|
+
return T_world_head
|
|
443
|
+
|
|
444
|
+
# update the main task
|
|
445
|
+
self.head_joints_task.set_joints(
|
|
446
|
+
{
|
|
447
|
+
"yaw_body": joints_angles[0],
|
|
448
|
+
"stewart_1": joints_angles[1],
|
|
449
|
+
"stewart_2": joints_angles[2],
|
|
450
|
+
"stewart_3": joints_angles[3],
|
|
451
|
+
"stewart_4": joints_angles[4],
|
|
452
|
+
"stewart_5": joints_angles[5],
|
|
453
|
+
"stewart_6": joints_angles[6],
|
|
454
|
+
}
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
done = True
|
|
458
|
+
# do the inital ik with 2 iterations
|
|
459
|
+
for i in range(no_iterations):
|
|
460
|
+
try:
|
|
461
|
+
self.fk_solver.solve(True) # False to not update the kinematics
|
|
462
|
+
except Exception as e:
|
|
463
|
+
self._logger.debug(f"FK solver failed: {e}, retrying...")
|
|
464
|
+
done = False
|
|
465
|
+
break
|
|
466
|
+
self.robot.update_kinematics()
|
|
467
|
+
|
|
468
|
+
if done and (not self._closed_loop_constraints_valid(self.robot)):
|
|
469
|
+
self._logger.debug(
|
|
470
|
+
"FK: Not all equality constraints are satisfied in FK, retrying..."
|
|
471
|
+
)
|
|
472
|
+
done = False
|
|
473
|
+
|
|
474
|
+
if not done:
|
|
475
|
+
self._update_state_to_initial(self.robot) # revert to the previous state
|
|
476
|
+
self.robot.update_kinematics()
|
|
477
|
+
|
|
478
|
+
no_iterations += 2 # add a few more iterations
|
|
479
|
+
# do the inital ik with 10 iterations
|
|
480
|
+
for i in range(no_iterations):
|
|
481
|
+
try:
|
|
482
|
+
self.fk_solver.solve(True) # False to not update the kinematics
|
|
483
|
+
except Exception as e:
|
|
484
|
+
self._logger.warning(f"FK solver failed: {e}, no solution found!")
|
|
485
|
+
return None
|
|
486
|
+
self.robot.update_kinematics()
|
|
487
|
+
|
|
488
|
+
# Get the head frame transformation
|
|
489
|
+
T_world_head = self.robot.get_T_world_frame("head")
|
|
490
|
+
T_world_head[:3, 3][2] -= self.head_z_offset # offset the height of the head
|
|
491
|
+
|
|
492
|
+
return T_world_head
|
|
493
|
+
|
|
494
|
+
def config_collision_model(self) -> None:
|
|
495
|
+
"""Configure the collision model for the robot.
|
|
496
|
+
|
|
497
|
+
Add collision pairs between the torso and the head colliders.
|
|
498
|
+
"""
|
|
499
|
+
geom_model = self.robot_ik.collision_model
|
|
500
|
+
|
|
501
|
+
id_torso_colliders = list(range(len(geom_model.geometryObjects) - 1))
|
|
502
|
+
id_head_collider = len(geom_model.geometryObjects) - 1
|
|
503
|
+
|
|
504
|
+
for i in id_torso_colliders:
|
|
505
|
+
geom_model.addCollisionPair(
|
|
506
|
+
pin.CollisionPair(id_head_collider, i)
|
|
507
|
+
) # torso with head colliders
|
|
508
|
+
|
|
509
|
+
def compute_collision(self, margin: float = 0.005) -> bool:
|
|
510
|
+
"""Compute the collision between the robot and the environment.
|
|
511
|
+
|
|
512
|
+
Args:
|
|
513
|
+
margin (float): The margin to consider for collision detection (default: 5mm).
|
|
514
|
+
|
|
515
|
+
Returns:
|
|
516
|
+
True if there is a collision, False otherwise.
|
|
517
|
+
|
|
518
|
+
"""
|
|
519
|
+
collision_data = self.robot_ik.collision_model.createData()
|
|
520
|
+
data = self.robot_ik.model.createData()
|
|
521
|
+
|
|
522
|
+
# pin.computeCollisions(
|
|
523
|
+
pin.computeDistances(
|
|
524
|
+
self.robot_ik.model,
|
|
525
|
+
data,
|
|
526
|
+
self.robot_ik.collision_model,
|
|
527
|
+
collision_data,
|
|
528
|
+
self.robot_ik.state.q,
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
# Iterate over all collision pairs
|
|
532
|
+
for distance_result in collision_data.distanceResults:
|
|
533
|
+
if distance_result.min_distance <= margin:
|
|
534
|
+
return True # Something is too close or colliding!
|
|
535
|
+
|
|
536
|
+
return False # Safe
|
|
537
|
+
|
|
538
|
+
def compute_jacobian(
|
|
539
|
+
self, q: Optional[npt.NDArray[np.float64]] = None
|
|
540
|
+
) -> npt.NDArray[np.float64]:
|
|
541
|
+
"""Compute the Jacobian of the head frame with respect to the actuated DoFs.
|
|
542
|
+
|
|
543
|
+
The jacobian in local world aligned.
|
|
544
|
+
|
|
545
|
+
Args:
|
|
546
|
+
q (np.ndarray, optional): Joint angles of the robot. If None, uses the current state of the robot. (default: None)
|
|
547
|
+
|
|
548
|
+
Returns:
|
|
549
|
+
np.ndarray: The Jacobian matrix.
|
|
550
|
+
|
|
551
|
+
"""
|
|
552
|
+
# If q is provided, use it to compute the forward kinematics
|
|
553
|
+
if q is not None:
|
|
554
|
+
self.fk(q, no_iterations=20)
|
|
555
|
+
|
|
556
|
+
# Computing the platform Jacobian
|
|
557
|
+
# dx = Jp.dq
|
|
558
|
+
Jp: npt.NDArray[np.float64] = self.robot.frame_jacobian(
|
|
559
|
+
"head", "local_world_aligned"
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
# Computing the constraints Jacobian
|
|
563
|
+
# 0 = Jc.dq
|
|
564
|
+
constraints = []
|
|
565
|
+
for i in range(1, 6):
|
|
566
|
+
Jc = self.robot.relative_position_jacobian(
|
|
567
|
+
f"closing_{i}_1", f"closing_{i}_2"
|
|
568
|
+
)
|
|
569
|
+
constraints.append(Jc)
|
|
570
|
+
Jc = np.vstack(constraints)
|
|
571
|
+
|
|
572
|
+
# Splitting jacobians as
|
|
573
|
+
# Jp_a.dq_a + Jp_p.dq_p = dx
|
|
574
|
+
Jp_a = Jp[:, self.actives_idx]
|
|
575
|
+
Jp_p = Jp[:, self.passives_idx]
|
|
576
|
+
# Jc_a.dq_a + Jc_p.dq_p = 0
|
|
577
|
+
Jc_a = Jc[:, self.actives_idx]
|
|
578
|
+
Jc_p = Jc[:, self.passives_idx]
|
|
579
|
+
|
|
580
|
+
# Computing effector jacobian under constraints
|
|
581
|
+
# Because constraint equation
|
|
582
|
+
# Jc_a.dq_a + Jc_p.dq_p = 0
|
|
583
|
+
# can be written as:
|
|
584
|
+
# dq_p = - (Jc_p)^(⁻1) @ Jc_a @ dq_a
|
|
585
|
+
# Then we can substitute dq_p in the first equation and get
|
|
586
|
+
# This new jacobian
|
|
587
|
+
J: npt.NDArray[np.float64] = Jp_a - Jp_p @ np.linalg.inv(Jc_p) @ Jc_a
|
|
588
|
+
|
|
589
|
+
return J[:, self.actuated_idx_in_active]
|
|
590
|
+
|
|
591
|
+
def compute_gravity_torque(
|
|
592
|
+
self, q: Optional[npt.NDArray[np.float64]] = None
|
|
593
|
+
) -> npt.NDArray[np.float64]:
|
|
594
|
+
"""Compute the gravity torque vector for the actuated joints of the robot.
|
|
595
|
+
|
|
596
|
+
This method uses the static gravity compensation torques from the robot's dictionary.
|
|
597
|
+
|
|
598
|
+
Args:
|
|
599
|
+
q (np.ndarray, optional): Joint angles of the robot. If None, uses the current state of the robot. (default: None)
|
|
600
|
+
|
|
601
|
+
Returns:
|
|
602
|
+
np.ndarray: The gravity torque vector.
|
|
603
|
+
|
|
604
|
+
"""
|
|
605
|
+
# If q is provided, use it to compute the forward kinematics
|
|
606
|
+
if q is not None:
|
|
607
|
+
self.fk(q)
|
|
608
|
+
|
|
609
|
+
# Get the static gravity compensation torques for all joints
|
|
610
|
+
# except the mobile base 6dofs
|
|
611
|
+
grav_torque_all_joints = np.array(
|
|
612
|
+
list(
|
|
613
|
+
self.robot.static_gravity_compensation_torques_dict(
|
|
614
|
+
"body_foot_3dprint"
|
|
615
|
+
).values()
|
|
616
|
+
)
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
# See the paper for more info (equations 4-9):
|
|
620
|
+
# https://hal.science/hal-03379538/file/BriotKhalil_SpringerEncyclRob_bookchapterPKMDyn.pdf#page=4
|
|
621
|
+
#
|
|
622
|
+
# Basically to compute the actuated torques necessary to compensate the gravity, we need to compute the
|
|
623
|
+
# the equivalent wrench in the head frame that would be created if all the joints were actuated.
|
|
624
|
+
# wrench_eq = np.linalg.pinv(J_all_joints.T) @ torque_all_joints
|
|
625
|
+
# And then we can compute the actuated torques as:
|
|
626
|
+
# torque_actuated = J_actuated.T @ wrench_eq
|
|
627
|
+
J_all_joints: npt.NDArray[np.float64] = self.robot.frame_jacobian(
|
|
628
|
+
"head", "local_world_aligned"
|
|
629
|
+
)[:, 6:] # all joints except the mobile base 6dofs
|
|
630
|
+
J_actuated = self.compute_jacobian()
|
|
631
|
+
# using a single matrix G to compute the actuated torques
|
|
632
|
+
G = J_actuated.T @ np.linalg.pinv(J_all_joints.T)
|
|
633
|
+
|
|
634
|
+
# torques of actuated joints
|
|
635
|
+
grav_torque_actuated: npt.NDArray[np.float64] = G @ grav_torque_all_joints
|
|
636
|
+
|
|
637
|
+
# Compute the gravity torque
|
|
638
|
+
return grav_torque_actuated
|
|
639
|
+
|
|
640
|
+
def set_automatic_body_yaw(self, automatic_body_yaw: bool) -> None:
|
|
641
|
+
"""Set the automatic body yaw.
|
|
642
|
+
|
|
643
|
+
Args:
|
|
644
|
+
automatic_body_yaw (bool): Whether to enable automatic body yaw.
|
|
645
|
+
|
|
646
|
+
"""
|
|
647
|
+
self.automatic_body_yaw = automatic_body_yaw
|
|
648
|
+
|
|
649
|
+
if not self.automatic_body_yaw:
|
|
650
|
+
self.ik_yaw_joint_task.configure("joints", "soft", 3.0)
|
|
651
|
+
else:
|
|
652
|
+
self.ik_yaw_joint_task.configure("joints", "soft", 5e-5)
|
|
653
|
+
|
|
654
|
+
def get_joint(self, joint_name: str) -> float:
|
|
655
|
+
"""Get the joint object by its name."""
|
|
656
|
+
return float(self.robot.get_joint(joint_name))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Media module."""
|