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,114 @@
1
+ """Utility functions for audio handling, specifically for detecting the ReSpeaker sound card."""
2
+
3
+ import logging
4
+ import subprocess
5
+ from pathlib import Path
6
+
7
+
8
+ def _process_card_number_output(output: str) -> int:
9
+ """Process the output of 'arecord -l' to find the ReSpeaker or Reachy Mini Audio card number."""
10
+ lines = output.split("\n")
11
+ for line in lines:
12
+ if "reachy mini audio" in line.lower():
13
+ card_number = line.split(" ")[1].split(":")[0]
14
+ logging.debug(f"Found Reachy Mini Audio sound card: {card_number}")
15
+ return int(card_number)
16
+ elif "respeaker" in line.lower():
17
+ card_number = line.split(" ")[1].split(":")[0]
18
+ logging.warning(
19
+ f"Found ReSpeaker sound card: {card_number}. Please update firmware!"
20
+ )
21
+ return int(card_number)
22
+
23
+ logging.warning("Reachy Mini Audio sound card not found. Returning default card")
24
+ return 0 # default sound card
25
+
26
+
27
+ def get_respeaker_card_number() -> int:
28
+ """Return the card number of the ReSpeaker sound card, or 0 if not found."""
29
+ try:
30
+ result = subprocess.run(
31
+ ["arecord", "-l"], capture_output=True, text=True, check=True
32
+ )
33
+ output = result.stdout
34
+
35
+ return _process_card_number_output(output)
36
+
37
+ except subprocess.CalledProcessError as e:
38
+ logging.error(f"Cannot find sound card: {e}")
39
+ return -1
40
+
41
+
42
+ def has_reachymini_asoundrc() -> bool:
43
+ """Check if ~/.asoundrc exists and contains both reachymini_audio_sink and reachymini_audio_src."""
44
+ asoundrc_path = Path.home().joinpath(".asoundrc")
45
+ if not asoundrc_path.exists():
46
+ return False
47
+ content = asoundrc_path.read_text(errors="ignore")
48
+ return "reachymini_audio_sink" in content and "reachymini_audio_src" in content
49
+
50
+
51
+ def check_reachymini_asoundrc() -> bool:
52
+ """Check if ~/.asoundrc exists and is correctly configured for Reachy Mini Audio."""
53
+ asoundrc_path = Path.home().joinpath(".asoundrc")
54
+ if not asoundrc_path.exists():
55
+ return False
56
+ content = asoundrc_path.read_text(errors="ignore")
57
+ card_id = get_respeaker_card_number()
58
+ # Check for both sink and src
59
+ if not ("reachymini_audio_sink" in content and "reachymini_audio_src" in content):
60
+ return False
61
+ # Check that the card number in .asoundrc matches the detected card_id
62
+ import re
63
+
64
+ card_numbers = set(re.findall(r"card\s+(\d+)", content))
65
+ if str(card_id) not in card_numbers:
66
+ return False
67
+ return True
68
+
69
+
70
+ def write_asoundrc_to_home() -> None:
71
+ """Write the .asoundrc file with Reachy Mini audio configuration to the user's home directory."""
72
+ card_id = get_respeaker_card_number()
73
+ asoundrc_content = f"""
74
+ pcm.!default {{
75
+ type hw
76
+ card {card_id}
77
+ }}
78
+
79
+ ctl.!default {{
80
+ type hw
81
+ card {card_id}
82
+ }}
83
+
84
+ pcm.reachymini_audio_sink {{
85
+ type dmix
86
+ ipc_key 4241
87
+ slave {{
88
+ pcm "hw:{card_id},0"
89
+ channels 2
90
+ period_size 1024
91
+ buffer_size 4096
92
+ rate 16000
93
+ }}
94
+ bindings {{
95
+ 0 0
96
+ 1 1
97
+ }}
98
+ }}
99
+
100
+ pcm.reachymini_audio_src {{
101
+ type dsnoop
102
+ ipc_key 4242
103
+ slave {{
104
+ pcm "hw:{card_id},0"
105
+ channels 2
106
+ rate 16000
107
+ period_size 1024
108
+ buffer_size 4096
109
+ }}
110
+ }}
111
+ """
112
+ asoundrc_path = Path.home().joinpath(".asoundrc")
113
+ with open(asoundrc_path, "w") as f:
114
+ f.write(asoundrc_content)
@@ -0,0 +1,100 @@
1
+ """Base classes for camera implementations.
2
+
3
+ The camera implementations support various backends and provide a unified
4
+ interface for capturing images.
5
+ """
6
+
7
+ import logging
8
+ from abc import ABC, abstractmethod
9
+ from typing import Optional
10
+
11
+ import numpy as np
12
+ import numpy.typing as npt
13
+
14
+ from reachy_mini.media.camera_constants import (
15
+ CameraResolution,
16
+ CameraSpecs,
17
+ MujocoCameraSpecs,
18
+ )
19
+
20
+
21
+ class CameraBase(ABC):
22
+ """Abstract class for opening and managing a camera."""
23
+
24
+ def __init__(
25
+ self,
26
+ log_level: str = "INFO",
27
+ ) -> None:
28
+ """Initialize the camera."""
29
+ self.logger = logging.getLogger(__name__)
30
+ self.logger.setLevel(log_level)
31
+ self._resolution: Optional[CameraResolution] = None
32
+ self.camera_specs: Optional[CameraSpecs] = None
33
+ self.resized_K: Optional[npt.NDArray[np.float64]] = None
34
+
35
+ @property
36
+ def resolution(self) -> tuple[int, int]:
37
+ """Get the current camera resolution as a tuple (width, height)."""
38
+ if self._resolution is None:
39
+ raise RuntimeError("Camera resolution is not set.")
40
+ return (self._resolution.value[0], self._resolution.value[1])
41
+
42
+ @property
43
+ def framerate(self) -> int:
44
+ """Get the current camera frames per second."""
45
+ if self._resolution is None:
46
+ raise RuntimeError("Camera resolution is not set.")
47
+ return int(self._resolution.value[2])
48
+
49
+ @property
50
+ def K(self) -> Optional[npt.NDArray[np.float64]]:
51
+ """Get the camera intrinsic matrix for the current resolution."""
52
+ return self.resized_K
53
+
54
+ @property
55
+ def D(self) -> Optional[npt.NDArray[np.float64]]:
56
+ """Get the camera distortion coefficients."""
57
+ if self.camera_specs is not None:
58
+ return self.camera_specs.D
59
+ return None
60
+
61
+ def set_resolution(self, resolution: CameraResolution) -> None:
62
+ """Set the camera resolution."""
63
+ if self.camera_specs is None:
64
+ raise RuntimeError(
65
+ "Camera specs not set. Open the camera before setting the resolution."
66
+ )
67
+
68
+ if isinstance(self.camera_specs, MujocoCameraSpecs):
69
+ raise RuntimeError(
70
+ "Cannot change resolution of Mujoco simulated camera for now."
71
+ )
72
+
73
+ if resolution not in self.camera_specs.available_resolutions:
74
+ raise ValueError(
75
+ f"Resolution not supported by the camera. Available resolutions are : {self.camera_specs.available_resolutions}"
76
+ )
77
+
78
+ w_ratio = resolution.value[0] / self.camera_specs.default_resolution.value[0]
79
+ h_ratio = resolution.value[1] / self.camera_specs.default_resolution.value[1]
80
+ self.resized_K = self.camera_specs.K.copy()
81
+
82
+ self.resized_K[0, 0] *= w_ratio
83
+ self.resized_K[1, 1] *= h_ratio
84
+ self.resized_K[0, 2] *= w_ratio
85
+ self.resized_K[1, 2] *= h_ratio
86
+
87
+ @abstractmethod
88
+ def open(self) -> None:
89
+ """Open the camera."""
90
+ pass
91
+
92
+ @abstractmethod
93
+ def read(self) -> Optional[npt.NDArray[np.uint8]]:
94
+ """Read an image from the camera. Returns the image or None if error."""
95
+ pass
96
+
97
+ @abstractmethod
98
+ def close(self) -> None:
99
+ """Close the camera and release resources."""
100
+ pass
@@ -0,0 +1,152 @@
1
+ """Camera constants for Reachy Mini."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import Enum
5
+ from typing import List
6
+
7
+ import numpy as np
8
+ import numpy.typing as npt
9
+
10
+
11
+ class CameraResolution(Enum):
12
+ """Base class for camera resolutions."""
13
+
14
+ R1536x864at40fps = (1536, 864, 40)
15
+
16
+ R1280x720at60fps = (1280, 720, 60)
17
+ R1280x720at30fps = (1280, 720, 30)
18
+
19
+ R1920x1080at30fps = (1920, 1080, 30)
20
+ R1920x1080at60fps = (1920, 1080, 60)
21
+
22
+ R2304x1296at30fps = (2304, 1296, 30)
23
+ R1600x1200at30fps = (1600, 1200, 30)
24
+
25
+ R3264x2448at30fps = (3264, 2448, 30)
26
+ R3264x2448at10fps = (3264, 2448, 10)
27
+
28
+ R3840x2592at30fps = (3840, 2592, 30)
29
+ R3840x2592at10fps = (3840, 2592, 10)
30
+ R3840x2160at30fps = (3840, 2160, 30)
31
+ R3840x2160at10fps = (3840, 2160, 10)
32
+
33
+ R3072x1728at10fps = (3072, 1728, 10)
34
+
35
+ R4608x2592at10fps = (4608, 2592, 10)
36
+
37
+
38
+ @dataclass
39
+ class CameraSpecs:
40
+ """Base camera specifications."""
41
+
42
+ name: str = ""
43
+ available_resolutions: List[CameraResolution] = field(default_factory=list)
44
+ default_resolution: CameraResolution = CameraResolution.R1280x720at30fps
45
+ vid = 0
46
+ pid = 0
47
+ K: npt.NDArray[np.float64] = field(default_factory=lambda: np.eye(3))
48
+ D: npt.NDArray[np.float64] = field(default_factory=lambda: np.zeros((5,)))
49
+
50
+
51
+ @dataclass
52
+ class ArducamSpecs(CameraSpecs):
53
+ """Arducam camera specifications."""
54
+
55
+ name = "arducam"
56
+ available_resolutions = [
57
+ CameraResolution.R2304x1296at30fps,
58
+ CameraResolution.R4608x2592at10fps,
59
+ CameraResolution.R1920x1080at30fps,
60
+ CameraResolution.R1600x1200at30fps,
61
+ CameraResolution.R1280x720at30fps,
62
+ ]
63
+ default_resolution = CameraResolution.R1280x720at30fps
64
+ vid = 0x0C45
65
+ pid = 0x636D
66
+ K = np.array([[550.3564, 0.0, 638.0112], [0.0, 549.1653, 364.589], [0.0, 0.0, 1.0]])
67
+ D = np.array([-0.0694, 0.1565, -0.0004, 0.0003, -0.0983])
68
+
69
+
70
+ @dataclass
71
+ class ReachyMiniLiteCamSpecs(CameraSpecs):
72
+ """Reachy Mini Lite camera specifications."""
73
+
74
+ name = "lite"
75
+ available_resolutions = [
76
+ CameraResolution.R1920x1080at60fps,
77
+ CameraResolution.R3840x2592at30fps,
78
+ CameraResolution.R3840x2160at30fps,
79
+ CameraResolution.R3264x2448at30fps,
80
+ ]
81
+ default_resolution = CameraResolution.R1920x1080at60fps
82
+ vid = 0x38FB
83
+ pid = 0x1002
84
+ K = np.array(
85
+ [
86
+ [821.515, 0.0, 962.241],
87
+ [0.0, 820.830, 542.459],
88
+ [0.0, 0.0, 1.0],
89
+ ]
90
+ )
91
+
92
+ D = np.array(
93
+ [
94
+ -2.94475669e-02,
95
+ 6.00511974e-02,
96
+ 3.57813971e-06,
97
+ -2.96459394e-04,
98
+ -3.79243988e-02,
99
+ ]
100
+ )
101
+
102
+
103
+ @dataclass
104
+ class ReachyMiniWirelessCamSpecs(ReachyMiniLiteCamSpecs):
105
+ """Reachy Mini Wireless camera specifications."""
106
+
107
+ name = "wireless"
108
+ available_resolutions = [
109
+ CameraResolution.R1920x1080at30fps,
110
+ CameraResolution.R1280x720at60fps,
111
+ CameraResolution.R3840x2592at10fps,
112
+ CameraResolution.R3840x2160at10fps,
113
+ CameraResolution.R3264x2448at10fps,
114
+ CameraResolution.R3072x1728at10fps,
115
+ ]
116
+ default_resolution = CameraResolution.R1920x1080at30fps
117
+
118
+
119
+ @dataclass
120
+ class OlderRPiCamSpecs(ReachyMiniLiteCamSpecs):
121
+ """Older Raspberry Pi camera specifications. Keeping for compatibility."""
122
+
123
+ name = "older_rpi"
124
+ vid = 0x1BCF
125
+ pid = 0x28C4
126
+
127
+
128
+ @dataclass
129
+ class MujocoCameraSpecs(CameraSpecs):
130
+ """Mujoco simulated camera specifications."""
131
+
132
+ available_resolutions = [
133
+ CameraResolution.R1280x720at60fps,
134
+ ]
135
+ default_resolution = CameraResolution.R1280x720at60fps
136
+ # ideal camera matrix
137
+ K = np.array(
138
+ [
139
+ [
140
+ CameraResolution.R1280x720at60fps.value[0],
141
+ 0.0,
142
+ CameraResolution.R1280x720at60fps.value[0] / 2,
143
+ ],
144
+ [
145
+ 0.0,
146
+ CameraResolution.R1280x720at60fps.value[1],
147
+ CameraResolution.R1280x720at60fps.value[1] / 2,
148
+ ],
149
+ [0.0, 0.0, 1.0],
150
+ ]
151
+ )
152
+ D = np.zeros((5,)) # no distortion
@@ -0,0 +1,231 @@
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, Tuple, cast
10
+
11
+ import numpy as np
12
+ import numpy.typing as npt
13
+
14
+ from reachy_mini.media.camera_constants import (
15
+ ArducamSpecs,
16
+ CameraResolution,
17
+ CameraSpecs,
18
+ ReachyMiniLiteCamSpecs,
19
+ ReachyMiniWirelessCamSpecs,
20
+ )
21
+
22
+ try:
23
+ import gi
24
+
25
+ except ImportError as e:
26
+ raise ImportError(
27
+ "The 'gi' module is required for GStreamerCamera but could not be imported. \
28
+ Please install the GStreamer backend: pip install .[gstreamer]."
29
+ ) from e
30
+
31
+ gi.require_version("Gst", "1.0")
32
+ gi.require_version("GstApp", "1.0")
33
+
34
+
35
+ from gi.repository import GLib, Gst, GstApp # noqa: E402
36
+
37
+ from .camera_base import CameraBase # noqa: E402
38
+
39
+
40
+ class GStreamerCamera(CameraBase):
41
+ """Camera implementation using GStreamer."""
42
+
43
+ def __init__(
44
+ self,
45
+ log_level: str = "INFO",
46
+ ) -> None:
47
+ """Initialize the GStreamer camera."""
48
+ super().__init__(log_level=log_level)
49
+ Gst.init(None)
50
+ self._loop = GLib.MainLoop()
51
+ self._thread_bus_calls: Optional[Thread] = None
52
+
53
+ self.pipeline = Gst.Pipeline.new("camera_recorder")
54
+
55
+ cam_path, self.camera_specs = self.get_video_device()
56
+
57
+ if self.camera_specs is None:
58
+ raise RuntimeError("Camera specs not set")
59
+ self._resolution = self.camera_specs.default_resolution
60
+ self.resized_K = self.camera_specs.K
61
+
62
+ if self._resolution is None:
63
+ raise RuntimeError("Failed to get default camera resolution.")
64
+
65
+ # note for some applications the jpeg image could be directly used
66
+ self._appsink_video: GstApp = Gst.ElementFactory.make("appsink")
67
+ self.set_resolution(self._resolution)
68
+ self._appsink_video.set_property("drop", True) # avoid overflow
69
+ self._appsink_video.set_property("max-buffers", 1) # keep last image only
70
+ self.pipeline.add(self._appsink_video)
71
+
72
+ if cam_path == "":
73
+ self.logger.warning("Recording pipeline set without camera.")
74
+ self.pipeline.remove(self._appsink_video)
75
+ elif cam_path == "/tmp/reachymini_camera_socket":
76
+ camsrc = Gst.ElementFactory.make("unixfdsrc")
77
+ camsrc.set_property("socket-path", "/tmp/reachymini_camera_socket")
78
+ self.pipeline.add(camsrc)
79
+ queue = Gst.ElementFactory.make("queue")
80
+ self.pipeline.add(queue)
81
+ videoconvert = Gst.ElementFactory.make("videoconvert")
82
+ self.pipeline.add(videoconvert)
83
+ camsrc.link(queue)
84
+ queue.link(videoconvert)
85
+ videoconvert.link(self._appsink_video)
86
+ elif cam_path == "imx708":
87
+ camsrc = Gst.ElementFactory.make("libcamerasrc")
88
+ self.pipeline.add(camsrc)
89
+ queue = Gst.ElementFactory.make("queue")
90
+ self.pipeline.add(queue)
91
+ videoconvert = Gst.ElementFactory.make("videoconvert")
92
+ self.pipeline.add(videoconvert)
93
+ camsrc.link(queue)
94
+ queue.link(videoconvert)
95
+ videoconvert.link(self._appsink_video)
96
+ else:
97
+ camsrc = Gst.ElementFactory.make("v4l2src")
98
+ camsrc.set_property("device", cam_path)
99
+ self.pipeline.add(camsrc)
100
+ queue = Gst.ElementFactory.make("queue")
101
+ self.pipeline.add(queue)
102
+ # use vaapijpegdec or nvjpegdec for hardware acceleration
103
+ jpegdec = Gst.ElementFactory.make("jpegdec")
104
+ self.pipeline.add(jpegdec)
105
+ videoconvert = Gst.ElementFactory.make("videoconvert")
106
+ self.pipeline.add(videoconvert)
107
+ camsrc.link(queue)
108
+ queue.link(jpegdec)
109
+ jpegdec.link(videoconvert)
110
+ videoconvert.link(self._appsink_video)
111
+
112
+ def _on_bus_message(self, bus: Gst.Bus, msg: Gst.Message, loop) -> bool: # type: ignore[no-untyped-def]
113
+ t = msg.type
114
+ if t == Gst.MessageType.EOS:
115
+ self.logger.warning("End-of-stream")
116
+ return False
117
+
118
+ elif t == Gst.MessageType.ERROR:
119
+ err, debug = msg.parse_error()
120
+ self.logger.error(f"Error: {err} {debug}")
121
+ return False
122
+
123
+ return True
124
+
125
+ def _handle_bus_calls(self) -> None:
126
+ self.logger.debug("starting bus message loop")
127
+ bus = self.pipeline.get_bus()
128
+ bus.add_watch(GLib.PRIORITY_DEFAULT, self._on_bus_message, self._loop)
129
+ self._loop.run()
130
+ bus.remove_watch()
131
+ self.logger.debug("bus message loop stopped")
132
+
133
+ def set_resolution(self, resolution: CameraResolution) -> None:
134
+ """Set the camera resolution."""
135
+ super().set_resolution(resolution)
136
+
137
+ # Check if pipeline is not playing before changing resolution
138
+ if self.pipeline.get_state(0).state == Gst.State.PLAYING:
139
+ raise RuntimeError(
140
+ "Cannot change resolution while the camera is streaming. Please close the camera first."
141
+ )
142
+
143
+ self._resolution = resolution
144
+ caps_video = Gst.Caps.from_string(
145
+ f"video/x-raw,format=BGR, width={self._resolution.value[0]},height={self._resolution.value[1]},framerate={self.framerate}/1"
146
+ )
147
+ self._appsink_video.set_property("caps", caps_video)
148
+
149
+ def open(self) -> None:
150
+ """Open the camera using GStreamer."""
151
+ self.pipeline.set_state(Gst.State.PLAYING)
152
+ self._thread_bus_calls = Thread(target=self._handle_bus_calls, daemon=True)
153
+ self._thread_bus_calls.start()
154
+
155
+ def _get_sample(self, appsink: GstApp.AppSink) -> Optional[bytes]:
156
+ sample = appsink.try_pull_sample(20_000_000)
157
+ if sample is None:
158
+ return None
159
+ data = None
160
+ if isinstance(sample, Gst.Sample):
161
+ buf = sample.get_buffer()
162
+ if buf is None:
163
+ self.logger.warning("Buffer is None")
164
+
165
+ data = buf.extract_dup(0, buf.get_size())
166
+ return data
167
+
168
+ def read(self) -> Optional[npt.NDArray[np.uint8]]:
169
+ """Read a frame from the camera. Returns the frame or None if error.
170
+
171
+ Returns:
172
+ Optional[npt.NDArray[np.uint8]]: The captured BGR frame as a NumPy array, or None if error.
173
+
174
+ """
175
+ data = self._get_sample(self._appsink_video)
176
+ if data is None:
177
+ return None
178
+
179
+ arr = np.frombuffer(data, dtype=np.uint8).reshape(
180
+ (self.resolution[1], self.resolution[0], 3)
181
+ )
182
+ return arr
183
+
184
+ def close(self) -> None:
185
+ """Release the camera resource."""
186
+ self._loop.quit()
187
+ self.pipeline.set_state(Gst.State.NULL)
188
+
189
+ def get_video_device(self) -> Tuple[str, Optional[CameraSpecs]]:
190
+ """Use Gst.DeviceMonitor to find the unix camera path /dev/videoX.
191
+
192
+ Returns the device path (e.g., '/dev/video2'), or '' if not found.
193
+ """
194
+ if os.path.exists("/tmp/reachymini_camera_socket"):
195
+ camera_specs = cast(CameraSpecs, ReachyMiniWirelessCamSpecs)
196
+ self.logger.debug(
197
+ "Found wireless camera socket at /tmp/reachymini_camera_socket"
198
+ )
199
+ return "/tmp/reachymini_camera_socket", camera_specs
200
+
201
+ monitor = Gst.DeviceMonitor()
202
+ monitor.add_filter("Video/Source")
203
+ monitor.start()
204
+
205
+ cam_names = ["Reachy", "Arducam_12MP", "imx708"]
206
+
207
+ devices = monitor.get_devices()
208
+ for cam_name in cam_names:
209
+ for device in devices:
210
+ name = device.get_display_name()
211
+ device_props = device.get_properties()
212
+
213
+ if cam_name in name:
214
+ if device_props and device_props.has_field("api.v4l2.path"):
215
+ device_path = device_props.get_string("api.v4l2.path")
216
+ camera_specs = (
217
+ cast(CameraSpecs, ArducamSpecs)
218
+ if cam_name == "Arducam_12MP"
219
+ else cast(CameraSpecs, ReachyMiniLiteCamSpecs)
220
+ )
221
+ self.logger.debug(f"Found {cam_name} camera at {device_path}")
222
+ monitor.stop()
223
+ return str(device_path), camera_specs
224
+ elif cam_name == "imx708":
225
+ camera_specs = cast(CameraSpecs, ReachyMiniWirelessCamSpecs)
226
+ self.logger.debug(f"Found {cam_name} camera")
227
+ monitor.stop()
228
+ return cam_name, camera_specs
229
+ monitor.stop()
230
+ self.logger.warning("No camera found.")
231
+ return "", None
@@ -0,0 +1,89 @@
1
+ """OpenCv camera backend.
2
+
3
+ This module provides an implementation of the CameraBase class using OpenCV.
4
+ """
5
+
6
+ from typing import Optional, cast
7
+
8
+ import cv2
9
+ import numpy as np
10
+ import numpy.typing as npt
11
+
12
+ from reachy_mini.media.camera_constants import (
13
+ CameraResolution,
14
+ CameraSpecs,
15
+ MujocoCameraSpecs,
16
+ )
17
+ from reachy_mini.media.camera_utils import find_camera
18
+
19
+ from .camera_base import CameraBase
20
+
21
+
22
+ class OpenCVCamera(CameraBase):
23
+ """Camera implementation using OpenCV."""
24
+
25
+ def __init__(
26
+ self,
27
+ log_level: str = "INFO",
28
+ ) -> None:
29
+ """Initialize the OpenCV camera."""
30
+ super().__init__(log_level=log_level)
31
+ self.cap: Optional[cv2.VideoCapture] = None
32
+
33
+ def set_resolution(self, resolution: CameraResolution) -> None:
34
+ """Set the camera resolution."""
35
+ super().set_resolution(resolution)
36
+
37
+ self._resolution = resolution
38
+ if self.cap is not None:
39
+ self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self._resolution.value[0])
40
+ self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self._resolution.value[1])
41
+
42
+ def open(self, udp_camera: Optional[str] = None) -> None:
43
+ """Open the camera using OpenCV VideoCapture."""
44
+ if udp_camera:
45
+ self.cap = cv2.VideoCapture(udp_camera)
46
+ self.camera_specs = cast(CameraSpecs, MujocoCameraSpecs)
47
+ self._resolution = self.camera_specs.default_resolution
48
+ else:
49
+ self.cap, self.camera_specs = find_camera()
50
+ if self.cap is None or self.camera_specs is None:
51
+ raise RuntimeError("Camera not found")
52
+
53
+ self._resolution = self.camera_specs.default_resolution
54
+ if self._resolution is None:
55
+ raise RuntimeError("Failed to get default camera resolution.")
56
+
57
+ self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self._resolution.value[0])
58
+ self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self._resolution.value[1])
59
+
60
+ self.resized_K = self.camera_specs.K
61
+
62
+ if not self.cap.isOpened():
63
+ raise RuntimeError("Failed to open camera")
64
+
65
+ def read(self) -> Optional[npt.NDArray[np.uint8]]:
66
+ """Read a frame from the camera.
67
+
68
+ Returns:
69
+ The frame as a uint8 numpy array, or None if no frame could be read.
70
+
71
+ Raises:
72
+ RuntimeError: If the camera is not opened.
73
+
74
+ """
75
+ if self.cap is None:
76
+ raise RuntimeError("Camera is not opened.")
77
+ ret, frame = self.cap.read()
78
+ if not ret:
79
+ return None
80
+ # Ensure uint8 dtype
81
+ if frame.dtype != np.uint8:
82
+ frame = frame.astype(np.uint8, copy=False)
83
+ return cast(npt.NDArray[np.uint8], frame)
84
+
85
+ def close(self) -> None:
86
+ """Release the camera resource."""
87
+ if self.cap is not None:
88
+ self.cap.release()
89
+ self.cap = None