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,146 @@
1
+ """State-related API routes.
2
+
3
+ This exposes:
4
+ - basic get routes to retrieve most common fields
5
+ - full state and streaming state updates
6
+ """
7
+
8
+ import asyncio
9
+ from datetime import datetime, timezone
10
+ from typing import Any
11
+
12
+ from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect
13
+
14
+ from ....daemon.backend.abstract import Backend
15
+ from ..dependencies import get_backend, ws_get_backend
16
+ from ..models import AnyPose, FullState, as_any_pose
17
+
18
+ router = APIRouter(prefix="/state")
19
+
20
+
21
+ @router.get("/present_head_pose")
22
+ async def get_head_pose(
23
+ use_pose_matrix: bool = False,
24
+ backend: Backend = Depends(get_backend),
25
+ ) -> AnyPose:
26
+ """Get the present head pose.
27
+
28
+ Arguments:
29
+ use_pose_matrix (bool): Whether to use the pose matrix representation (4x4 flattened) or the translation + Euler angles representation (x, y, z, roll, pitch, yaw).
30
+ backend (Backend): The backend instance.
31
+
32
+ Returns:
33
+ AnyPose: The present head pose.
34
+
35
+ """
36
+ return as_any_pose(backend.get_present_head_pose(), use_pose_matrix)
37
+
38
+
39
+ @router.get("/present_body_yaw")
40
+ async def get_body_yaw(
41
+ backend: Backend = Depends(get_backend),
42
+ ) -> float:
43
+ """Get the present body yaw (in radians)."""
44
+ return backend.get_present_body_yaw()
45
+
46
+
47
+ @router.get("/present_antenna_joint_positions")
48
+ async def get_antenna_joint_positions(
49
+ backend: Backend = Depends(get_backend),
50
+ ) -> tuple[float, float]:
51
+ """Get the present antenna joint positions (in radians) - (left, right)."""
52
+ pos = backend.get_present_antenna_joint_positions()
53
+ assert len(pos) == 2
54
+ return (pos[0], pos[1])
55
+
56
+
57
+ @router.get("/full")
58
+ async def get_full_state(
59
+ with_control_mode: bool = True,
60
+ with_head_pose: bool = True,
61
+ with_target_head_pose: bool = False,
62
+ with_head_joints: bool = False,
63
+ with_target_head_joints: bool = False,
64
+ with_body_yaw: bool = True,
65
+ with_target_body_yaw: bool = False,
66
+ with_antenna_positions: bool = True,
67
+ with_target_antenna_positions: bool = False,
68
+ with_passive_joints: bool = False,
69
+ use_pose_matrix: bool = False,
70
+ backend: Backend = Depends(get_backend),
71
+ ) -> FullState:
72
+ """Get the full robot state, with optional fields."""
73
+ result: dict[str, Any] = {}
74
+
75
+ if with_control_mode:
76
+ result["control_mode"] = backend.get_motor_control_mode().value
77
+
78
+ if with_head_pose:
79
+ pose = backend.get_present_head_pose()
80
+ result["head_pose"] = as_any_pose(pose, use_pose_matrix)
81
+ if with_target_head_pose:
82
+ target_pose = backend.target_head_pose
83
+ assert target_pose is not None
84
+ result["target_head_pose"] = as_any_pose(target_pose, use_pose_matrix)
85
+ if with_head_joints:
86
+ result["head_joints"] = backend.get_present_head_joint_positions()
87
+ if with_target_head_joints:
88
+ result["target_head_joints"] = backend.target_head_joint_positions
89
+ if with_body_yaw:
90
+ result["body_yaw"] = backend.get_present_body_yaw()
91
+ if with_target_body_yaw:
92
+ result["target_body_yaw"] = backend.target_body_yaw
93
+ if with_antenna_positions:
94
+ result["antennas_position"] = backend.get_present_antenna_joint_positions()
95
+ if with_target_antenna_positions:
96
+ result["target_antennas_position"] = backend.target_antenna_joint_positions
97
+ if with_passive_joints:
98
+ joints = backend.get_present_passive_joint_positions()
99
+ if joints is not None:
100
+ result["passive_joints"] = list(joints.values())
101
+ else:
102
+ result["passive_joints"] = None
103
+
104
+ result["timestamp"] = datetime.now(timezone.utc)
105
+ return FullState.model_validate(result)
106
+
107
+
108
+ @router.websocket("/ws/full")
109
+ async def ws_full_state(
110
+ websocket: WebSocket,
111
+ frequency: float = 10.0,
112
+ with_head_pose: bool = True,
113
+ with_target_head_pose: bool = False,
114
+ with_head_joints: bool = False,
115
+ with_target_head_joints: bool = False,
116
+ with_body_yaw: bool = True,
117
+ with_target_body_yaw: bool = False,
118
+ with_antenna_positions: bool = True,
119
+ with_target_antenna_positions: bool = False,
120
+ with_passive_joints: bool = False,
121
+ use_pose_matrix: bool = False,
122
+ backend: Backend = Depends(ws_get_backend),
123
+ ) -> None:
124
+ """WebSocket endpoint to stream the full state of the robot."""
125
+ await websocket.accept()
126
+ period = 1.0 / frequency
127
+
128
+ try:
129
+ while True:
130
+ full_state = await get_full_state(
131
+ with_head_pose=with_head_pose,
132
+ with_target_head_pose=with_target_head_pose,
133
+ with_head_joints=with_head_joints,
134
+ with_target_head_joints=with_target_head_joints,
135
+ with_body_yaw=with_body_yaw,
136
+ with_target_body_yaw=with_target_body_yaw,
137
+ with_antenna_positions=with_antenna_positions,
138
+ with_target_antenna_positions=with_target_antenna_positions,
139
+ with_passive_joints=with_passive_joints,
140
+ use_pose_matrix=use_pose_matrix,
141
+ backend=backend,
142
+ )
143
+ await websocket.send_text(full_state.model_dump_json())
144
+ await asyncio.sleep(period)
145
+ except WebSocketDisconnect:
146
+ pass
@@ -0,0 +1,86 @@
1
+ """Update router for Reachy Mini Daemon API.
2
+
3
+ This module provides endpoints to check for updates, start updates, and monitor update status.
4
+ """
5
+
6
+ import logging
7
+ import threading
8
+
9
+ import requests
10
+ from fastapi import APIRouter, HTTPException, WebSocket
11
+
12
+ from reachy_mini.daemon.app import bg_job_register
13
+ from reachy_mini.daemon.app.bg_job_register import JobInfo
14
+ from reachy_mini.utils.wireless_version.update import update_reachy_mini
15
+ from reachy_mini.utils.wireless_version.update_available import (
16
+ get_local_version,
17
+ get_pypi_version,
18
+ is_update_available,
19
+ )
20
+
21
+ router = APIRouter(prefix="/update")
22
+ busy_lock = threading.Lock()
23
+
24
+
25
+ @router.get("/available")
26
+ def available(pre_release: bool = False) -> dict[str, dict[str, dict[str, bool | str]]]:
27
+ """Check if an update is available for Reachy Mini Wireless."""
28
+ if busy_lock.locked():
29
+ raise HTTPException(status_code=400, detail="Update is in progress")
30
+
31
+ current_version = str(get_local_version("reachy_mini"))
32
+
33
+ try:
34
+ is_available = is_update_available("reachy_mini", pre_release)
35
+ available = str(get_pypi_version("reachy_mini", pre_release))
36
+ except (ConnectionError, requests.exceptions.ConnectionError):
37
+ is_available = False
38
+ available = "unknown"
39
+
40
+ return {
41
+ "update": {
42
+ "reachy_mini": {
43
+ "is_available": is_available,
44
+ "current_version": current_version,
45
+ "available_version": available,
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ @router.post("/start")
52
+ def start_update(pre_release: bool = False) -> dict[str, str]:
53
+ """Start the update process for Reachy Mini Wireless version."""
54
+ if busy_lock.locked():
55
+ raise HTTPException(status_code=400, detail="Update already in progress")
56
+
57
+ if not is_update_available("reachy_mini", pre_release):
58
+ raise HTTPException(status_code=400, detail="No update available")
59
+
60
+ async def update_wrapper(logger: logging.Logger) -> None:
61
+ with busy_lock:
62
+ await update_reachy_mini(pre_release, logger)
63
+
64
+ job_uuid = bg_job_register.run_command(
65
+ "update_reachy_mini",
66
+ update_wrapper,
67
+ )
68
+
69
+ return {"job_id": job_uuid}
70
+
71
+
72
+ @router.get("/info")
73
+ def get_update_info(job_id: str) -> JobInfo:
74
+ """Get the info of an update job."""
75
+ try:
76
+ return bg_job_register.get_info(job_id)
77
+ except ValueError as e:
78
+ raise HTTPException(status_code=404, detail=str(e))
79
+
80
+
81
+ @router.websocket("/ws/logs")
82
+ async def websocket_logs(websocket: WebSocket, job_id: str) -> None:
83
+ """WebSocket endpoint to stream update logs in real time."""
84
+ await websocket.accept()
85
+ await bg_job_register.ws_poll_info(websocket, job_id)
86
+ await websocket.close()
@@ -0,0 +1,423 @@
1
+ """Volume control API routes.
2
+
3
+ This exposes:
4
+ - get current volume
5
+ - set volume
6
+ - same for microphone
7
+ - play test sound (optional)
8
+ """
9
+
10
+ import logging
11
+ import platform
12
+ import subprocess
13
+ from typing import Optional
14
+
15
+ from fastapi import APIRouter, Depends, HTTPException
16
+ from pydantic import BaseModel, Field
17
+
18
+ from reachy_mini.daemon.app.dependencies import get_backend
19
+ from reachy_mini.daemon.backend.abstract import Backend
20
+
21
+ router = APIRouter(prefix="/volume")
22
+ logger = logging.getLogger(__name__)
23
+
24
+ # Constants
25
+ AUDIO_COMMAND_TIMEOUT = 2 # Timeout in seconds for audio commands
26
+
27
+ # Device-specific card names for amixer
28
+ DEVICE_CARD_NAMES = {
29
+ "reachy_mini_audio": "Audio", # Reachy Mini Audio device
30
+ "respeaker": "Array", # Legacy ReSpeaker device
31
+ "default": "Audio", # Default to Reachy Mini Audio
32
+ }
33
+
34
+
35
+ class VolumeRequest(BaseModel):
36
+ """Request model for setting volume."""
37
+
38
+ volume: int = Field(..., ge=0, le=100, description="Volume level (0-100)")
39
+
40
+
41
+ class VolumeResponse(BaseModel):
42
+ """Response model for volume operations."""
43
+
44
+ volume: int
45
+ device: str
46
+ platform: str
47
+
48
+
49
+ class TestSoundResponse(BaseModel):
50
+ """Response model for test sound operations."""
51
+
52
+ status: str
53
+ message: str
54
+
55
+
56
+ def get_current_platform() -> str:
57
+ """Get the current platform."""
58
+ system = platform.system()
59
+ if system == "Darwin":
60
+ return "macOS"
61
+ elif system == "Linux":
62
+ return "Linux"
63
+ else:
64
+ return system
65
+
66
+
67
+ def detect_audio_device() -> str:
68
+ """Detect the current audio output device."""
69
+ system = platform.system()
70
+
71
+ if system == "Linux":
72
+ # Try to detect if Reachy Mini Audio or legacy Respeaker is available
73
+ try:
74
+ result = subprocess.run(
75
+ ["aplay", "-l"],
76
+ capture_output=True,
77
+ text=True,
78
+ timeout=AUDIO_COMMAND_TIMEOUT,
79
+ )
80
+ output_lower = result.stdout.lower()
81
+ if "reachy mini audio" in output_lower:
82
+ return "reachy_mini_audio"
83
+ elif "respeaker" in output_lower:
84
+ return "respeaker"
85
+ except (subprocess.TimeoutExpired, FileNotFoundError):
86
+ pass
87
+ return "default"
88
+ elif system == "Darwin":
89
+ return "system"
90
+ else:
91
+ return "unknown"
92
+
93
+
94
+ def get_linux_card_name() -> str:
95
+ """Get the appropriate card name for Linux amixer commands based on detected device."""
96
+ device = detect_audio_device()
97
+ return DEVICE_CARD_NAMES.get(device, DEVICE_CARD_NAMES["default"])
98
+
99
+
100
+ # macOS Volume Control
101
+
102
+
103
+ def get_volume_macos() -> Optional[int]:
104
+ """Get current system volume on macOS."""
105
+ try:
106
+ result = subprocess.run(
107
+ ["osascript", "-e", "output volume of (get volume settings)"],
108
+ capture_output=True,
109
+ text=True,
110
+ timeout=AUDIO_COMMAND_TIMEOUT,
111
+ )
112
+ if result.returncode == 0:
113
+ return int(result.stdout.strip())
114
+ except (subprocess.TimeoutExpired, FileNotFoundError, ValueError) as e:
115
+ logger.error(f"Failed to get macOS volume: {e}")
116
+ return None
117
+
118
+
119
+ def set_volume_macos(volume: int) -> bool:
120
+ """Set system volume on macOS using osascript."""
121
+ try:
122
+ subprocess.run(
123
+ ["osascript", "-e", f"set volume output volume {volume}"],
124
+ capture_output=True,
125
+ timeout=AUDIO_COMMAND_TIMEOUT,
126
+ check=True,
127
+ )
128
+ return True
129
+ except (
130
+ subprocess.TimeoutExpired,
131
+ FileNotFoundError,
132
+ subprocess.CalledProcessError,
133
+ ) as e:
134
+ logger.error(f"Failed to set macOS volume: {e}")
135
+ return False
136
+
137
+
138
+ # Linux Volume Control
139
+
140
+
141
+ def get_volume_linux() -> Optional[int]:
142
+ """Get current volume on Linux using amixer."""
143
+ card_name = get_linux_card_name()
144
+ try:
145
+ result = subprocess.run(
146
+ ["amixer", "-c", card_name, "sget", "PCM"],
147
+ capture_output=True,
148
+ text=True,
149
+ timeout=AUDIO_COMMAND_TIMEOUT,
150
+ )
151
+ if result.returncode == 0:
152
+ # Parse output to extract volume percentage
153
+ for line in result.stdout.splitlines():
154
+ if "Left:" in line and "[" in line:
155
+ # Extract percentage between brackets
156
+ parts = line.split("[")
157
+ for part in parts:
158
+ if "%" in part:
159
+ volume_str = part.split("%")[0]
160
+ return int(volume_str)
161
+ except (subprocess.TimeoutExpired, FileNotFoundError, ValueError) as e:
162
+ logger.error(f"Failed to get Linux volume: {e}")
163
+ return None
164
+
165
+
166
+ def set_volume_linux(volume: int) -> bool:
167
+ """Set current volume on Linux using amixer."""
168
+ card_name = get_linux_card_name()
169
+ try:
170
+ subprocess.run(
171
+ ["amixer", "-c", card_name, "sset", "PCM", f"{volume}%"],
172
+ capture_output=True,
173
+ text=True,
174
+ timeout=AUDIO_COMMAND_TIMEOUT,
175
+ check=True,
176
+ )
177
+ subprocess.run(
178
+ ["amixer", "-c", card_name, "sset", "PCM,1", "100%"],
179
+ capture_output=True,
180
+ text=True,
181
+ timeout=AUDIO_COMMAND_TIMEOUT,
182
+ check=True,
183
+ )
184
+ return True
185
+ except (
186
+ subprocess.TimeoutExpired,
187
+ FileNotFoundError,
188
+ subprocess.CalledProcessError,
189
+ ValueError,
190
+ ) as e:
191
+ logger.error(f"Failed to set Linux volume: {e}")
192
+ return False
193
+
194
+
195
+ # API Endpoints - Speaker Volume
196
+
197
+
198
+ @router.get("/current")
199
+ async def get_volume() -> VolumeResponse:
200
+ """Get the current volume level."""
201
+ system = get_current_platform()
202
+ device = detect_audio_device()
203
+
204
+ volume = None
205
+ if system == "macOS":
206
+ volume = get_volume_macos()
207
+ elif system == "Linux":
208
+ volume = get_volume_linux()
209
+
210
+ if volume is None:
211
+ raise HTTPException(status_code=500, detail="Failed to get volume")
212
+
213
+ return VolumeResponse(volume=volume, device=device, platform=system)
214
+
215
+
216
+ @router.post("/set")
217
+ async def set_volume(
218
+ volume_req: VolumeRequest,
219
+ backend: Backend = Depends(get_backend),
220
+ ) -> VolumeResponse:
221
+ """Set the volume level and play a test sound."""
222
+ system = get_current_platform()
223
+ device = detect_audio_device()
224
+
225
+ success = False
226
+ if system == "macOS":
227
+ success = set_volume_macos(volume_req.volume)
228
+ elif system == "Linux":
229
+ success = set_volume_linux(volume_req.volume)
230
+ else:
231
+ raise HTTPException(
232
+ status_code=501,
233
+ detail=f"Volume control not supported on {system}",
234
+ )
235
+
236
+ if not success:
237
+ raise HTTPException(status_code=500, detail="Failed to set volume")
238
+
239
+ # Play test sound
240
+ test_sound = "impatient1.wav"
241
+ if backend.audio:
242
+ try:
243
+ backend.audio.play_sound(test_sound)
244
+ except Exception as e:
245
+ msg = str(e).lower()
246
+ if "device unavailable" in msg or "-9985" in msg:
247
+ logger.warning(
248
+ "Test sound not played: audio device busy (likely GStreamer): %s",
249
+ e,
250
+ )
251
+ else:
252
+ logger.warning("Failed to play test sound: %s", e)
253
+ else:
254
+ logger.warning("No audio backend available, skipping test sound.")
255
+
256
+ return VolumeResponse(volume=volume_req.volume, device=device, platform=system)
257
+
258
+
259
+ @router.post("/test-sound")
260
+ async def play_test_sound(backend: Backend = Depends(get_backend)) -> TestSoundResponse:
261
+ """Play a test sound."""
262
+ test_sound = "impatient1.wav"
263
+
264
+ if not backend.audio:
265
+ raise HTTPException(status_code=503, detail="Audio device not available")
266
+
267
+ try:
268
+ backend.audio.play_sound(test_sound)
269
+ return TestSoundResponse(status="ok", message="Test sound played")
270
+ except Exception as e:
271
+ msg = str(e).lower()
272
+
273
+ # Special-case ALSA / PortAudio device-busy situation
274
+ if "device unavailable" in msg or "-9985" in msg:
275
+ logger.warning(
276
+ "Test sound request while audio device is busy (likely GStreamer): %s",
277
+ e,
278
+ )
279
+ # Still 200, but tell the caller it was skipped
280
+ return TestSoundResponse(
281
+ status="busy",
282
+ message="Audio device is currently in use, test sound was skipped.",
283
+ )
284
+
285
+ # Any other error is treated as a real failure
286
+ logger.error("Failed to play test sound: %s", e, exc_info=True)
287
+ raise HTTPException(
288
+ status_code=500,
289
+ detail="Failed to play test sound (see logs for details)",
290
+ )
291
+
292
+
293
+ # macOS Microphone Control
294
+
295
+
296
+ def get_microphone_volume_macos() -> Optional[int]:
297
+ """Get current microphone input volume on macOS."""
298
+ try:
299
+ result = subprocess.run(
300
+ ["osascript", "-e", "input volume of (get volume settings)"],
301
+ capture_output=True,
302
+ text=True,
303
+ timeout=AUDIO_COMMAND_TIMEOUT,
304
+ )
305
+ if result.returncode == 0:
306
+ return int(result.stdout.strip())
307
+ except (subprocess.TimeoutExpired, FileNotFoundError, ValueError) as e:
308
+ logger.error(f"Failed to get macOS microphone volume: {e}")
309
+ return None
310
+
311
+
312
+ def set_microphone_volume_macos(volume: int) -> bool:
313
+ """Set microphone input volume on macOS using osascript."""
314
+ try:
315
+ subprocess.run(
316
+ ["osascript", "-e", f"set volume input volume {volume}"],
317
+ capture_output=True,
318
+ timeout=AUDIO_COMMAND_TIMEOUT,
319
+ check=True,
320
+ )
321
+ return True
322
+ except (
323
+ subprocess.TimeoutExpired,
324
+ FileNotFoundError,
325
+ subprocess.CalledProcessError,
326
+ ) as e:
327
+ logger.error(f"Failed to set macOS microphone volume: {e}")
328
+ return False
329
+
330
+
331
+ # Linux Microphone Control
332
+
333
+
334
+ def get_microphone_volume_linux() -> Optional[int]:
335
+ """Get current microphone input volume on Linux using amixer."""
336
+ card_name = get_linux_card_name()
337
+ try:
338
+ result = subprocess.run(
339
+ ["amixer", "-c", card_name, "sget", "Headset"],
340
+ capture_output=True,
341
+ text=True,
342
+ timeout=AUDIO_COMMAND_TIMEOUT,
343
+ )
344
+ if result.returncode == 0:
345
+ # Parse output to extract volume percentage
346
+ for line in result.stdout.splitlines():
347
+ if "Left:" in line and "[" in line:
348
+ parts = line.split("[")
349
+ for part in parts:
350
+ if "%" in part:
351
+ volume_str = part.split("%")[0]
352
+ return int(volume_str)
353
+ except (subprocess.TimeoutExpired, FileNotFoundError, ValueError) as e:
354
+ logger.error(f"Failed to get Linux microphone volume: {e}")
355
+ return None
356
+
357
+
358
+ def set_microphone_volume_linux(volume: int) -> bool:
359
+ """Set microphone input volume on Linux using amixer."""
360
+ card_name = get_linux_card_name()
361
+ try:
362
+ subprocess.run(
363
+ ["amixer", "-c", card_name, "sset", "Headset", f"{volume}%"],
364
+ capture_output=True,
365
+ text=True,
366
+ timeout=AUDIO_COMMAND_TIMEOUT,
367
+ check=True,
368
+ )
369
+ return True
370
+ except (
371
+ subprocess.TimeoutExpired,
372
+ FileNotFoundError,
373
+ subprocess.CalledProcessError,
374
+ ValueError,
375
+ ) as e:
376
+ logger.error(f"Failed to set Linux microphone volume: {e}")
377
+ return False
378
+
379
+
380
+ # API Endpoints - Microphone Volume
381
+
382
+
383
+ @router.get("/microphone/current")
384
+ async def get_microphone_volume() -> VolumeResponse:
385
+ """Get the current microphone input volume level."""
386
+ system = get_current_platform()
387
+ device = detect_audio_device()
388
+
389
+ volume = None
390
+ if system == "macOS":
391
+ volume = get_microphone_volume_macos()
392
+ elif system == "Linux":
393
+ volume = get_microphone_volume_linux()
394
+
395
+ if volume is None:
396
+ raise HTTPException(status_code=500, detail="Failed to get microphone volume")
397
+
398
+ return VolumeResponse(volume=volume, device=device, platform=system)
399
+
400
+
401
+ @router.post("/microphone/set")
402
+ async def set_microphone_volume(
403
+ volume_req: VolumeRequest,
404
+ ) -> VolumeResponse:
405
+ """Set the microphone input volume level."""
406
+ system = get_current_platform()
407
+ device = detect_audio_device()
408
+
409
+ success = False
410
+ if system == "macOS":
411
+ success = set_microphone_volume_macos(volume_req.volume)
412
+ elif system == "Linux":
413
+ success = set_microphone_volume_linux(volume_req.volume)
414
+ else:
415
+ raise HTTPException(
416
+ status_code=501,
417
+ detail=f"Microphone volume control not supported on {system}",
418
+ )
419
+
420
+ if not success:
421
+ raise HTTPException(status_code=500, detail="Failed to set microphone volume")
422
+
423
+ return VolumeResponse(volume=volume_req.volume, device=device, platform=system)