reachy-mini 1.0.0__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.

Potentially problematic release.


This version of reachy-mini might be problematic. Click here for more details.

Files changed (385) hide show
  1. reachy_mini/__init__.py +4 -0
  2. reachy_mini/apps/__init__.py +24 -0
  3. reachy_mini/apps/app.py +121 -0
  4. reachy_mini/apps/manager.py +183 -0
  5. reachy_mini/apps/sources/__init__.py +4 -0
  6. reachy_mini/apps/sources/hf_space.py +25 -0
  7. reachy_mini/apps/sources/local_common_venv.py +44 -0
  8. reachy_mini/apps/templates/README.md.j2 +1 -0
  9. reachy_mini/apps/templates/main.py.j2 +46 -0
  10. reachy_mini/apps/templates/pyproject.toml.j2 +18 -0
  11. reachy_mini/apps/utils.py +30 -0
  12. reachy_mini/assets/config/hardware_config.yaml +119 -0
  13. reachy_mini/assets/confused1.wav +0 -0
  14. reachy_mini/assets/count.wav +0 -0
  15. reachy_mini/assets/dance1.wav +0 -0
  16. reachy_mini/assets/go_sleep.wav +0 -0
  17. reachy_mini/assets/impatient1.wav +0 -0
  18. reachy_mini/assets/kinematics_data.json +253 -0
  19. reachy_mini/assets/models/fknetwork.dynamic.onnx +0 -0
  20. reachy_mini/assets/models/fknetwork.onnx +0 -0
  21. reachy_mini/assets/models/fknetwork_int8.onnx +0 -0
  22. reachy_mini/assets/models/iknetwork.onnx +0 -0
  23. reachy_mini/assets/wake_up.wav +0 -0
  24. reachy_mini/daemon/__init__.py +1 -0
  25. reachy_mini/daemon/app/__init__.py +1 -0
  26. reachy_mini/daemon/app/bg_job_register.py +142 -0
  27. reachy_mini/daemon/app/dashboard/static/assets/KO-cartoon-static.svg +40 -0
  28. reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon-static.svg +42 -0
  29. reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon.svg +6 -0
  30. reachy_mini/daemon/app/dashboard/static/assets/go-to-sleep-cartoon.svg +6 -0
  31. reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon-static.svg +50 -0
  32. reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon.svg +6 -0
  33. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-awake.svg +18 -0
  34. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-connection-lost-animation.svg +6 -0
  35. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-go-to-sleep-animation.svg +6 -0
  36. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko-animation.svg +6 -0
  37. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko.svg +22 -0
  38. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping-static.svg +41 -0
  39. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping.svg +18 -0
  40. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-wake-up-animation.svg +6 -0
  41. reachy_mini/daemon/app/dashboard/static/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
  42. reachy_mini/daemon/app/dashboard/static/js/apps.js +304 -0
  43. reachy_mini/daemon/app/dashboard/static/js/appstore.js +150 -0
  44. reachy_mini/daemon/app/dashboard/static/js/daemon.js +163 -0
  45. reachy_mini/daemon/app/dashboard/static/js/move_player.js +132 -0
  46. reachy_mini/daemon/app/dashboard/static/js/setup_wifi.js +94 -0
  47. reachy_mini/daemon/app/dashboard/static/js/update.js +80 -0
  48. reachy_mini/daemon/app/dashboard/static/style.css +83 -0
  49. reachy_mini/daemon/app/dashboard/templates/base.html +23 -0
  50. reachy_mini/daemon/app/dashboard/templates/index.html +17 -0
  51. reachy_mini/daemon/app/dashboard/templates/sections/apps.html +8 -0
  52. reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +29 -0
  53. reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +36 -0
  54. reachy_mini/daemon/app/dashboard/templates/sections/move_player.html +27 -0
  55. reachy_mini/daemon/app/dashboard/update.html +22 -0
  56. reachy_mini/daemon/app/dashboard/wifi_config.html +41 -0
  57. reachy_mini/daemon/app/dependencies.py +41 -0
  58. reachy_mini/daemon/app/main.py +262 -0
  59. reachy_mini/daemon/app/models.py +147 -0
  60. reachy_mini/daemon/app/routers/apps.py +114 -0
  61. reachy_mini/daemon/app/routers/daemon.py +80 -0
  62. reachy_mini/daemon/app/routers/kinematics.py +57 -0
  63. reachy_mini/daemon/app/routers/motors.py +41 -0
  64. reachy_mini/daemon/app/routers/move.py +257 -0
  65. reachy_mini/daemon/app/routers/state.py +146 -0
  66. reachy_mini/daemon/backend/__init__.py +1 -0
  67. reachy_mini/daemon/backend/abstract.py +750 -0
  68. reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
  69. reachy_mini/daemon/backend/mujoco/backend.py +304 -0
  70. reachy_mini/daemon/backend/mujoco/utils.py +59 -0
  71. reachy_mini/daemon/backend/mujoco/video_udp.py +53 -0
  72. reachy_mini/daemon/backend/robot/__init__.py +8 -0
  73. reachy_mini/daemon/backend/robot/backend.py +535 -0
  74. reachy_mini/daemon/daemon.py +444 -0
  75. reachy_mini/daemon/utils.py +114 -0
  76. reachy_mini/descriptions/reachy_mini/mjcf/additional.xml +6 -0
  77. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.part +13 -0
  78. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.stl +0 -0
  79. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.part +13 -0
  80. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.stl +0 -0
  81. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.part +13 -0
  82. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.stl +0 -0
  83. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.part +13 -0
  84. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.stl +0 -0
  85. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.part +13 -0
  86. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.stl +0 -0
  87. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.part +13 -0
  88. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.stl +0 -0
  89. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.part +13 -0
  90. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.stl +0 -0
  91. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.part +13 -0
  92. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.stl +0 -0
  93. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.part +13 -0
  94. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.stl +0 -0
  95. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.part +13 -0
  96. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.stl +0 -0
  97. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.part +13 -0
  98. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.stl +0 -0
  99. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.part +13 -0
  100. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.stl +0 -0
  101. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.part +13 -0
  102. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.stl +0 -0
  103. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.part +13 -0
  104. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.stl +0 -0
  105. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.part +13 -0
  106. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.stl +0 -0
  107. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.part +13 -0
  108. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.stl +0 -0
  109. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/croissant_1k.obj +5021 -0
  110. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/textures/croissant_diff_1k.png +0 -0
  111. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.part +13 -0
  112. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.stl +0 -0
  113. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.part +13 -0
  114. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.stl +0 -0
  115. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.part +13 -0
  116. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.stl +0 -0
  117. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.part +13 -0
  118. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.stl +0 -0
  119. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  120. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
  121. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/food_apple_01_1k.obj +18045 -0
  122. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/textures/food_apple_01_diff_1k.png +0 -0
  123. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.part +13 -0
  124. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.stl +0 -0
  125. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.part +13 -0
  126. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.stl +0 -0
  127. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.part +13 -0
  128. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.stl +0 -0
  129. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.part +13 -0
  130. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.stl +0 -0
  131. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.part +13 -0
  132. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.stl +0 -0
  133. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.part +13 -0
  134. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.stl +0 -0
  135. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  136. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
  137. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.part +13 -0
  138. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.stl +0 -0
  139. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.part +13 -0
  140. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.stl +0 -0
  141. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.part +13 -0
  142. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.stl +0 -0
  143. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  144. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
  145. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  146. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
  147. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  148. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
  149. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.part +13 -0
  150. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.stl +0 -0
  151. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/rubber_duck_toy_1k.obj +8940 -0
  152. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/textures/rubber_duck_toy_diff_1k.png +0 -0
  153. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.part +13 -0
  154. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.stl +0 -0
  155. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.part +13 -0
  156. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.stl +0 -0
  157. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.part +13 -0
  158. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.stl +0 -0
  159. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.part +13 -0
  160. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.stl +0 -0
  161. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.part +13 -0
  162. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.stl +0 -0
  163. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.part +13 -0
  164. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.stl +0 -0
  165. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/textures/wooden_table_02_diff_1k.png +0 -0
  166. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/wooden_table_02_1k.obj +485 -0
  167. reachy_mini/descriptions/reachy_mini/mjcf/config.json +21 -0
  168. reachy_mini/descriptions/reachy_mini/mjcf/joints_properties.xml +29 -0
  169. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml +613 -0
  170. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml.bak +442 -0
  171. reachy_mini/descriptions/reachy_mini/mjcf/scene.xml +24 -0
  172. reachy_mini/descriptions/reachy_mini/mjcf/scenes/empty.xml +27 -0
  173. reachy_mini/descriptions/reachy_mini/mjcf/scenes/minimal.xml +131 -0
  174. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.part +13 -0
  175. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.stl +0 -0
  176. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.part +13 -0
  177. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.stl +0 -0
  178. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.part +13 -0
  179. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.stl +0 -0
  180. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.part +13 -0
  181. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.stl +0 -0
  182. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.part +13 -0
  183. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.stl +0 -0
  184. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.part +13 -0
  185. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.stl +0 -0
  186. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.part +13 -0
  187. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.stl +0 -0
  188. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.part +13 -0
  189. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.stl +0 -0
  190. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.part +13 -0
  191. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.stl +0 -0
  192. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.part +13 -0
  193. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.stl +0 -0
  194. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.part +13 -0
  195. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.stl +0 -0
  196. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.part +13 -0
  197. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.stl +0 -0
  198. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.part +13 -0
  199. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.stl +0 -0
  200. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.part +13 -0
  201. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.stl +0 -0
  202. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.part +13 -0
  203. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.stl +0 -0
  204. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.part +13 -0
  205. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.stl +0 -0
  206. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.part +13 -0
  207. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.stl +0 -0
  208. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.part +13 -0
  209. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.stl +0 -0
  210. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.part +13 -0
  211. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.stl +0 -0
  212. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.part +13 -0
  213. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.stl +0 -0
  214. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.part +13 -0
  215. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.stl +0 -0
  216. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.part +13 -0
  217. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.stl +0 -0
  218. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.part +13 -0
  219. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.stl +0 -0
  220. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.part +13 -0
  221. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.stl +0 -0
  222. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  223. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
  224. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.part +14 -0
  225. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.stl +0 -0
  226. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.part +14 -0
  227. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.stl +0 -0
  228. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.part +13 -0
  229. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.stl +0 -0
  230. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.part +13 -0
  231. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.stl +0 -0
  232. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.part +13 -0
  233. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.stl +0 -0
  234. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.part +13 -0
  235. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.stl +0 -0
  236. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.part +13 -0
  237. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.stl +0 -0
  238. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.part +13 -0
  239. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.stl +0 -0
  240. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.part +13 -0
  241. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.stl +0 -0
  242. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.part +13 -0
  243. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.stl +0 -0
  244. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.part +13 -0
  245. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.stl +0 -0
  246. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.part +13 -0
  247. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.stl +0 -0
  248. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.part +13 -0
  249. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.stl +0 -0
  250. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  251. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
  252. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.part +13 -0
  253. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.stl +0 -0
  254. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.part +13 -0
  255. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.stl +0 -0
  256. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.part +13 -0
  257. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.stl +0 -0
  258. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.part +13 -0
  259. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.stl +0 -0
  260. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.part +13 -0
  261. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.stl +0 -0
  262. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.part +13 -0
  263. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.stl +0 -0
  264. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  265. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
  266. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  267. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
  268. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  269. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
  270. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.part +13 -0
  271. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.stl +0 -0
  272. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.part +13 -0
  273. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.stl +0 -0
  274. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.part +13 -0
  275. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.stl +0 -0
  276. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.part +13 -0
  277. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.stl +0 -0
  278. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.part +13 -0
  279. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.stl +0 -0
  280. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.part +13 -0
  281. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.stl +0 -0
  282. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.part +13 -0
  283. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.stl +0 -0
  284. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.part +13 -0
  285. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.stl +0 -0
  286. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.part +13 -0
  287. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.stl +0 -0
  288. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.part +13 -0
  289. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.stl +0 -0
  290. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.part +13 -0
  291. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.stl +0 -0
  292. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.part +13 -0
  293. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.stl +0 -0
  294. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.part +13 -0
  295. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.stl +0 -0
  296. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.part +13 -0
  297. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.stl +0 -0
  298. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.part +13 -0
  299. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.stl +0 -0
  300. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.part +13 -0
  301. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.stl +0 -0
  302. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.part +13 -0
  303. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.stl +0 -0
  304. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.part +13 -0
  305. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.stl +0 -0
  306. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.part +13 -0
  307. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.stl +0 -0
  308. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.part +13 -0
  309. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.stl +0 -0
  310. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.part +13 -0
  311. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.stl +0 -0
  312. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.part +13 -0
  313. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.stl +0 -0
  314. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.part +13 -0
  315. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.stl +0 -0
  316. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.part +13 -0
  317. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.stl +0 -0
  318. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.part +13 -0
  319. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.stl +0 -0
  320. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.part +13 -0
  321. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.stl +0 -0
  322. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.part +13 -0
  323. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.stl +0 -0
  324. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.part +13 -0
  325. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.stl +0 -0
  326. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.part +13 -0
  327. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.stl +0 -0
  328. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.part +13 -0
  329. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.stl +0 -0
  330. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.part +13 -0
  331. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.stl +0 -0
  332. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.part +13 -0
  333. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.stl +0 -0
  334. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.part +14 -0
  335. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.stl +0 -0
  336. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.part +14 -0
  337. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.stl +0 -0
  338. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.part +14 -0
  339. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.stl +0 -0
  340. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.part +14 -0
  341. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.stl +0 -0
  342. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.part +14 -0
  343. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.stl +0 -0
  344. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.part +14 -0
  345. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.stl +0 -0
  346. reachy_mini/descriptions/reachy_mini/urdf/config.json +18 -0
  347. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf +3281 -0
  348. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf.bak +3282 -0
  349. reachy_mini/descriptions/reachy_mini/urdf/robot_no_collision.urdf +2316 -0
  350. reachy_mini/io/__init__.py +1 -0
  351. reachy_mini/io/abstract.py +70 -0
  352. reachy_mini/io/protocol.py +44 -0
  353. reachy_mini/io/zenoh_client.py +258 -0
  354. reachy_mini/io/zenoh_server.py +183 -0
  355. reachy_mini/kinematics/__init__.py +68 -0
  356. reachy_mini/kinematics/analytical_kinematics.py +102 -0
  357. reachy_mini/kinematics/nn_kinematics.py +100 -0
  358. reachy_mini/kinematics/placo_kinematics.py +666 -0
  359. reachy_mini/media/__init__.py +1 -0
  360. reachy_mini/media/audio_base.py +163 -0
  361. reachy_mini/media/audio_gstreamer.py +195 -0
  362. reachy_mini/media/audio_sounddevice.py +226 -0
  363. reachy_mini/media/audio_utils.py +27 -0
  364. reachy_mini/media/camera_base.py +63 -0
  365. reachy_mini/media/camera_constants.py +13 -0
  366. reachy_mini/media/camera_gstreamer.py +162 -0
  367. reachy_mini/media/camera_opencv.py +61 -0
  368. reachy_mini/media/camera_utils.py +60 -0
  369. reachy_mini/media/media_manager.py +194 -0
  370. reachy_mini/motion/__init__.py +4 -0
  371. reachy_mini/motion/goto.py +71 -0
  372. reachy_mini/motion/move.py +36 -0
  373. reachy_mini/motion/recorded_move.py +132 -0
  374. reachy_mini/reachy_mini.py +705 -0
  375. reachy_mini/utils/__init__.py +46 -0
  376. reachy_mini/utils/constants.py +9 -0
  377. reachy_mini/utils/interpolation.py +227 -0
  378. reachy_mini/utils/parse_urdf_for_kinematics.py +110 -0
  379. reachy_mini/utils/rerun.py +546 -0
  380. reachy_mini-1.0.0.dist-info/METADATA +286 -0
  381. reachy_mini-1.0.0.dist-info/RECORD +385 -0
  382. reachy_mini-1.0.0.dist-info/WHEEL +5 -0
  383. reachy_mini-1.0.0.dist-info/entry_points.txt +3 -0
  384. reachy_mini-1.0.0.dist-info/licenses/LICENSE +201 -0
  385. reachy_mini-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,162 @@
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
+ from threading import Thread
8
+ from typing import Optional
9
+
10
+ import numpy as np
11
+ import numpy.typing as npt
12
+
13
+ from reachy_mini.media.camera_constants import CameraResolution
14
+
15
+ from .camera_base import CameraBackend, CameraBase
16
+
17
+ try:
18
+ import gi
19
+ except ImportError as e:
20
+ raise ImportError(
21
+ "The 'gi' module is required for GStreamerCamera but could not be imported. \
22
+ Please install the GStreamer backend: pip install .[gstreamer]."
23
+ ) from e
24
+
25
+ gi.require_version("Gst", "1.0")
26
+ gi.require_version("GstApp", "1.0")
27
+
28
+
29
+ from gi.repository import GLib, Gst, GstApp # noqa: E402
30
+
31
+
32
+ class GStreamerCamera(CameraBase):
33
+ """Camera implementation using GStreamer."""
34
+
35
+ def __init__(
36
+ self,
37
+ log_level: str = "INFO",
38
+ resolution: CameraResolution = CameraResolution.R1280x720,
39
+ ) -> None:
40
+ """Initialize the GStreamer camera."""
41
+ super().__init__(
42
+ backend=CameraBackend.GSTREAMER, log_level=log_level, resolution=resolution
43
+ )
44
+ Gst.init(None)
45
+ self._loop = GLib.MainLoop()
46
+ self._thread_bus_calls: Optional[Thread] = None
47
+
48
+ self.pipeline = Gst.Pipeline.new("camera_recorder")
49
+
50
+ # note for some applications the jpeg image could be directly used
51
+ self._appsink_video: GstApp = Gst.ElementFactory.make("appsink")
52
+ caps_video = Gst.Caps.from_string(
53
+ f"video/x-raw,format=BGR, width={self.resolution[0]},height={self.resolution[1]},framerate={self.framerate}/1"
54
+ )
55
+ self._appsink_video.set_property("caps", caps_video)
56
+ self._appsink_video.set_property("drop", True) # avoid overflow
57
+ self._appsink_video.set_property("max-buffers", 1) # keep last image only
58
+ self.pipeline.add(self._appsink_video)
59
+
60
+ cam_path = self.get_arducam_video_device()
61
+ if cam_path == "":
62
+ self.logger.warning("Recording pipeline set without camera.")
63
+ self.pipeline.remove(self._appsink_video)
64
+ else:
65
+ camsrc = Gst.ElementFactory.make("v4l2src")
66
+ camsrc.set_property("device", cam_path)
67
+ self.pipeline.add(camsrc)
68
+ queue = Gst.ElementFactory.make("queue")
69
+ self.pipeline.add(queue)
70
+ # use vaapijpegdec or nvjpegdec for hardware acceleration
71
+ jpegdec = Gst.ElementFactory.make("jpegdec")
72
+ self.pipeline.add(jpegdec)
73
+ videoconvert = Gst.ElementFactory.make("videoconvert")
74
+ self.pipeline.add(videoconvert)
75
+ camsrc.link(queue)
76
+ queue.link(jpegdec)
77
+ jpegdec.link(videoconvert)
78
+ videoconvert.link(self._appsink_video)
79
+
80
+ def _on_bus_message(self, bus: Gst.Bus, msg: Gst.Message, loop) -> bool: # type: ignore[no-untyped-def]
81
+ t = msg.type
82
+ if t == Gst.MessageType.EOS:
83
+ self.logger.warning("End-of-stream")
84
+ return False
85
+
86
+ elif t == Gst.MessageType.ERROR:
87
+ err, debug = msg.parse_error()
88
+ self.logger.error(f"Error: {err} {debug}")
89
+ return False
90
+
91
+ return True
92
+
93
+ def _handle_bus_calls(self) -> None:
94
+ self.logger.debug("starting bus message loop")
95
+ bus = self.pipeline.get_bus()
96
+ bus.add_watch(GLib.PRIORITY_DEFAULT, self._on_bus_message, self._loop)
97
+ self._loop.run()
98
+ bus.remove_watch()
99
+ self.logger.debug("bus message loop stopped")
100
+
101
+ def open(self) -> None:
102
+ """Open the camera using GStreamer."""
103
+ self.pipeline.set_state(Gst.State.PLAYING)
104
+ self._thread_bus_calls = Thread(target=self._handle_bus_calls, daemon=True)
105
+ self._thread_bus_calls.start()
106
+
107
+ def _get_sample(self, appsink: GstApp.AppSink) -> Optional[bytes]:
108
+ sample = appsink.try_pull_sample(20_000_000)
109
+ if sample is None:
110
+ return None
111
+ data = None
112
+ if isinstance(sample, Gst.Sample):
113
+ buf = sample.get_buffer()
114
+ if buf is None:
115
+ self.logger.warning("Buffer is None")
116
+
117
+ data = buf.extract_dup(0, buf.get_size())
118
+ return data
119
+
120
+ def read(self) -> Optional[npt.NDArray[np.uint8]]:
121
+ """Read a frame from the camera. Returns the frame or None if error.
122
+
123
+ Returns:
124
+ Optional[npt.NDArray[np.uint8]]: The captured BGR frame as a NumPy array, or None if error.
125
+
126
+ """
127
+ data = self._get_sample(self._appsink_video)
128
+ if data is None:
129
+ return None
130
+
131
+ arr = np.frombuffer(data, dtype=np.uint8).reshape(
132
+ (self.resolution[1], self.resolution[0], 3)
133
+ )
134
+ return arr
135
+
136
+ def close(self) -> None:
137
+ """Release the camera resource."""
138
+ self._loop.quit()
139
+ self.pipeline.set_state(Gst.State.NULL)
140
+
141
+ def get_arducam_video_device(self) -> str:
142
+ """Use Gst.DeviceMonitor to find the unix camera path /dev/videoX of the Arducam_12MP webcam.
143
+
144
+ Returns the device path (e.g., '/dev/video2'), or '' if not found.
145
+ """
146
+ monitor = Gst.DeviceMonitor()
147
+ monitor.add_filter("Video/Source")
148
+ monitor.start()
149
+
150
+ devices = monitor.get_devices()
151
+ for device in devices:
152
+ name = device.get_display_name()
153
+ device_props = device.get_properties()
154
+ if name and "Arducam_12MP" in name:
155
+ if device_props and device_props.has_field("api.v4l2.path"):
156
+ device_path = device_props.get_string("api.v4l2.path")
157
+ self.logger.debug(f"Found Arducam_12MP at {device_path}")
158
+ monitor.stop()
159
+ return str(device_path)
160
+ monitor.stop()
161
+ self.logger.warning("Arducam_12MP webcam not found.")
162
+ return ""
@@ -0,0 +1,61 @@
1
+ """OpenCv camera backend.
2
+
3
+ This module provides an implementation of the CameraBase class using OpenCV.
4
+ """
5
+
6
+ from typing import Optional
7
+
8
+ import cv2
9
+ import numpy as np
10
+ import numpy.typing as npt
11
+
12
+ from reachy_mini.media.camera_constants import CameraResolution
13
+ from reachy_mini.media.camera_utils import find_camera
14
+
15
+ from .camera_base import CameraBackend, CameraBase
16
+
17
+
18
+ class OpenCVCamera(CameraBase):
19
+ """Camera implementation using OpenCV."""
20
+
21
+ def __init__(
22
+ self,
23
+ log_level: str = "INFO",
24
+ resolution: CameraResolution = CameraResolution.R1280x720,
25
+ ) -> None:
26
+ """Initialize the OpenCV camera."""
27
+ super().__init__(
28
+ backend=CameraBackend.OPENCV, log_level=log_level, resolution=resolution
29
+ )
30
+ self.cap: Optional[cv2.VideoCapture] = None
31
+
32
+ def open(self, udp_camera: Optional[str] = None) -> None:
33
+ """Open the camera using OpenCV VideoCapture."""
34
+ if udp_camera:
35
+ self.cap = cv2.VideoCapture(udp_camera)
36
+ else:
37
+ self.cap = find_camera()
38
+ if self.cap is None:
39
+ raise RuntimeError("Camera not found")
40
+ self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.resolution[0])
41
+ self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.resolution[1])
42
+
43
+ if not self.cap.isOpened():
44
+ raise RuntimeError("Failed to open camera")
45
+
46
+ def read(self) -> Optional[npt.NDArray[np.uint8]]:
47
+ """Read a frame from the camera. Returns the frame or None if error."""
48
+ if self.cap is None:
49
+ raise RuntimeError("Camera is not opened.")
50
+
51
+ ret, frame = self.cap.read()
52
+ if not ret:
53
+ return None
54
+
55
+ return np.asarray(frame, dtype=np.uint8, copy=False)
56
+
57
+ def close(self) -> None:
58
+ """Release the camera resource."""
59
+ if self.cap is not None:
60
+ self.cap.release()
61
+ self.cap = None
@@ -0,0 +1,60 @@
1
+ """Camera utility for Reachy Mini."""
2
+
3
+ import platform
4
+
5
+ import cv2
6
+ from cv2_enumerate_cameras import enumerate_cameras
7
+
8
+
9
+ def find_camera(
10
+ vid: int = 0x0C45,
11
+ pid: int = 0x636D,
12
+ apiPreference: int = cv2.CAP_ANY,
13
+ ) -> cv2.VideoCapture | None:
14
+ """Find and return a camera with the specified VID and PID.
15
+
16
+ Args:
17
+ vid (int): Vendor ID of the camera. Default is 0x0C45 (Arducam).
18
+ pid (int): Product ID of the camera. Default is 0x636D (Arducam).
19
+ apiPreference (int): Preferred API backend for the camera. Default is cv2.CAP_ANY.
20
+
21
+ Returns:
22
+ cv2.VideoCapture | None: A VideoCapture object if the camera is found and opened successfully, otherwise None.
23
+
24
+ """
25
+ if platform.system() == "Linux":
26
+ apiPreference = cv2.CAP_V4L2
27
+
28
+ selected_cap = None
29
+ for c in enumerate_cameras(apiPreference):
30
+ if c.vid == vid and c.pid == pid:
31
+ # the Arducam camera creates two /dev/videoX devices
32
+ # that enumerate_cameras cannot differentiate
33
+ try:
34
+ cap = cv2.VideoCapture(c.index, c.backend)
35
+ if cap.isOpened():
36
+ selected_cap = cap
37
+ except Exception as e:
38
+ print(f"Error opening camera {c.index}: {e}")
39
+ return selected_cap
40
+
41
+
42
+ if __name__ == "__main__":
43
+ from reachy_mini.media.camera_constants import CameraResolution
44
+
45
+ cam = find_camera()
46
+
47
+ if cam is None:
48
+ print("Camera not found")
49
+ else:
50
+ cam.set(cv2.CAP_PROP_FRAME_WIDTH, CameraResolution.R1280x720.value[0])
51
+ cam.set(cv2.CAP_PROP_FRAME_HEIGHT, CameraResolution.R1280x720.value[1])
52
+
53
+ while True:
54
+ ret, frame = cam.read()
55
+ if not ret:
56
+ print("Failed to grab frame")
57
+ break
58
+ cv2.imshow("Camera Feed", frame)
59
+ if cv2.waitKey(1) & 0xFF == ord("q"):
60
+ break
@@ -0,0 +1,194 @@
1
+ """Media Manager.
2
+
3
+ Provides camera and audio access based on the selected backedn
4
+ """
5
+
6
+ import logging
7
+ from enum import Enum
8
+ from typing import Optional
9
+
10
+ import numpy as np
11
+ import numpy.typing as npt
12
+
13
+ from reachy_mini.media.audio_base import AudioBase
14
+ from reachy_mini.media.camera_base import CameraBase
15
+ from reachy_mini.media.camera_constants import CameraResolution
16
+
17
+ # actual backends are dynamically imported
18
+
19
+
20
+ class MediaBackend(Enum):
21
+ """Media backends."""
22
+
23
+ NO_MEDIA = "no_media"
24
+ DEFAULT = "default"
25
+ DEFAULT_NO_VIDEO = "default_no_video"
26
+ GSTREAMER = "gstreamer"
27
+
28
+
29
+ class MediaManager:
30
+ """Abstract class for opening and managing audio devices."""
31
+
32
+ def __init__(
33
+ self,
34
+ backend: MediaBackend = MediaBackend.DEFAULT,
35
+ log_level: str = "INFO",
36
+ use_sim: bool = False,
37
+ resolution: CameraResolution = CameraResolution.R1280x720,
38
+ ) -> None:
39
+ """Initialize the audio device."""
40
+ self.logger = logging.getLogger(__name__)
41
+ self.logger.setLevel(log_level)
42
+ self.backend = backend
43
+ self.camera: Optional[CameraBase] = None
44
+ if (
45
+ not backend == MediaBackend.DEFAULT_NO_VIDEO
46
+ and not backend == MediaBackend.NO_MEDIA
47
+ ):
48
+ self._init_camera(use_sim, log_level, resolution)
49
+ self.audio: Optional[AudioBase] = None
50
+ if not backend == MediaBackend.NO_MEDIA:
51
+ self._init_audio(log_level)
52
+
53
+ def __del__(self) -> None:
54
+ """Destructor to ensure resources are released."""
55
+ if self.camera is not None:
56
+ self.camera.close()
57
+ if self.audio is not None:
58
+ self.audio.stop_recording()
59
+ self.audio.stop_playing()
60
+
61
+ def _init_camera(
62
+ self,
63
+ use_sim: bool,
64
+ log_level: str,
65
+ resolution: CameraResolution,
66
+ ) -> None:
67
+ """Initialize the camera."""
68
+ self.logger.debug("Initializing camera...")
69
+ if self.backend == MediaBackend.DEFAULT:
70
+ self.logger.info("Using OpenCV camera backend.")
71
+ from reachy_mini.media.camera_opencv import OpenCVCamera
72
+
73
+ self.camera = OpenCVCamera(log_level=log_level, resolution=resolution)
74
+ if use_sim:
75
+ self.camera.open(udp_camera="udp://@127.0.0.1:5005")
76
+ else:
77
+ self.camera.open()
78
+ elif self.backend == MediaBackend.GSTREAMER:
79
+ self.logger.info("Using GStreamer camera backend.")
80
+ from reachy_mini.media.camera_gstreamer import GStreamerCamera
81
+
82
+ self.camera = GStreamerCamera(log_level=log_level, resolution=resolution)
83
+ self.camera.open()
84
+ # Todo: use simulation with gstreamer?
85
+
86
+ else:
87
+ raise NotImplementedError(f"Camera backend {self.backend} not implemented.")
88
+
89
+ def get_frame(self) -> Optional[npt.NDArray[np.uint8]]:
90
+ """Get a frame from the camera.
91
+
92
+ Returns:
93
+ Optional[npt.NDArray[np.uint8]]: The captured BGR frame, or None if the camera is not available.
94
+
95
+ """
96
+ if self.camera is None:
97
+ self.logger.warning("Camera is not initialized.")
98
+ return None
99
+ return self.camera.read()
100
+
101
+ def _init_audio(self, log_level: str) -> None:
102
+ """Initialize the audio system."""
103
+ self.logger.debug("Initializing audio...")
104
+ if (
105
+ self.backend == MediaBackend.DEFAULT
106
+ or self.backend == MediaBackend.DEFAULT_NO_VIDEO
107
+ ):
108
+ self.logger.info("Using SoundDevice audio backend.")
109
+ from reachy_mini.media.audio_sounddevice import SoundDeviceAudio
110
+
111
+ self.audio = SoundDeviceAudio(log_level=log_level)
112
+ elif self.backend == MediaBackend.GSTREAMER:
113
+ self.logger.info("Using GStreamer audio backend.")
114
+ from reachy_mini.media.audio_gstreamer import GStreamerAudio
115
+
116
+ self.audio = GStreamerAudio(log_level=log_level)
117
+ else:
118
+ raise NotImplementedError(f"Audio backend {self.backend} not implemented.")
119
+
120
+ def play_sound(self, sound_file: str) -> None:
121
+ """Play a sound file.
122
+
123
+ Args:
124
+ sound_file (str): Path to the sound file to play.
125
+
126
+ """
127
+ if self.audio is None:
128
+ self.logger.warning("Audio system is not initialized.")
129
+ return
130
+ self.audio.play_sound(sound_file)
131
+
132
+ def start_recording(self) -> None:
133
+ """Start recording audio."""
134
+ if self.audio is None:
135
+ self.logger.warning("Audio system is not initialized.")
136
+ return
137
+ self.audio.start_recording()
138
+
139
+ def get_audio_sample(self) -> Optional[bytes | npt.NDArray[np.float32]]:
140
+ """Get an audio sample from the audio device.
141
+
142
+ Returns:
143
+ Optional[np.ndarray]: The recorded audio sample, or None if no data is available.
144
+
145
+ """
146
+ if self.audio is None:
147
+ self.logger.warning("Audio system is not initialized.")
148
+ return None
149
+ return self.audio.get_audio_sample()
150
+
151
+ def get_audio_samplerate(self) -> int:
152
+ """Get the samplerate of the audio device.
153
+
154
+ Returns:
155
+ int: The samplerate of the audio device.
156
+
157
+ """
158
+ if self.audio is None:
159
+ self.logger.warning("Audio system is not initialized.")
160
+ return -1
161
+ return self.audio.SAMPLE_RATE
162
+
163
+ def stop_recording(self) -> None:
164
+ """Stop recording audio."""
165
+ if self.audio is None:
166
+ self.logger.warning("Audio system is not initialized.")
167
+ return
168
+ self.audio.stop_recording()
169
+
170
+ def start_playing(self) -> None:
171
+ """Start playing audio."""
172
+ if self.audio is None:
173
+ self.logger.warning("Audio system is not initialized.")
174
+ return
175
+ self.audio.start_playing()
176
+
177
+ def push_audio_sample(self, data: npt.NDArray[np.float32]) -> None:
178
+ """Push audio data to the output device.
179
+
180
+ Args:
181
+ data (npt.NDArray[np.float32]): The audio data to push to the output device (mono format).
182
+
183
+ """
184
+ if self.audio is None:
185
+ self.logger.warning("Audio system is not initialized.")
186
+ return
187
+ self.audio.push_audio_sample(data)
188
+
189
+ def stop_playing(self) -> None:
190
+ """Stop playing audio."""
191
+ if self.audio is None:
192
+ self.logger.warning("Audio system is not initialized.")
193
+ return
194
+ self.audio.stop_playing()
@@ -0,0 +1,4 @@
1
+ """Motion module for Reachy Mini.
2
+
3
+ This module contains both utilities to create and play moves, as well as utilities to download datasets of recorded moves.
4
+ """
@@ -0,0 +1,71 @@
1
+ """A goto move to a target head pose and/or antennas position."""
2
+
3
+ import numpy as np
4
+ import numpy.typing as npt
5
+
6
+ from reachy_mini.utils.interpolation import (
7
+ InterpolationTechnique,
8
+ linear_pose_interpolation,
9
+ time_trajectory,
10
+ )
11
+
12
+ from .move import Move
13
+
14
+
15
+ class GotoMove(Move):
16
+ """A goto move to a target head pose and/or antennas position."""
17
+
18
+ def __init__(
19
+ self,
20
+ start_head_pose: npt.NDArray[np.float64],
21
+ target_head_pose: npt.NDArray[np.float64] | None,
22
+ start_antennas: npt.NDArray[np.float64],
23
+ target_antennas: npt.NDArray[np.float64] | None,
24
+ start_body_yaw: float,
25
+ target_body_yaw: float | None,
26
+ duration: float,
27
+ method: InterpolationTechnique,
28
+ ):
29
+ """Set up the goto move."""
30
+ self.start_head_pose = start_head_pose
31
+ self.target_head_pose = (
32
+ target_head_pose if target_head_pose is not None else start_head_pose
33
+ )
34
+ self.start_antennas = start_antennas
35
+ self.target_antennas = (
36
+ target_antennas if target_antennas is not None else start_antennas
37
+ )
38
+ self.start_body_yaw = start_body_yaw
39
+ self.target_body_yaw = (
40
+ target_body_yaw if target_body_yaw is not None else start_body_yaw
41
+ )
42
+
43
+ self._duration = duration
44
+ self.method = method
45
+
46
+ @property
47
+ def duration(self) -> float:
48
+ """Duration of the goto in seconds."""
49
+ return self._duration
50
+
51
+ def evaluate(
52
+ self, t: float
53
+ ) -> tuple[
54
+ npt.NDArray[np.float64] | None, npt.NDArray[np.float64] | None, float | None
55
+ ]:
56
+ """Evaluate the goto at time t."""
57
+ interp_time = time_trajectory(t / self.duration, method=self.method)
58
+
59
+ interp_head_pose = linear_pose_interpolation(
60
+ self.start_head_pose, self.target_head_pose, interp_time
61
+ )
62
+ interp_antennas_joint = (
63
+ self.start_antennas
64
+ + (self.target_antennas - self.start_antennas) * interp_time
65
+ )
66
+ interp_body_yaw_joint = (
67
+ self.start_body_yaw
68
+ + (self.target_body_yaw - self.start_body_yaw) * interp_time
69
+ )
70
+
71
+ return interp_head_pose, interp_antennas_joint, interp_body_yaw_joint
@@ -0,0 +1,36 @@
1
+ """Module for defining motion moves on the ReachyMini robot."""
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+ import numpy as np
6
+ import numpy.typing as npt
7
+
8
+
9
+ class Move(ABC):
10
+ """Abstract base class for defining a move on the ReachyMini robot."""
11
+
12
+ @property
13
+ @abstractmethod
14
+ def duration(self) -> float:
15
+ """Duration of the move in seconds."""
16
+ pass
17
+
18
+ @abstractmethod
19
+ def evaluate(
20
+ self,
21
+ t: float,
22
+ ) -> tuple[
23
+ npt.NDArray[np.float64] | None, npt.NDArray[np.float64] | None, float | None
24
+ ]:
25
+ """Evaluate the move at time t, typically called at a high-frequency (eg. 100Hz).
26
+
27
+ Arguments:
28
+ t: The time at which to evaluate the move (in seconds). It will always be between 0 and duration.
29
+
30
+ Returns:
31
+ head: The head position (4x4 homogeneous matrix).
32
+ antennas: The antennas positions (rad).
33
+ body_yaw: The body yaw angle (rad).
34
+
35
+ """
36
+ pass