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.
Files changed (479) hide show
  1. reachy_mini/__init__.py +4 -0
  2. reachy_mini/apps/__init__.py +25 -0
  3. reachy_mini/apps/app.py +258 -0
  4. reachy_mini/apps/assistant.py +787 -0
  5. reachy_mini/apps/manager.py +312 -0
  6. reachy_mini/apps/sources/__init__.py +4 -0
  7. reachy_mini/apps/sources/hf_space.py +106 -0
  8. reachy_mini/apps/sources/local_common_venv.py +567 -0
  9. reachy_mini/apps/templates/README.md.j2 +12 -0
  10. reachy_mini/apps/templates/gitignore.j2 +3 -0
  11. reachy_mini/apps/templates/index.html.j2 +40 -0
  12. reachy_mini/apps/templates/main.py.j2 +74 -0
  13. reachy_mini/apps/templates/pyproject.toml.j2 +28 -0
  14. reachy_mini/apps/templates/static/index.html.j2 +27 -0
  15. reachy_mini/apps/templates/static/main.js.j2 +47 -0
  16. reachy_mini/apps/templates/static/style.css.j2 +25 -0
  17. reachy_mini/apps/templates/style.css.j2 +411 -0
  18. reachy_mini/apps/utils.py +30 -0
  19. reachy_mini/assets/config/hardware_config.yaml +164 -0
  20. reachy_mini/assets/confused1.wav +0 -0
  21. reachy_mini/assets/count.wav +0 -0
  22. reachy_mini/assets/dance1.wav +0 -0
  23. reachy_mini/assets/firmware/CHANGELOG.md +15 -0
  24. reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.2.bin +0 -0
  25. reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.3.bin +0 -0
  26. reachy_mini/assets/firmware/update.sh +9 -0
  27. reachy_mini/assets/go_sleep.wav +0 -0
  28. reachy_mini/assets/impatient1.wav +0 -0
  29. reachy_mini/assets/kinematics_data.json +253 -0
  30. reachy_mini/assets/models/fknetwork.dynamic.onnx +0 -0
  31. reachy_mini/assets/models/fknetwork.onnx +0 -0
  32. reachy_mini/assets/models/fknetwork_int8.onnx +0 -0
  33. reachy_mini/assets/models/iknetwork.onnx +0 -0
  34. reachy_mini/assets/wake_up.wav +0 -0
  35. reachy_mini/daemon/__init__.py +1 -0
  36. reachy_mini/daemon/app/__init__.py +1 -0
  37. reachy_mini/daemon/app/bg_job_register.py +142 -0
  38. reachy_mini/daemon/app/dashboard/static/assets/KO-cartoon-static.svg +40 -0
  39. reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon-static.svg +42 -0
  40. reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon.svg +6 -0
  41. reachy_mini/daemon/app/dashboard/static/assets/go-to-sleep-cartoon.svg +6 -0
  42. reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon-static.svg +50 -0
  43. reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon.svg +6 -0
  44. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-awake.svg +18 -0
  45. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-connection-lost-animation.svg +6 -0
  46. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-go-to-sleep-animation.svg +6 -0
  47. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko-animation.svg +6 -0
  48. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko.svg +22 -0
  49. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping-static.svg +41 -0
  50. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping.svg +18 -0
  51. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-wake-up-animation.svg +6 -0
  52. reachy_mini/daemon/app/dashboard/static/css/app.css +1433 -0
  53. reachy_mini/daemon/app/dashboard/static/fonts/Archivo-Italic-VariableFont_wdth,wght.ttf +0 -0
  54. reachy_mini/daemon/app/dashboard/static/fonts/Archivo-VariableFont_wdth,wght.ttf +0 -0
  55. reachy_mini/daemon/app/dashboard/static/fonts/Asap-Italic-VariableFont_wdth,wght.ttf +0 -0
  56. reachy_mini/daemon/app/dashboard/static/fonts/Asap-VariableFont_wdth,wght.ttf +0 -0
  57. reachy_mini/daemon/app/dashboard/static/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
  58. reachy_mini/daemon/app/dashboard/static/js/apps.js +323 -0
  59. reachy_mini/daemon/app/dashboard/static/js/appstore.js +167 -0
  60. reachy_mini/daemon/app/dashboard/static/js/daemon.js +169 -0
  61. reachy_mini/daemon/app/dashboard/static/js/health_check.js +9 -0
  62. reachy_mini/daemon/app/dashboard/static/js/move_player.js +132 -0
  63. reachy_mini/daemon/app/dashboard/static/js/notification.js +41 -0
  64. reachy_mini/daemon/app/dashboard/static/js/update.js +132 -0
  65. reachy_mini/daemon/app/dashboard/static/js/volume_control.js +252 -0
  66. reachy_mini/daemon/app/dashboard/static/js/wifi.js +176 -0
  67. reachy_mini/daemon/app/dashboard/tailwindcss/README.md +15 -0
  68. reachy_mini/daemon/app/dashboard/tailwindcss/package-lock.json +1127 -0
  69. reachy_mini/daemon/app/dashboard/tailwindcss/package.json +6 -0
  70. reachy_mini/daemon/app/dashboard/tailwindcss/pnpm-lock.yaml +608 -0
  71. reachy_mini/daemon/app/dashboard/tailwindcss/postcss.config.js +6 -0
  72. reachy_mini/daemon/app/dashboard/tailwindcss/styles/app.css +185 -0
  73. reachy_mini/daemon/app/dashboard/tailwindcss/tailwind.config.js +11 -0
  74. reachy_mini/daemon/app/dashboard/templates/base.html +21 -0
  75. reachy_mini/daemon/app/dashboard/templates/index.html +20 -0
  76. reachy_mini/daemon/app/dashboard/templates/sections/apps.html +8 -0
  77. reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +35 -0
  78. reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +45 -0
  79. reachy_mini/daemon/app/dashboard/templates/sections/move_player.html +121 -0
  80. reachy_mini/daemon/app/dashboard/templates/sections/notification.html +19 -0
  81. reachy_mini/daemon/app/dashboard/templates/sections/update.html +54 -0
  82. reachy_mini/daemon/app/dashboard/templates/sections/wifi.html +46 -0
  83. reachy_mini/daemon/app/dashboard/templates/settings.html +14 -0
  84. reachy_mini/daemon/app/dependencies.py +41 -0
  85. reachy_mini/daemon/app/main.py +469 -0
  86. reachy_mini/daemon/app/models.py +149 -0
  87. reachy_mini/daemon/app/routers/apps.py +114 -0
  88. reachy_mini/daemon/app/routers/daemon.py +85 -0
  89. reachy_mini/daemon/app/routers/kinematics.py +57 -0
  90. reachy_mini/daemon/app/routers/motors.py +41 -0
  91. reachy_mini/daemon/app/routers/move.py +265 -0
  92. reachy_mini/daemon/app/routers/state.py +146 -0
  93. reachy_mini/daemon/app/routers/update.py +86 -0
  94. reachy_mini/daemon/app/routers/volume.py +423 -0
  95. reachy_mini/daemon/app/routers/wifi_config.py +219 -0
  96. reachy_mini/daemon/app/services/__init__.py +1 -0
  97. reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py +796 -0
  98. reachy_mini/daemon/app/services/bluetooth/commands/HOTSPOT.sh +7 -0
  99. reachy_mini/daemon/app/services/bluetooth/commands/RESTART_DAEMON.sh +4 -0
  100. reachy_mini/daemon/app/services/bluetooth/commands/SOFTWARE_RESET.sh +7 -0
  101. reachy_mini/daemon/app/services/bluetooth/install_service_bluetooth.sh +39 -0
  102. reachy_mini/daemon/app/services/gpio_shutdown/__init__.py +1 -0
  103. reachy_mini/daemon/app/services/gpio_shutdown/install_service.sh +33 -0
  104. reachy_mini/daemon/app/services/gpio_shutdown/launcher.sh +3 -0
  105. reachy_mini/daemon/app/services/gpio_shutdown/shutdown_monitor.py +28 -0
  106. reachy_mini/daemon/app/services/wireless/generate_asoundrc.sh +70 -0
  107. reachy_mini/daemon/app/services/wireless/install_service.sh +33 -0
  108. reachy_mini/daemon/app/services/wireless/launcher.sh +5 -0
  109. reachy_mini/daemon/backend/__init__.py +1 -0
  110. reachy_mini/daemon/backend/abstract.py +815 -0
  111. reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
  112. reachy_mini/daemon/backend/mujoco/backend.py +395 -0
  113. reachy_mini/daemon/backend/mujoco/utils.py +59 -0
  114. reachy_mini/daemon/backend/mujoco/video_udp.py +57 -0
  115. reachy_mini/daemon/backend/robot/__init__.py +8 -0
  116. reachy_mini/daemon/backend/robot/backend.py +597 -0
  117. reachy_mini/daemon/daemon.py +651 -0
  118. reachy_mini/daemon/utils.py +116 -0
  119. reachy_mini/descriptions/reachy_mini/mjcf/additional.xml +6 -0
  120. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.part +13 -0
  121. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.stl +0 -0
  122. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.part +13 -0
  123. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.stl +0 -0
  124. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.part +13 -0
  125. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.stl +0 -0
  126. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.part +13 -0
  127. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.stl +0 -0
  128. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.part +13 -0
  129. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.stl +0 -0
  130. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.part +13 -0
  131. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.stl +0 -0
  132. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.part +13 -0
  133. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.stl +0 -0
  134. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.part +13 -0
  135. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.stl +0 -0
  136. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.part +13 -0
  137. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.stl +0 -0
  138. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.part +13 -0
  139. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.stl +0 -0
  140. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.part +13 -0
  141. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.stl +0 -0
  142. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.part +13 -0
  143. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.stl +0 -0
  144. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.part +13 -0
  145. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.stl +0 -0
  146. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.part +13 -0
  147. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.stl +0 -0
  148. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.part +13 -0
  149. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.stl +0 -0
  150. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.part +13 -0
  151. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.stl +0 -0
  152. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/README.m +1 -0
  153. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
  154. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
  155. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
  156. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
  157. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
  158. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
  159. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
  160. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
  161. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
  162. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
  163. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
  164. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
  165. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
  166. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
  167. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
  168. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
  169. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/croissant_1k.obj +5021 -0
  170. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/textures/croissant_diff_1k.png +0 -0
  171. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.part +13 -0
  172. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.stl +0 -0
  173. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.part +13 -0
  174. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.stl +0 -0
  175. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.part +13 -0
  176. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.stl +0 -0
  177. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.part +13 -0
  178. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.stl +0 -0
  179. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  180. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
  181. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/food_apple_01_1k.obj +18045 -0
  182. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/textures/food_apple_01_diff_1k.png +0 -0
  183. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.part +13 -0
  184. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.stl +0 -0
  185. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.part +13 -0
  186. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.stl +0 -0
  187. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.part +13 -0
  188. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.stl +0 -0
  189. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.part +13 -0
  190. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.stl +0 -0
  191. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.part +13 -0
  192. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.stl +0 -0
  193. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.part +13 -0
  194. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.stl +0 -0
  195. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  196. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
  197. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.part +13 -0
  198. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.stl +0 -0
  199. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.part +13 -0
  200. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.stl +0 -0
  201. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.part +13 -0
  202. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.stl +0 -0
  203. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  204. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
  205. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  206. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
  207. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  208. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
  209. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.part +13 -0
  210. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.stl +0 -0
  211. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/rubber_duck_toy_1k.obj +8940 -0
  212. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/textures/rubber_duck_toy_diff_1k.png +0 -0
  213. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.part +13 -0
  214. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.stl +0 -0
  215. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.part +13 -0
  216. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.stl +0 -0
  217. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.part +13 -0
  218. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.stl +0 -0
  219. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.part +13 -0
  220. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.stl +0 -0
  221. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.part +13 -0
  222. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.stl +0 -0
  223. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.part +13 -0
  224. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.stl +0 -0
  225. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/textures/wooden_table_02_diff_1k.png +0 -0
  226. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/wooden_table_02_1k.obj +485 -0
  227. reachy_mini/descriptions/reachy_mini/mjcf/config.json +21 -0
  228. reachy_mini/descriptions/reachy_mini/mjcf/joints_properties.xml +29 -0
  229. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml +642 -0
  230. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml.bak +442 -0
  231. reachy_mini/descriptions/reachy_mini/mjcf/scene.xml +24 -0
  232. reachy_mini/descriptions/reachy_mini/mjcf/scenes/empty.xml +27 -0
  233. reachy_mini/descriptions/reachy_mini/mjcf/scenes/minimal.xml +132 -0
  234. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.part +13 -0
  235. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.stl +0 -0
  236. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.part +13 -0
  237. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.stl +0 -0
  238. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.part +13 -0
  239. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.stl +0 -0
  240. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.part +13 -0
  241. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.stl +0 -0
  242. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.part +13 -0
  243. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.stl +0 -0
  244. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.part +13 -0
  245. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.stl +0 -0
  246. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.part +13 -0
  247. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.stl +0 -0
  248. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.part +13 -0
  249. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.stl +0 -0
  250. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.part +13 -0
  251. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.stl +0 -0
  252. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.part +13 -0
  253. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.stl +0 -0
  254. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.part +13 -0
  255. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.stl +0 -0
  256. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.part +13 -0
  257. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.stl +0 -0
  258. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.part +13 -0
  259. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.stl +0 -0
  260. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.part +13 -0
  261. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.stl +0 -0
  262. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.part +13 -0
  263. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.stl +0 -0
  264. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.part +13 -0
  265. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.stl +0 -0
  266. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.part +13 -0
  267. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.stl +0 -0
  268. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.part +13 -0
  269. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.stl +0 -0
  270. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.part +13 -0
  271. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.stl +0 -0
  272. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.part +13 -0
  273. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.stl +0 -0
  274. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/README.m +1 -0
  275. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
  276. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
  277. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
  278. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
  279. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
  280. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
  281. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
  282. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
  283. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
  284. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
  285. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
  286. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
  287. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
  288. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
  289. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
  290. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
  291. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.part +13 -0
  292. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.stl +0 -0
  293. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.part +13 -0
  294. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.stl +0 -0
  295. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.part +13 -0
  296. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.stl +0 -0
  297. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.part +13 -0
  298. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.stl +0 -0
  299. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  300. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
  301. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.part +14 -0
  302. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.stl +0 -0
  303. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.part +14 -0
  304. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.stl +0 -0
  305. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.part +13 -0
  306. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.stl +0 -0
  307. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.part +13 -0
  308. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.stl +0 -0
  309. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.part +13 -0
  310. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.stl +0 -0
  311. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.part +13 -0
  312. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.stl +0 -0
  313. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.part +13 -0
  314. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.stl +0 -0
  315. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.part +13 -0
  316. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.stl +0 -0
  317. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.part +13 -0
  318. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.stl +0 -0
  319. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.part +13 -0
  320. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.stl +0 -0
  321. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.part +13 -0
  322. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.stl +0 -0
  323. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.part +13 -0
  324. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.stl +0 -0
  325. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.part +13 -0
  326. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.stl +0 -0
  327. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  328. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
  329. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.part +13 -0
  330. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.stl +0 -0
  331. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.part +13 -0
  332. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.stl +0 -0
  333. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.part +13 -0
  334. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.stl +0 -0
  335. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.part +13 -0
  336. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.stl +0 -0
  337. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.part +13 -0
  338. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.stl +0 -0
  339. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.part +13 -0
  340. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.stl +0 -0
  341. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  342. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
  343. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  344. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
  345. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  346. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
  347. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.part +13 -0
  348. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.stl +0 -0
  349. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.part +13 -0
  350. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.stl +0 -0
  351. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.part +13 -0
  352. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.stl +0 -0
  353. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.part +13 -0
  354. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.stl +0 -0
  355. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.part +13 -0
  356. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.stl +0 -0
  357. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.part +13 -0
  358. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.stl +0 -0
  359. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.part +13 -0
  360. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.stl +0 -0
  361. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.part +13 -0
  362. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.stl +0 -0
  363. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.part +13 -0
  364. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.stl +0 -0
  365. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.part +13 -0
  366. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.stl +0 -0
  367. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.part +13 -0
  368. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.stl +0 -0
  369. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.part +13 -0
  370. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.stl +0 -0
  371. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.part +13 -0
  372. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.stl +0 -0
  373. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.part +13 -0
  374. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.stl +0 -0
  375. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.part +13 -0
  376. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.stl +0 -0
  377. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.part +13 -0
  378. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.stl +0 -0
  379. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.part +13 -0
  380. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.stl +0 -0
  381. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.part +13 -0
  382. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.stl +0 -0
  383. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.part +13 -0
  384. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.stl +0 -0
  385. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.part +13 -0
  386. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.stl +0 -0
  387. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.part +13 -0
  388. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.stl +0 -0
  389. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.part +13 -0
  390. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.stl +0 -0
  391. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.part +13 -0
  392. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.stl +0 -0
  393. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.part +13 -0
  394. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.stl +0 -0
  395. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.part +13 -0
  396. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.stl +0 -0
  397. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.part +13 -0
  398. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.stl +0 -0
  399. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.part +13 -0
  400. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.stl +0 -0
  401. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.part +13 -0
  402. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.stl +0 -0
  403. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.part +13 -0
  404. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.stl +0 -0
  405. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.part +13 -0
  406. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.stl +0 -0
  407. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.part +13 -0
  408. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.stl +0 -0
  409. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.part +13 -0
  410. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.stl +0 -0
  411. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.part +14 -0
  412. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.stl +0 -0
  413. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.part +14 -0
  414. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.stl +0 -0
  415. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.part +14 -0
  416. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.stl +0 -0
  417. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.part +14 -0
  418. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.stl +0 -0
  419. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.part +14 -0
  420. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.stl +0 -0
  421. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.part +14 -0
  422. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.stl +0 -0
  423. reachy_mini/descriptions/reachy_mini/urdf/config.json +18 -0
  424. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf +3281 -0
  425. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf.bak +3282 -0
  426. reachy_mini/descriptions/reachy_mini/urdf/robot_no_collision.urdf +2316 -0
  427. reachy_mini/descriptions/reachy_mini/urdf/robot_simple_collision.urdf +2399 -0
  428. reachy_mini/io/__init__.py +15 -0
  429. reachy_mini/io/abstract.py +70 -0
  430. reachy_mini/io/audio_ws.py +242 -0
  431. reachy_mini/io/protocol.py +44 -0
  432. reachy_mini/io/video_ws.py +135 -0
  433. reachy_mini/io/ws_controller.py +120 -0
  434. reachy_mini/io/zenoh_client.py +273 -0
  435. reachy_mini/io/zenoh_server.py +230 -0
  436. reachy_mini/kinematics/__init__.py +68 -0
  437. reachy_mini/kinematics/analytical_kinematics.py +151 -0
  438. reachy_mini/kinematics/nn_kinematics.py +109 -0
  439. reachy_mini/kinematics/placo_kinematics.py +656 -0
  440. reachy_mini/media/__init__.py +1 -0
  441. reachy_mini/media/audio_base.py +111 -0
  442. reachy_mini/media/audio_control_utils.py +455 -0
  443. reachy_mini/media/audio_gstreamer.py +272 -0
  444. reachy_mini/media/audio_sounddevice.py +321 -0
  445. reachy_mini/media/audio_utils.py +114 -0
  446. reachy_mini/media/camera_base.py +100 -0
  447. reachy_mini/media/camera_constants.py +152 -0
  448. reachy_mini/media/camera_gstreamer.py +231 -0
  449. reachy_mini/media/camera_opencv.py +89 -0
  450. reachy_mini/media/camera_utils.py +111 -0
  451. reachy_mini/media/media_manager.py +281 -0
  452. reachy_mini/media/webrtc_client_gstreamer.py +288 -0
  453. reachy_mini/media/webrtc_daemon.py +334 -0
  454. reachy_mini/motion/__init__.py +4 -0
  455. reachy_mini/motion/goto.py +71 -0
  456. reachy_mini/motion/move.py +43 -0
  457. reachy_mini/motion/recorded_move.py +146 -0
  458. reachy_mini/reachy_mini.py +753 -0
  459. reachy_mini/tools/reflash_motors.py +116 -0
  460. reachy_mini/tools/setup_motor.py +422 -0
  461. reachy_mini/tools/setup_motor_rpi.py +108 -0
  462. reachy_mini/utils/__init__.py +46 -0
  463. reachy_mini/utils/constants.py +9 -0
  464. reachy_mini/utils/hardware_config/__init__.py +1 -0
  465. reachy_mini/utils/hardware_config/parser.py +65 -0
  466. reachy_mini/utils/interpolation.py +227 -0
  467. reachy_mini/utils/parse_urdf_for_kinematics.py +110 -0
  468. reachy_mini/utils/rerun.py +320 -0
  469. reachy_mini/utils/wireless_version/__init__.py +1 -0
  470. reachy_mini/utils/wireless_version/startup_check.py +144 -0
  471. reachy_mini/utils/wireless_version/update.py +20 -0
  472. reachy_mini/utils/wireless_version/update_available.py +61 -0
  473. reachy_mini/utils/wireless_version/utils.py +39 -0
  474. reachy_mini-1.2.5rc1.dist-info/METADATA +161 -0
  475. reachy_mini-1.2.5rc1.dist-info/RECORD +479 -0
  476. reachy_mini-1.2.5rc1.dist-info/WHEEL +5 -0
  477. reachy_mini-1.2.5rc1.dist-info/entry_points.txt +4 -0
  478. reachy_mini-1.2.5rc1.dist-info/licenses/LICENSE +201 -0
  479. reachy_mini-1.2.5rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,272 @@
