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 @@
1
+ """IO module."""
@@ -0,0 +1,70 @@
1
+ """Base classes for server and client implementations.
2
+
3
+ These abstract classes define the interface for server and client components
4
+ in the Reachy Mini project. They provide methods for starting and stopping
5
+ the server, handling commands, and managing client connections.
6
+ """
7
+
8
+ from abc import ABC, abstractmethod
9
+ from threading import Event
10
+ from uuid import UUID
11
+
12
+ from reachy_mini.io.protocol import AnyTaskRequest
13
+
14
+
15
+ class AbstractServer(ABC):
16
+ """Base class for server implementations."""
17
+
18
+ @abstractmethod
19
+ def start(self) -> None:
20
+ """Start the server."""
21
+ pass
22
+
23
+ @abstractmethod
24
+ def stop(self) -> None:
25
+ """Stop the server."""
26
+ pass
27
+
28
+ @abstractmethod
29
+ def command_received_event(self) -> Event:
30
+ """Wait for a new command and return it."""
31
+ pass
32
+
33
+
34
+ class AbstractClient(ABC):
35
+ """Base class for client implementations."""
36
+
37
+ @abstractmethod
38
+ def wait_for_connection(self) -> None:
39
+ """Wait for the client to connect to the server."""
40
+ pass
41
+
42
+ @abstractmethod
43
+ def is_connected(self) -> bool:
44
+ """Check if the client is connected to the server."""
45
+ pass
46
+
47
+ @abstractmethod
48
+ def disconnect(self) -> None:
49
+ """Disconnect the client from the server."""
50
+ pass
51
+
52
+ @abstractmethod
53
+ def send_command(self, command: str) -> None:
54
+ """Send a command to the server."""
55
+ pass
56
+
57
+ @abstractmethod
58
+ def get_current_joints(self) -> tuple[list[float], list[float]]:
59
+ """Get the current joint positions."""
60
+ pass
61
+
62
+ @abstractmethod
63
+ def send_task_request(self, task_req: AnyTaskRequest) -> UUID:
64
+ """Send a task request to the server and return a unique task identifier."""
65
+ pass
66
+
67
+ @abstractmethod
68
+ def wait_for_task_completion(self, task_uid: UUID, timeout: float = 5.0) -> None:
69
+ """Wait for the specified task to complete."""
70
+ pass
@@ -0,0 +1,44 @@
1
+ """Protocol definitions for Reachy Mini client/server communication."""
2
+
3
+ from datetime import datetime
4
+ from uuid import UUID
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from reachy_mini.utils.interpolation import InterpolationTechnique
9
+
10
+
11
+ class GotoTaskRequest(BaseModel):
12
+ """Class to represent a goto target task."""
13
+
14
+ head: list[float] | None # 4x4 flatten pose matrix
15
+ antennas: list[float] | None # [right_angle, left_angle] (in rads)
16
+ duration: float
17
+ method: InterpolationTechnique
18
+ body_yaw: float | None
19
+
20
+
21
+ class PlayMoveTaskRequest(BaseModel):
22
+ """Class to represent a play move task."""
23
+
24
+ move_name: str
25
+
26
+
27
+ AnyTaskRequest = GotoTaskRequest | PlayMoveTaskRequest
28
+
29
+
30
+ class TaskRequest(BaseModel):
31
+ """Class to represent any task request."""
32
+
33
+ uuid: UUID
34
+ req: AnyTaskRequest
35
+ timestamp: datetime
36
+
37
+
38
+ class TaskProgress(BaseModel):
39
+ """Class to represent task progress."""
40
+
41
+ uuid: UUID
42
+ finished: bool = False
43
+ error: str | None = None
44
+ timestamp: datetime
@@ -0,0 +1,258 @@
1
+ """Zenoh client for Reachy Mini.
2
+
3
+ This module implements a Zenoh client that allows communication with the Reachy Mini
4
+ robot. It subscribes to joint positions updates and allows sending commands to the robot.
5
+ """
6
+
7
+ import json
8
+ import threading
9
+ import time
10
+ from dataclasses import dataclass
11
+ from datetime import datetime
12
+ from typing import Any, Dict, List, Optional
13
+ from uuid import UUID, uuid4
14
+
15
+ import numpy as np
16
+ import numpy.typing as npt
17
+ import zenoh
18
+
19
+ from reachy_mini.io.abstract import AbstractClient
20
+ from reachy_mini.io.protocol import AnyTaskRequest, TaskProgress, TaskRequest
21
+
22
+
23
+ class ZenohClient(AbstractClient):
24
+ """Zenoh client for Reachy Mini."""
25
+
26
+ def __init__(self, localhost_only: bool = True):
27
+ """Initialize the Zenoh client."""
28
+ if localhost_only:
29
+ c = zenoh.Config.from_json5(
30
+ json.dumps(
31
+ {
32
+ "connect": {
33
+ "endpoints": {
34
+ "peer": ["tcp/localhost:7447"],
35
+ "router": [],
36
+ },
37
+ },
38
+ }
39
+ )
40
+ )
41
+ else:
42
+ c = zenoh.Config()
43
+
44
+ self.joint_position_received = threading.Event()
45
+ self.head_pose_received = threading.Event()
46
+ self.status_received = threading.Event()
47
+
48
+ self.session = zenoh.open(c)
49
+ self.cmd_pub = self.session.declare_publisher("reachy_mini/command")
50
+
51
+ self.joint_sub = self.session.declare_subscriber(
52
+ "reachy_mini/joint_positions",
53
+ self._handle_joint_positions,
54
+ )
55
+
56
+ self.pose_sub = self.session.declare_subscriber(
57
+ "reachy_mini/head_pose",
58
+ self._handle_head_pose,
59
+ )
60
+
61
+ self.recording_sub = self.session.declare_subscriber(
62
+ "reachy_mini/recorded_data",
63
+ self._handle_recorded_data,
64
+ )
65
+
66
+ self.status_sub = self.session.declare_subscriber(
67
+ "reachy_mini/daemon_status",
68
+ self._handle_status,
69
+ )
70
+
71
+ self._last_head_joint_positions = None
72
+ self._last_antennas_joint_positions = None
73
+ self._last_head_pose: Optional[npt.NDArray[np.float64]] = None
74
+ self._recorded_data: Optional[
75
+ List[Dict[str, float | List[float] | List[List[float]]]]
76
+ ] = None
77
+ self._recorded_data_ready = threading.Event()
78
+ self._is_alive = False
79
+ self._last_status: Dict[str, Any] = {} # contains a DaemonStatus
80
+
81
+ self.tasks: dict[UUID, TaskState] = {}
82
+ self.task_request_pub = self.session.declare_publisher("reachy_mini/task")
83
+ self.task_progress_sub = self.session.declare_subscriber(
84
+ "reachy_mini/task_progress",
85
+ self._handle_task_progress,
86
+ )
87
+
88
+ def wait_for_connection(self, timeout: float = 5.0) -> None:
89
+ """Wait for the client to connect to the server.
90
+
91
+ Args:
92
+ timeout (float): Maximum time to wait for the connection in seconds.
93
+
94
+ Raises:
95
+ TimeoutError: If the connection is not established within the timeout period.
96
+
97
+ """
98
+ start = time.time()
99
+ while not self.joint_position_received.wait(
100
+ timeout=1.0
101
+ ) or not self.head_pose_received.wait(timeout=1.0):
102
+ if time.time() - start > timeout:
103
+ self.disconnect()
104
+ raise TimeoutError(
105
+ "Timeout while waiting for connection with the server."
106
+ )
107
+ print("Waiting for connection with the server...")
108
+
109
+ self._is_alive = True
110
+ self._check_alive_evt = threading.Event()
111
+ threading.Thread(target=self.check_alive, daemon=True).start()
112
+
113
+ def check_alive(self) -> None:
114
+ """Periodically check if the client is still connected to the server."""
115
+ while True:
116
+ self._is_alive = self.is_connected()
117
+ self._check_alive_evt.set()
118
+ time.sleep(1.0)
119
+
120
+ def is_connected(self) -> bool:
121
+ """Check if the client is connected to the server."""
122
+ self.joint_position_received.clear()
123
+ self.head_pose_received.clear()
124
+ return self.joint_position_received.wait(
125
+ timeout=1.0
126
+ ) and self.head_pose_received.wait(timeout=1.0)
127
+
128
+ def disconnect(self) -> None:
129
+ """Disconnect the client from the server."""
130
+ self.session.close() # type: ignore[no-untyped-call]
131
+
132
+ def send_command(self, command: str) -> None:
133
+ """Send a command to the server."""
134
+ if not self._is_alive:
135
+ raise ConnectionError("Lost connection with the server.")
136
+
137
+ self.cmd_pub.put(command.encode("utf-8"))
138
+
139
+ def _handle_joint_positions(self, sample: zenoh.Sample) -> None:
140
+ """Handle incoming joint positions."""
141
+ if sample.payload:
142
+ positions = json.loads(sample.payload.to_string())
143
+ self._last_head_joint_positions = positions.get("head_joint_positions")
144
+ self._last_antennas_joint_positions = positions.get(
145
+ "antennas_joint_positions"
146
+ )
147
+ self.joint_position_received.set()
148
+
149
+ def _handle_recorded_data(self, sample: zenoh.Sample) -> None:
150
+ """Handle incoming recorded data."""
151
+ print("Received recorded data.")
152
+ if sample.payload:
153
+ data = json.loads(sample.payload.to_string())
154
+ self._recorded_data = data
155
+ self._recorded_data_ready.set()
156
+ if self._recorded_data is not None:
157
+ print(f"Recorded data: {len(self._recorded_data)} frames received.")
158
+
159
+ def _handle_status(self, sample: zenoh.Sample) -> None:
160
+ """Handle incoming status updates."""
161
+ if sample.payload:
162
+ status = json.loads(sample.payload.to_string())
163
+ self._last_status = status
164
+ self.status_received.set()
165
+
166
+ def get_current_joints(self) -> tuple[list[float], list[float]]:
167
+ """Get the current joint positions."""
168
+ assert (
169
+ self._last_head_joint_positions is not None
170
+ and self._last_antennas_joint_positions is not None
171
+ ), "No joint positions received yet. Wait for the client to connect."
172
+ return (
173
+ self._last_head_joint_positions.copy(),
174
+ self._last_antennas_joint_positions.copy(),
175
+ )
176
+
177
+ def wait_for_recorded_data(self, timeout: float = 5.0) -> bool:
178
+ """Block until the daemon publishes the frames (or timeout)."""
179
+ return self._recorded_data_ready.wait(timeout)
180
+
181
+ def get_recorded_data(
182
+ self, wait: bool = True, timeout: float = 5.0
183
+ ) -> Optional[List[Dict[str, float | List[float] | List[List[float]]]]]:
184
+ """Return the cached recording, optionally blocking until it arrives.
185
+
186
+ Raises `TimeoutError` if nothing shows up in time.
187
+ """
188
+ if wait and not self._recorded_data_ready.wait(timeout):
189
+ raise TimeoutError("Recording not received in time.")
190
+ self._recorded_data_ready.clear() # ready for next run
191
+ if self._recorded_data is not None:
192
+ return self._recorded_data.copy()
193
+ return None
194
+
195
+ def get_status(self, wait: bool = True, timeout: float = 5.0) -> Dict[str, Any]:
196
+ """Get the last received status. Returns DaemonStatus as a dict."""
197
+ if wait and not self.status_received.wait(timeout):
198
+ raise TimeoutError("Status not received in time.")
199
+ self.status_received.clear() # ready for next run
200
+ return self._last_status
201
+
202
+ def _handle_head_pose(self, sample: zenoh.Sample) -> None:
203
+ """Handle incoming head pose."""
204
+ if sample.payload:
205
+ pose = json.loads(sample.payload.to_string())
206
+ self._last_head_pose = np.array(pose.get("head_pose")).reshape(4, 4)
207
+ self.head_pose_received.set()
208
+
209
+ def get_current_head_pose(self) -> npt.NDArray[np.float64]:
210
+ """Get the current head pose."""
211
+ assert self._last_head_pose is not None, "No head pose received yet."
212
+ return self._last_head_pose.copy()
213
+
214
+ def send_task_request(self, task_req: AnyTaskRequest) -> UUID:
215
+ """Send a task request to the server."""
216
+ if not self._is_alive:
217
+ raise ConnectionError("Lost connection with the server.")
218
+
219
+ task = TaskRequest(uuid=uuid4(), req=task_req, timestamp=datetime.now())
220
+
221
+ self.tasks[task.uuid] = TaskState(event=threading.Event(), error=None)
222
+
223
+ self.task_request_pub.put(task.model_dump_json())
224
+
225
+ return task.uuid
226
+
227
+ def wait_for_task_completion(self, task_uid: UUID, timeout: float = 5.0) -> None:
228
+ """Wait for the specified task to complete."""
229
+ if task_uid not in self.tasks:
230
+ raise ValueError("Task not found.")
231
+
232
+ self.tasks[task_uid].event.wait(timeout)
233
+
234
+ if not self.tasks[task_uid].event.is_set():
235
+ raise TimeoutError("Task did not complete in time.")
236
+ if self.tasks[task_uid].error is not None:
237
+ raise Exception(f"Task failed with error: {self.tasks[task_uid].error}")
238
+
239
+ del self.tasks[task_uid]
240
+
241
+ def _handle_task_progress(self, sample: zenoh.Sample) -> None:
242
+ if sample.payload:
243
+ progress = TaskProgress.model_validate_json(sample.payload.to_string())
244
+ assert progress.uuid in self.tasks, "Unknown task UUID."
245
+
246
+ if progress.error:
247
+ self.tasks[progress.uuid].error = progress.error
248
+
249
+ if progress.finished:
250
+ self.tasks[progress.uuid].event.set()
251
+
252
+
253
+ @dataclass
254
+ class TaskState:
255
+ """Represents the state of a task."""
256
+
257
+ event: threading.Event
258
+ error: str | None
@@ -0,0 +1,183 @@
1
+ """Zenoh server for Reachy Mini.
2
+
3
+ This module implements a Zenoh server that allows communication with the Reachy Mini
4
+ robot. It handles commands for joint positions and torque settings, and publishes joint positions updates.
5
+
6
+ It uses the Zenoh protocol for efficient data exchange and can be configured to run
7
+ either on localhost only or to accept connections from other hosts.
8
+ """
9
+
10
+ import asyncio
11
+ import json
12
+ import threading
13
+ from datetime import datetime
14
+
15
+ import numpy as np
16
+ import zenoh
17
+
18
+ from reachy_mini.daemon.backend.abstract import Backend, MotorControlMode
19
+ from reachy_mini.io.abstract import AbstractServer
20
+ from reachy_mini.io.protocol import (
21
+ GotoTaskRequest,
22
+ PlayMoveTaskRequest,
23
+ TaskProgress,
24
+ TaskRequest,
25
+ )
26
+
27
+
28
+ class ZenohServer(AbstractServer):
29
+ """Zenoh server for Reachy Mini."""
30
+
31
+ def __init__(self, backend: Backend, localhost_only: bool = True):
32
+ """Initialize the Zenoh server."""
33
+ self.localhost_only = localhost_only
34
+ self.backend = backend
35
+
36
+ self._lock = threading.Lock()
37
+ self._cmd_event = threading.Event()
38
+
39
+ def start(self) -> None:
40
+ """Start the Zenoh server."""
41
+ if self.localhost_only:
42
+ c = zenoh.Config.from_json5(
43
+ json.dumps(
44
+ {
45
+ "listen": {
46
+ "endpoints": ["tcp/localhost:7447"],
47
+ },
48
+ "scouting": {
49
+ "multicast": {
50
+ "enabled": False,
51
+ },
52
+ "gossip": {
53
+ "enabled": False,
54
+ },
55
+ },
56
+ "connect": {
57
+ "endpoints": [
58
+ "tcp/localhost:7447",
59
+ ],
60
+ },
61
+ }
62
+ )
63
+ )
64
+ else:
65
+ c = zenoh.Config()
66
+
67
+ self.session = zenoh.open(c)
68
+ self.sub = self.session.declare_subscriber(
69
+ "reachy_mini/command",
70
+ self._handle_command,
71
+ )
72
+ self.pub = self.session.declare_publisher("reachy_mini/joint_positions")
73
+ self.pub_record = self.session.declare_publisher("reachy_mini/recorded_data")
74
+ self.backend.set_joint_positions_publisher(self.pub)
75
+ self.backend.set_recording_publisher(self.pub_record)
76
+
77
+ self.pub_pose = self.session.declare_publisher("reachy_mini/head_pose")
78
+ self.backend.set_pose_publisher(self.pub_pose)
79
+
80
+ self.task_req_sub = self.session.declare_subscriber(
81
+ "reachy_mini/task",
82
+ self._handle_task_request,
83
+ )
84
+ self.task_progress_pub = self.session.declare_publisher(
85
+ "reachy_mini/task_progress"
86
+ )
87
+
88
+ self.pub_status = self.session.declare_publisher("reachy_mini/daemon_status")
89
+
90
+ def stop(self) -> None:
91
+ """Stop the Zenoh server."""
92
+ self.session.close() # type: ignore[no-untyped-call]
93
+
94
+ def command_received_event(self) -> threading.Event:
95
+ """Wait for a new command and return it."""
96
+ return self._cmd_event
97
+
98
+ def _handle_command(self, sample: zenoh.Sample) -> None:
99
+ data = sample.payload.to_string()
100
+ command = json.loads(data)
101
+ with self._lock:
102
+ if "torque" in command:
103
+ if command["torque"]:
104
+ self.backend.set_motor_control_mode(MotorControlMode.Enabled)
105
+ else:
106
+ self.backend.set_motor_control_mode(MotorControlMode.Disabled)
107
+ if "head_joint_positions" in command:
108
+ self.backend.set_target_head_joint_positions(
109
+ np.array(command["head_joint_positions"])
110
+ )
111
+ if "head_pose" in command:
112
+ self.backend.set_target_head_pose(
113
+ np.array(command["head_pose"]).reshape(4, 4)
114
+ )
115
+ if "body_yaw" in command:
116
+ self.backend.set_target_body_yaw(command["body_yaw"])
117
+ if "antennas_joint_positions" in command:
118
+ self.backend.set_target_antenna_joint_positions(
119
+ np.array(command["antennas_joint_positions"]),
120
+ )
121
+ if "gravity_compensation" in command:
122
+ try:
123
+ if command["gravity_compensation"]:
124
+ self.backend.set_motor_control_mode(
125
+ MotorControlMode.GravityCompensation
126
+ )
127
+ else:
128
+ self.backend.set_motor_control_mode(MotorControlMode.Enabled)
129
+
130
+ except ValueError as e:
131
+ print(e)
132
+ if "automatic_body_yaw" in command:
133
+ self.backend.set_automatic_body_yaw(command["automatic_body_yaw"])
134
+
135
+ if "set_target_record" in command:
136
+ self.backend.append_record(command["set_target_record"])
137
+
138
+ if "start_recording" in command:
139
+ self.backend.start_recording()
140
+ if "stop_recording" in command:
141
+ self.backend.stop_recording()
142
+ self._cmd_event.set()
143
+
144
+ def _handle_task_request(self, sample: zenoh.Sample) -> None:
145
+ task_req = TaskRequest.model_validate_json(sample.payload.to_string())
146
+
147
+ if isinstance(task_req.req, GotoTaskRequest):
148
+ req = task_req.req
149
+
150
+ def task() -> None:
151
+ asyncio.run(
152
+ self.backend.goto_target(
153
+ head=np.array(req.head).reshape(4, 4) if req.head else None,
154
+ antennas=np.array(req.antennas) if req.antennas else None,
155
+ duration=req.duration,
156
+ method=req.method,
157
+ body_yaw=req.body_yaw,
158
+ )
159
+ )
160
+ elif isinstance(task_req.req, PlayMoveTaskRequest):
161
+
162
+ def task() -> None:
163
+ print("PLAY MOVE")
164
+
165
+ else:
166
+ assert False, f"Unknown task request type {task_req.req.__class__.__name__}"
167
+
168
+ def wrapped_task() -> None:
169
+ error = None
170
+ try:
171
+ task()
172
+ except Exception as e:
173
+ error = str(e)
174
+
175
+ progress = TaskProgress(
176
+ uuid=task_req.uuid,
177
+ finished=True,
178
+ error=error,
179
+ timestamp=datetime.now(),
180
+ )
181
+ self.task_progress_pub.put(progress.model_dump_json())
182
+
183
+ threading.Thread(target=wrapped_task).start()
@@ -0,0 +1,68 @@
1
+ """Try to import kinematics engines, and provide mockup classes if they are not available."""
2
+
3
+ from typing import Annotated
4
+
5
+ import numpy as np
6
+ import numpy.typing as npt
7
+
8
+ try:
9
+ from reachy_mini.kinematics.nn_kinematics import NNKinematics # noqa: F401
10
+ except ImportError:
11
+
12
+ class MockupNNKinematics:
13
+ """Mockup class for NNKinematics."""
14
+
15
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
16
+ """Raise ImportError when trying to instantiate the class."""
17
+ raise ImportError(
18
+ "NNKinematics could not be imported. Make sure you run pip install reachy_mini[nn_kinematics]."
19
+ )
20
+
21
+ def ik(self, *args, **kwargs) -> Annotated[npt.NDArray[np.float64], (7,)]: # type: ignore[no-untyped-def]
22
+ """Mockup method for ik."""
23
+ raise ImportError(
24
+ "NNKinematics could not be imported. Make sure you run pip install reachy_mini[nn_kinematics]."
25
+ )
26
+
27
+ def fk(self, *args, **kwargs) -> Annotated[npt.NDArray[np.float64], (4, 4)]: # type: ignore[no-untyped-def]
28
+ """Mockup method for fk."""
29
+ raise ImportError(
30
+ "NNKinematics could not be imported. Make sure you run pip install reachy_mini[nn_kinematics]."
31
+ )
32
+
33
+ NNKinematics = MockupNNKinematics # type: ignore[assignment, misc]
34
+
35
+ try:
36
+ from reachy_mini.kinematics.placo_kinematics import PlacoKinematics # noqa: F401
37
+ except ImportError:
38
+
39
+ class MockupPlacoKinematics:
40
+ """Mockup class for PlacoKinematics."""
41
+
42
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
43
+ """Raise ImportError when trying to instantiate the class."""
44
+ raise ImportError(
45
+ "PlacoKinematics could not be imported. Make sure you run pip install reachy_mini[placo_kinematics]."
46
+ )
47
+
48
+ def ik(self, *args, **kwargs) -> Annotated[npt.NDArray[np.float64], (7,)]: # type: ignore[no-untyped-def]
49
+ """Mockup method for ik."""
50
+ raise ImportError(
51
+ "PlacoKinematics could not be imported. Make sure you run pip install reachy_mini[placo_kinematics]."
52
+ )
53
+
54
+ def fk(self, *args, **kwargs) -> Annotated[npt.NDArray[np.float64], (4, 4)]: # type: ignore[no-untyped-def]
55
+ """Mockup method for fk."""
56
+ raise ImportError(
57
+ "PlacoKinematics could not be imported. Make sure you run pip install reachy_mini[placo_kinematics]."
58
+ )
59
+
60
+ PlacoKinematics = MockupPlacoKinematics # type: ignore[assignment, misc]
61
+
62
+
63
+ from reachy_mini.kinematics.analytical_kinematics import ( # noqa: F401
64
+ AnalyticalKinematics,
65
+ )
66
+
67
+ AnyKinematics = NNKinematics | PlacoKinematics | AnalyticalKinematics
68
+ __all__ = ["NNKinematics", "PlacoKinematics", "AnalyticalKinematics"]