1
+ """GStreamer camera backend.
2
+
3
+ This module provides an implementation of the CameraBase class using GStreamer.
4
+ By default the module directly returns JPEG images as output by the camera.
5
+ """
6
+
7
+ import os
8
+ from threading import Thread
9
+ from typing import Optional
10
+
11
+ import numpy as np
12
+ import numpy.typing as npt
13
+
14
+ from reachy_mini.media.audio_utils import (
15
+ get_respeaker_card_number,
16
+ has_reachymini_asoundrc,
17
+ )
18
+ from reachy_mini.utils.constants import ASSETS_ROOT_PATH
19
+
20
+ try:
21
+ import gi
22
+ except ImportError as e:
23
+ raise ImportError(
24
+ "The 'gi' module is required for GStreamerCamera but could not be imported. \
25
+ Please install the GStreamer backend: pip install .[gstreamer]."
26
+ ) from e
27
+
28
+ gi.require_version("Gst", "1.0")
29
+ gi.require_version("GstApp", "1.0")
30
+
31
+
32
+ from gi.repository import GLib, Gst, GstApp # noqa: E402
33
+
34
+ from .audio_base import AudioBase # noqa: E402
35
+
36
+
37
+ class GStreamerAudio(AudioBase):
38
+ """Audio implementation using GStreamer."""
39
+
40
+ def __init__(self, log_level: str = "INFO") -> None:
41
+ """Initialize the GStreamer audio."""
42
+ super().__init__(log_level=log_level)
43
+ Gst.init(None)
44
+ self._loop = GLib.MainLoop()
45
+ self._thread_bus_calls = Thread(target=lambda: self._loop.run(), daemon=True)
46
+ self._thread_bus_calls.start()
47
+
48
+ self._id_audio_card = get_respeaker_card_number()
49
+
50
+ self._pipeline_record = Gst.Pipeline.new("audio_recorder")
51
+ self._appsink_audio: Optional[GstApp] = None
52
+ self._init_pipeline_record(self._pipeline_record)
53
+ self._bus_record = self._pipeline_record.get_bus()
54
+ self._bus_record.add_watch(
55
+ GLib.PRIORITY_DEFAULT, self._on_bus_message, self._loop
56
+ )
57
+
58
+ self._pipeline_playback = Gst.Pipeline.new("audio_player")
59
+ self._appsrc: Optional[GstApp] = None
60
+ self._init_pipeline_playback(self._pipeline_playback)
61
+ self._bus_playback = self._pipeline_playback.get_bus()
62
+ self._bus_playback.add_watch(
63
+ GLib.PRIORITY_DEFAULT, self._on_bus_message, self._loop
64
+ )
65
+
66
+ def _init_pipeline_record(self, pipeline: Gst.Pipeline) -> None:
67
+ self._appsink_audio = Gst.ElementFactory.make("appsink")
68
+ caps = Gst.Caps.from_string(
69
+ f"audio/x-raw,rate={self.SAMPLE_RATE},channels={self.CHANNELS},format=F32LE,layout=interleaved"
70
+ )
71
+ self._appsink_audio.set_property("caps", caps)
72
+ self._appsink_audio.set_property("drop", True) # avoid overflow
73
+ self._appsink_audio.set_property("max-buffers", 200)
74
+
75
+ audiosrc: Optional[Gst.Element] = None
76
+ if self._id_audio_card == -1:
77
+ audiosrc = Gst.ElementFactory.make("autoaudiosrc") # use default mic
78
+ elif has_reachymini_asoundrc():
79
+ # reachy mini wireless has a preconfigured asoundrc
80
+ audiosrc = Gst.ElementFactory.make("alsasrc")
81
+ audiosrc.set_property("device", "reachymini_audio_src")
82
+ else:
83
+ audiosrc = Gst.ElementFactory.make("alsasrc")
84
+ audiosrc.set_property("device", f"hw:{self._id_audio_card},0")
85
+
86
+ queue = Gst.ElementFactory.make("queue")
87
+ audioconvert = Gst.ElementFactory.make("audioconvert")
88
+ audioresample = Gst.ElementFactory.make("audioresample")
89
+
90
+ if not all([audiosrc, queue, audioconvert, audioresample, self._appsink_audio]):
91
+ raise RuntimeError("Failed to create GStreamer elements")
92
+
93
+ pipeline.add(audiosrc)
94
+ pipeline.add(queue)
95
+ pipeline.add(audioconvert)
96
+ pipeline.add(audioresample)
97
+ pipeline.add(self._appsink_audio)
98
+
99
+ audiosrc.link(queue)
100
+ queue.link(audioconvert)
101
+ audioconvert.link(audioresample)
102
+ audioresample.link(self._appsink_audio)
103
+
104
+ def __del__(self) -> None:
105
+ """Destructor to ensure gstreamer resources are released."""
106
+ super().__del__()
107
+ self._loop.quit()
108
+ self._bus_record.remove_watch()
109
+ self._bus_playback.remove_watch()
110
+
111
+ def _init_pipeline_playback(self, pipeline: Gst.Pipeline) -> None:
112
+ self._appsrc = Gst.ElementFactory.make("appsrc")
113
+ self._appsrc.set_property("format", Gst.Format.TIME)
114
+ self._appsrc.set_property("is-live", True)
115
+ caps = Gst.Caps.from_string(
116
+ f"audio/x-raw,format=F32LE,channels={self.CHANNELS},rate={self.SAMPLE_RATE},layout=interleaved"
117
+ )
118
+ self._appsrc.set_property("caps", caps)
119
+
120
+ audioconvert = Gst.ElementFactory.make("audioconvert")
121
+ audioresample = Gst.ElementFactory.make("audioresample")
122
+
123
+ queue = Gst.ElementFactory.make("queue")
124
+ audiosink: Optional[Gst.Element] = None
125
+ if self._id_audio_card == -1:
126
+ audiosink = Gst.ElementFactory.make("autoaudiosink") # use default speaker
127
+ elif has_reachymini_asoundrc():
128
+ # reachy mini wireless has a preconfigured asoundrc
129
+ audiosink = Gst.ElementFactory.make("alsasink")
130
+ audiosink.set_property("device", "reachymini_audio_sink")
131
+ else:
132
+ audiosink = Gst.ElementFactory.make("alsasink")
133
+ audiosink.set_property("device", f"hw:{self._id_audio_card},0")
134
+
135
+ pipeline.add(queue)
136
+ pipeline.add(audiosink)
137
+ pipeline.add(self._appsrc)
138
+ pipeline.add(audioconvert)
139
+ pipeline.add(audioresample)
140
+
141
+ self._appsrc.link(queue)
142
+ queue.link(audioconvert)
143
+ audioconvert.link(audioresample)
144
+ audioresample.link(audiosink)
145
+
146
+ def _on_bus_message(self, bus: Gst.Bus, msg: Gst.Message, loop) -> bool: # type: ignore[no-untyped-def]
147
+ t = msg.type
148
+ if t == Gst.MessageType.EOS:
149
+ self.logger.warning("End-of-stream")
150
+ return False
151
+
152
+ elif t == Gst.MessageType.ERROR:
153
+ err, debug = msg.parse_error()
154
+ self.logger.error(f"Error: {err} {debug}")
155
+ return False
156
+
157
+ return True
158
+
159
+ def start_recording(self) -> None:
160
+ """Open the audio card using GStreamer."""
161
+ self._pipeline_record.set_state(Gst.State.PLAYING)
162
+
163
+ def _get_sample(self, appsink: GstApp.AppSink) -> Optional[bytes]:
164
+ sample = appsink.try_pull_sample(20_000_000)
165
+ if sample is None:
166
+ return None
167
+ data = None
168
+ if isinstance(sample, Gst.Sample):
169
+ buf = sample.get_buffer()
170
+ if buf is None:
171
+ self.logger.warning("Buffer is None")
172
+
173
+ data = buf.extract_dup(0, buf.get_size())
174
+ return data
175
+
176
+ def get_audio_sample(self) -> Optional[npt.NDArray[np.float32]]:
177
+ """Read a sample from the audio card. Returns the sample or None if error.
178
+
179
+ Returns:
180
+ Optional[npt.NDArray[np.float32]]: The captured sample in raw format, or None if error.
181
+
182
+ """
183
+ sample = self._get_sample(self._appsink_audio)
184
+ if sample is None:
185
+ return None
186
+ return np.frombuffer(sample, dtype=np.float32).reshape(-1, 2)
187
+
188
+ def get_input_audio_samplerate(self) -> int:
189
+ """Get the input samplerate of the audio device."""
190
+ return self.SAMPLE_RATE
191
+
192
+ def get_output_audio_samplerate(self) -> int:
193
+ """Get the output samplerate of the audio device."""
194
+ return self.SAMPLE_RATE
195
+
196
+ def get_input_channels(self) -> int:
197
+ """Get the number of input channels of the audio device."""
198
+ return self.CHANNELS
199
+
200
+ def get_output_channels(self) -> int:
201
+ """Get the number of output channels of the audio device."""
202
+ return self.CHANNELS
203
+
204
+ def stop_recording(self) -> None:
205
+ """Release the camera resource."""
206
+ self._pipeline_record.set_state(Gst.State.NULL)
207
+
208
+ def start_playing(self) -> None:
209
+ """Open the audio output using GStreamer."""
210
+ self._pipeline_playback.set_state(Gst.State.PLAYING)
211
+
212
+ def stop_playing(self) -> None:
213
+ """Stop playing audio and release resources."""
214
+ self._pipeline_playback.set_state(Gst.State.NULL)
215
+
216
+ def push_audio_sample(self, data: npt.NDArray[np.float32]) -> None:
217
+ """Push audio data to the output device."""
218
+ if self._appsrc is not None:
219
+ buf = Gst.Buffer.new_wrapped(data.tobytes())
220
+ self._appsrc.push_buffer(buf)
221
+ else:
222
+ self.logger.warning(
223
+ "AppSrc is not initialized. Call start_playing() first."
224
+ )
225
+
226
+ def play_sound(self, sound_file: str) -> None:
227
+ """Play a sound file.
228
+
229
+ Todo: for now this function is mean to be used on the wireless version.
230
+
231
+ Args:
232
+ sound_file (str): Path to the sound file to play.
233
+
234
+ """
235
+ if not os.path.exists(sound_file):
236
+ file_path = f"{ASSETS_ROOT_PATH}/{sound_file}"
237
+ if not os.path.exists(file_path):
238
+ raise FileNotFoundError(
239
+ f"Sound file {sound_file} not found in assets directory or given path."
240
+ )
241
+ else:
242
+ file_path = sound_file
243
+
244
+ audiosink: Optional[Gst.Element] = None
245
+
246
+ if has_reachymini_asoundrc():
247
+ # reachy mini wireless has a preconfigured asoundrc
248
+ audiosink = Gst.ElementFactory.make("alsasink")
249
+ audiosink.set_property("device", "reachymini_audio_sink")
250
+
251
+ playbin = Gst.ElementFactory.make("playbin", "player")
252
+ if not playbin:
253
+ self.logger.error("Failed to create playbin element")
254
+ return
255
+ playbin.set_property("uri", f"file://{file_path}")
256
+ if audiosink is not None:
257
+ playbin.set_property("audio-sink", audiosink)
258
+
259
+ playbin.set_state(Gst.State.PLAYING)
260
+
261
+ def clear_player(self) -> None:
262
+ """Flush the player's appsrc to drop any queued audio immediately."""
263
+ if self._appsrc is not None:
264
+ self._pipeline_playback.set_state(Gst.State.PAUSED)
265
+ self._appsrc.send_event(Gst.Event.new_flush_start())
266
+ self._appsrc.send_event(Gst.Event.new_flush_stop(reset_time=True))
267
+ self._pipeline_playback.set_state(Gst.State.PLAYING)
268
+ self.logger.info("Cleared player queue")
269
+ else:
270
+ self.logger.warning(
271
+ "AppSrc is not initialized. Call start_playing() first."
272
+ )
@@ -0,0 +1,321 @@
1
+ """Audio implementation using sounddevice backend."""
2
+
3
+ import os
4
+ import threading
5
+ from collections import deque
6
+ from typing import Deque, List, Optional
7
+
8
+ import numpy as np
9
+ import numpy.typing as npt
10
+ import scipy
11
+ import sounddevice as sd
12
+ import soundfile as sf
13
+
14
+ from reachy_mini.utils.constants import ASSETS_ROOT_PATH
15
+
16
+ from .audio_base import AudioBase
17
+
18
+ MAX_INPUT_CHANNELS = 4
19
+ MAX_INPUT_QUEUE_SECONDS = 60.0
20
+
21
+
22
+ class SoundDeviceAudio(AudioBase):
23
+ """Audio device implementation using sounddevice."""
24
+
25
+ def __init__(
26
+ self,
27
+ log_level: str = "INFO",
28
+ ) -> None:
29
+ """Initialize the SoundDevice audio device."""
30
+ super().__init__(log_level=log_level)
31
+ self._input_stream = None
32
+ self._output_stream = None
33
+ self._input_lock = threading.Lock()
34
+ self._output_lock = threading.Lock()
35
+ self._input_buffer: Deque[npt.NDArray[np.float32]] = deque()
36
+ self._output_buffer: List[npt.NDArray[np.float32]] = []
37
+ self._input_max_queue_seconds: float = MAX_INPUT_QUEUE_SECONDS
38
+ self._input_queued_samples: int = 0
39
+
40
+ self._output_device_id = self._get_device_id(
41
+ ["Reachy Mini Audio", "respeaker"], device_io_type="output"
42
+ )
43
+ self._input_device_id = self._get_device_id(
44
+ ["Reachy Mini Audio", "respeaker"], device_io_type="input"
45
+ )
46
+
47
+ self._logs = {
48
+ "input_underflows": 0,
49
+ "input_overflows": 0,
50
+ }
51
+
52
+ @property
53
+ def _input_max_queue_samples(self) -> int:
54
+ return int(self._input_max_queue_seconds * self.get_input_audio_samplerate())
55
+
56
+ @property
57
+ def _is_recording(self) -> bool:
58
+ return self._input_stream is not None and self._input_stream.active
59
+
60
+ def start_recording(self) -> None:
61
+ """Open the audio input stream, using ReSpeaker card if available."""
62
+ if self._is_recording:
63
+ self.stop_recording()
64
+
65
+ self._input_stream = sd.InputStream(
66
+ device=self._input_device_id,
67
+ samplerate=self.get_input_audio_samplerate(),
68
+ callback=self._input_callback,
69
+ )
70
+ if self._input_stream is None:
71
+ raise RuntimeError("Failed to open SoundDevice audio input stream.")
72
+
73
+ self._input_buffer.clear()
74
+ self._input_queued_samples = 0
75
+ self._input_stream.start()
76
+ self.logger.info("SoundDevice audio input stream opened.")
77
+
78
+ def _input_callback(
79
+ self,
80
+ indata: npt.NDArray[np.float32],
81
+ frames: int,
82
+ time: int,
83
+ status: sd.CallbackFlags,
84
+ ) -> None:
85
+ if status and status.input_underflow:
86
+ self._logs["input_underflows"] += 1
87
+ if self._logs["input_underflows"] % 10 == 1:
88
+ self.logger.debug(
89
+ f"Audio input underflow count: {self._logs['input_underflows']}"
90
+ )
91
+
92
+ with self._input_lock:
93
+ if (
94
+ self._input_queued_samples + indata.shape[0]
95
+ > self._input_max_queue_samples
96
+ ):
97
+ while (
98
+ self._input_queued_samples + indata.shape[0]
99
+ > self._input_max_queue_samples
100
+ and len(self._input_buffer) > 0
101
+ ):
102
+ dropped = self._input_buffer.popleft()
103
+ self._input_queued_samples -= dropped.shape[0]
104
+ self._logs["input_overflows"] += 1
105
+ self.logger.warning(
106
+ "Audio input buffer overflowed, dropped old chunks !"
107
+ )
108
+ self._input_buffer.append(indata[:, :MAX_INPUT_CHANNELS].copy())
109
+ self._input_queued_samples += indata.shape[0]
110
+
111
+ def get_audio_sample(self) -> Optional[npt.NDArray[np.float32]]:
112
+ """Read audio data from the buffer. Returns numpy array or None if empty."""
113
+ with self._input_lock:
114
+ if self._input_buffer and len(self._input_buffer) > 0:
115
+ data: npt.NDArray[np.float32] = np.concatenate(
116
+ self._input_buffer, axis=0
117
+ )
118
+ self._input_buffer.clear()
119
+ self._input_queued_samples = 0
120
+ return data
121
+ self.logger.debug("No audio data available in buffer.")
122
+ return None
123
+
124
+ def get_input_audio_samplerate(self) -> int:
125
+ """Get the input samplerate of the audio device."""
126
+ return int(
127
+ sd.query_devices(self._input_device_id, "input")["default_samplerate"]
128
+ )
129
+
130
+ def get_output_audio_samplerate(self) -> int:
131
+ """Get the output samplerate of the audio device."""
132
+ return int(
133
+ sd.query_devices(self._output_device_id, "output")["default_samplerate"]
134
+ )
135
+
136
+ def get_input_channels(self) -> int:
137
+ """Get the number of input channels of the audio device."""
138
+ return min(
139
+ int(sd.query_devices(self._input_device_id, "input")["max_input_channels"]),
140
+ MAX_INPUT_CHANNELS,
141
+ )
142
+
143
+ def get_output_channels(self) -> int:
144
+ """Get the number of output channels of the audio device."""
145
+ return int(
146
+ sd.query_devices(self._output_device_id, "output")["max_output_channels"]
147
+ )
148
+
149
+ def stop_recording(self) -> None:
150
+ """Close the audio stream and release resources."""
151
+ if self._is_recording:
152
+ self._input_stream.stop() # type: ignore[attr-defined]
153
+ self._input_stream.close() # type: ignore[attr-defined]
154
+ self._input_stream = None
155
+ self.logger.info("SoundDevice audio stream closed.")
156
+
157
+ def push_audio_sample(self, data: npt.NDArray[np.float32]) -> None:
158
+ """Push audio data to the output device."""
159
+ if self._output_stream is not None:
160
+ with self._output_lock:
161
+ self._output_buffer.append(data.copy())
162
+ else:
163
+ self.logger.warning(
164
+ "Output stream is not open. Call start_playing() first."
165
+ )
166
+
167
+ def clear_output_buffer(self) -> None:
168
+ """Clear the output buffer."""
169
+ with self._output_lock:
170
+ self._output_buffer.clear()
171
+
172
+ def start_playing(self) -> None:
173
+ """Open the audio output stream."""
174
+ self.clear_output_buffer()
175
+
176
+ if self._output_stream is not None:
177
+ self.stop_playing()
178
+ self._output_stream = sd.OutputStream(
179
+ samplerate=self.get_output_audio_samplerate(),
180
+ device=self._output_device_id,
181
+ callback=self._output_callback,
182
+ )
183
+ if self._output_stream is None:
184
+ raise RuntimeError("Failed to open SoundDevice audio output stream.")
185
+ self._output_stream.start()
186
+ self.logger.info("SoundDevice audio output stream opened.")
187
+
188
+ def _output_callback(
189
+ self,
190
+ outdata: npt.NDArray[np.float32],
191
+ frames: int,
192
+ time: int,
193
+ status: sd.CallbackFlags,
194
+ ) -> None:
195
+ """Handle audio output stream callback."""
196
+ if status:
197
+ self.logger.warning(f"SoundDevice output status: {status}")
198
+
199
+ with self._output_lock:
200
+ filled = 0
201
+ while filled < frames and self._output_buffer:
202
+ chunk = self._output_buffer[0]
203
+
204
+ needed = frames - filled
205
+ available = len(chunk)
206
+ take = min(needed, available)
207
+
208
+ outdata[filled:filled + take] = chunk[:take]
209
+ filled += take
210
+
211
+ if take < available:
212
+ # Partial consumption, keep remainder
213
+ self._output_buffer[0] = chunk[take:]
214
+ else:
215
+ # Fully consumed this chunk
216
+ self._output_buffer.pop(0)
217
+
218
+ # Only pad with zeros if buffer is truly empty
219
+ if filled < frames:
220
+ outdata[filled:] = 0
221
+
222
+ def ensure_chunk_shape(
223
+ self, chunk: npt.NDArray[np.float32], target_shape: tuple[int, ...]
224
+ ) -> npt.NDArray[np.float32]:
225
+ """Ensure chunk has the shape (frames, num_channels) as required by outdata.
226
+
227
+ - If chunk is 1D, tile to required num_channels.
228
+ - If chunk is 2D with mismatched channels, use column 0.
229
+ - If chunk is already correct, return as-is.
230
+ """
231
+ num_channels = target_shape[1] if len(target_shape) > 1 else 1
232
+ if chunk.ndim == 1:
233
+ return np.tile(chunk[:, None], (1, num_channels))
234
+ elif chunk.shape[1] != num_channels:
235
+ # Broadcast first channel only
236
+ return np.tile(chunk[:, [0]], (1, num_channels))
237
+ return chunk
238
+
239
+ def stop_playing(self) -> None:
240
+ """Close the audio output stream."""
241
+ if self._output_stream is not None:
242
+ self._output_stream.stop()
243
+ self._output_stream.close()
244
+ self._output_stream = None
245
+ self.clear_output_buffer()
246
+ self.logger.info("SoundDevice audio output stream closed.")
247
+
248
+ def play_sound(self, sound_file: str) -> None:
249
+ """Play a sound file.
250
+
251
+ Args:
252
+ sound_file (str): Path to the sound file to play. May be given relative to the assets directory or as an absolute path.
253
+
254
+ """
255
+ if not os.path.exists(sound_file):
256
+ file_path = f"{ASSETS_ROOT_PATH}/{sound_file}"
257
+ if not os.path.exists(file_path):
258
+ raise FileNotFoundError(
259
+ f"Sound file {sound_file} not found in assets directory or given path."
260
+ )
261
+ else:
262
+ file_path = sound_file
263
+
264
+ data, samplerate_in = sf.read(file_path, dtype="float32")
265
+ samplerate_out = self.get_output_audio_samplerate()
266
+
267
+ if samplerate_in != samplerate_out:
268
+ data = scipy.signal.resample(
269
+ data, int(len(data) * (samplerate_out / samplerate_in))
270
+ )
271
+ data = self.ensure_chunk_shape(data, (-1, self.get_output_channels()))
272
+
273
+ self.logger.debug(f"Playing sound '{file_path}' at {samplerate_in} Hz")
274
+
275
+ if self._output_stream is not None:
276
+ self.push_audio_sample(data)
277
+ else:
278
+ self.logger.warning(
279
+ "Output stream wasn't open. We are opening it and leaving it open."
280
+ )
281
+ self.start_playing()
282
+ self.push_audio_sample(data)
283
+
284
+ def _get_device_id(
285
+ self, names_contains: List[str], device_io_type: str = "output"
286
+ ) -> int:
287
+ """Return the output device id whose name contains the given strings (case-insensitive).
288
+
289
+ Args:
290
+ names_contains (List[str]): List of strings that should be contained in the device name.
291
+ device_io_type (str): 'input' or 'output' to specify device type.
292
+
293
+ If not found, return the default output device id.
294
+
295
+ """
296
+ devices = sd.query_devices()
297
+
298
+ for idx, dev in enumerate(devices):
299
+ for name_contains in names_contains:
300
+ if (
301
+ name_contains.lower() in dev["name"].lower()
302
+ and dev[f"max_{device_io_type}_channels"] > 0
303
+ ):
304
+ return idx
305
+ # Return default output device if not found
306
+ self.logger.warning(
307
+ f"No {device_io_type} device found containing '{names_contains}', using default."
308
+ )
309
+ return self._safe_query_device(device_io_type)
310
+
311
+ def _safe_query_device(self, kind: str) -> int:
312
+ try:
313
+ return int(sd.query_devices(None, kind)["index"])
314
+ except sd.PortAudioError:
315
+ return (
316
+ int(sd.default.device[1])
317
+ if kind == "input"
318
+ else int(sd.default.device[0])
319
+ )
320
+ except IndexError:
321
+ return 0