reachy-mini 1.0.0rc1__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 (359) hide show
  1. reachy_mini/__init__.py +4 -0
  2. reachy_mini/apps/__init__.py +23 -0
  3. reachy_mini/apps/app.py +119 -0
  4. reachy_mini/apps/manager.py +178 -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 +38 -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 +3 -0
  20. reachy_mini/assets/models/fknetwork.onnx +3 -0
  21. reachy_mini/assets/models/fknetwork_int8.onnx +3 -0
  22. reachy_mini/assets/models/iknetwork.onnx +3 -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/dashboard/apps_manager.html +202 -0
  27. reachy_mini/daemon/app/dashboard/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
  28. reachy_mini/daemon/app/dashboard/js/dashboard.js +121 -0
  29. reachy_mini/daemon/app/dashboard/live_robot_state.html +242 -0
  30. reachy_mini/daemon/app/dashboard/style.css +37 -0
  31. reachy_mini/daemon/app/dependencies.py +36 -0
  32. reachy_mini/daemon/app/main.py +271 -0
  33. reachy_mini/daemon/app/models.py +146 -0
  34. reachy_mini/daemon/app/routers/apps.py +220 -0
  35. reachy_mini/daemon/app/routers/daemon.py +53 -0
  36. reachy_mini/daemon/app/routers/kinematics.py +36 -0
  37. reachy_mini/daemon/app/routers/motors.py +41 -0
  38. reachy_mini/daemon/app/routers/move.py +200 -0
  39. reachy_mini/daemon/app/routers/state.py +137 -0
  40. reachy_mini/daemon/app/templates/dashboard.html +40 -0
  41. reachy_mini/daemon/backend/__init__.py +1 -0
  42. reachy_mini/daemon/backend/abstract.py +717 -0
  43. reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
  44. reachy_mini/daemon/backend/mujoco/backend.py +304 -0
  45. reachy_mini/daemon/backend/mujoco/utils.py +59 -0
  46. reachy_mini/daemon/backend/mujoco/video_udp.py +53 -0
  47. reachy_mini/daemon/backend/robot/__init__.py +8 -0
  48. reachy_mini/daemon/backend/robot/backend.py +490 -0
  49. reachy_mini/daemon/daemon.py +442 -0
  50. reachy_mini/daemon/utils.py +114 -0
  51. reachy_mini/descriptions/reachy_mini/mjcf/additional.xml +6 -0
  52. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.part +13 -0
  53. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.stl +3 -0
  54. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.part +13 -0
  55. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.stl +3 -0
  56. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.part +13 -0
  57. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.stl +3 -0
  58. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.part +13 -0
  59. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.stl +3 -0
  60. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.part +13 -0
  61. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.stl +3 -0
  62. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.part +13 -0
  63. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.stl +3 -0
  64. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.part +13 -0
  65. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.stl +3 -0
  66. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.part +13 -0
  67. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.stl +3 -0
  68. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.part +13 -0
  69. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.stl +3 -0
  70. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.part +13 -0
  71. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.stl +3 -0
  72. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.part +13 -0
  73. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.stl +3 -0
  74. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.part +13 -0
  75. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.stl +3 -0
  76. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.part +13 -0
  77. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.stl +3 -0
  78. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.part +13 -0
  79. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.stl +3 -0
  80. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.part +13 -0
  81. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.stl +3 -0
  82. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.part +13 -0
  83. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.stl +3 -0
  84. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/croissant_1k.obj +3 -0
  85. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/textures/croissant_diff_1k.png +3 -0
  86. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.part +13 -0
  87. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.stl +3 -0
  88. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.part +13 -0
  89. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.stl +3 -0
  90. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.part +13 -0
  91. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.stl +3 -0
  92. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.part +13 -0
  93. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.stl +3 -0
  94. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  95. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.stl +3 -0
  96. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/food_apple_01_1k.obj +3 -0
  97. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/textures/food_apple_01_diff_1k.png +3 -0
  98. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.part +13 -0
  99. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.stl +3 -0
  100. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.part +13 -0
  101. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.stl +3 -0
  102. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.part +13 -0
  103. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.stl +3 -0
  104. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.part +13 -0
  105. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.stl +3 -0
  106. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.part +13 -0
  107. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.stl +3 -0
  108. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.part +13 -0
  109. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.stl +3 -0
  110. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  111. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.stl +3 -0
  112. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.part +13 -0
  113. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.stl +3 -0
  114. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.part +13 -0
  115. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.stl +3 -0
  116. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.part +13 -0
  117. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.stl +3 -0
  118. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  119. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.stl +3 -0
  120. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  121. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.stl +3 -0
  122. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  123. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.stl +3 -0
  124. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.part +13 -0
  125. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.stl +3 -0
  126. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/rubber_duck_toy_1k.obj +3 -0
  127. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/textures/rubber_duck_toy_diff_1k.png +3 -0
  128. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.part +13 -0
  129. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.stl +3 -0
  130. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.part +13 -0
  131. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.stl +3 -0
  132. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.part +13 -0
  133. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.stl +3 -0
  134. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.part +13 -0
  135. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.stl +3 -0
  136. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.part +13 -0
  137. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.stl +3 -0
  138. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.part +13 -0
  139. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.stl +3 -0
  140. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/textures/wooden_table_02_diff_1k.png +3 -0
  141. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/wooden_table_02_1k.obj +3 -0
  142. reachy_mini/descriptions/reachy_mini/mjcf/config.json +21 -0
  143. reachy_mini/descriptions/reachy_mini/mjcf/joints_properties.xml +29 -0
  144. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml +613 -0
  145. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml.bak +442 -0
  146. reachy_mini/descriptions/reachy_mini/mjcf/scene.xml +24 -0
  147. reachy_mini/descriptions/reachy_mini/mjcf/scenes/empty.xml +27 -0
  148. reachy_mini/descriptions/reachy_mini/mjcf/scenes/minimal.xml +131 -0
  149. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.part +13 -0
  150. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.stl +3 -0
  151. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.part +13 -0
  152. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.stl +3 -0
  153. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.part +13 -0
  154. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.stl +3 -0
  155. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.part +13 -0
  156. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.stl +3 -0
  157. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.part +13 -0
  158. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.stl +3 -0
  159. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.part +13 -0
  160. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.stl +3 -0
  161. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.part +13 -0
  162. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.stl +3 -0
  163. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.part +13 -0
  164. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.stl +3 -0
  165. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.part +13 -0
  166. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.stl +3 -0
  167. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.part +13 -0
  168. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.stl +3 -0
  169. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.part +13 -0
  170. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.stl +3 -0
  171. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.part +13 -0
  172. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.stl +3 -0
  173. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.part +13 -0
  174. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.stl +3 -0
  175. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.part +13 -0
  176. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.stl +3 -0
  177. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.part +13 -0
  178. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.stl +3 -0
  179. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.part +13 -0
  180. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.stl +3 -0
  181. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.part +13 -0
  182. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.stl +3 -0
  183. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.part +13 -0
  184. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.stl +3 -0
  185. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.part +13 -0
  186. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.stl +3 -0
  187. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.part +13 -0
  188. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.stl +3 -0
  189. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.part +13 -0
  190. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.stl +3 -0
  191. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.part +13 -0
  192. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.stl +3 -0
  193. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.part +13 -0
  194. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.stl +3 -0
  195. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.part +13 -0
  196. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.stl +3 -0
  197. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  198. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.stl +3 -0
  199. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.part +14 -0
  200. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.stl +3 -0
  201. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.part +14 -0
  202. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.stl +3 -0
  203. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.part +13 -0
  204. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.stl +3 -0
  205. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.part +13 -0
  206. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.stl +3 -0
  207. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.part +13 -0
  208. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.stl +3 -0
  209. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.part +13 -0
  210. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.stl +3 -0
  211. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.part +13 -0
  212. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.stl +3 -0
  213. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.part +13 -0
  214. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.stl +3 -0
  215. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.part +13 -0
  216. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.stl +3 -0
  217. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.part +13 -0
  218. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.stl +3 -0
  219. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.part +13 -0
  220. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.stl +3 -0
  221. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.part +13 -0
  222. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.stl +3 -0
  223. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.part +13 -0
  224. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.stl +3 -0
  225. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  226. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.stl +3 -0
  227. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.part +13 -0
  228. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.stl +3 -0
  229. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.part +13 -0
  230. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.stl +3 -0
  231. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.part +13 -0
  232. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.stl +3 -0
  233. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.part +13 -0
  234. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.stl +3 -0
  235. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.part +13 -0
  236. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.stl +3 -0
  237. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.part +13 -0
  238. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.stl +3 -0
  239. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  240. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.stl +3 -0
  241. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  242. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.stl +3 -0
  243. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  244. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.stl +3 -0
  245. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.part +13 -0
  246. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.stl +3 -0
  247. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.part +13 -0
  248. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.stl +3 -0
  249. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.part +13 -0
  250. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.stl +3 -0
  251. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.part +13 -0
  252. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.stl +3 -0
  253. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.part +13 -0
  254. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.stl +3 -0
  255. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.part +13 -0
  256. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.stl +3 -0
  257. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.part +13 -0
  258. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.stl +3 -0
  259. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.part +13 -0
  260. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.stl +3 -0
  261. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.part +13 -0
  262. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.stl +3 -0
  263. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.part +13 -0
  264. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.stl +3 -0
  265. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.part +13 -0
  266. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.stl +3 -0
  267. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.part +13 -0
  268. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.stl +3 -0
  269. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.part +13 -0
  270. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.stl +3 -0
  271. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.part +13 -0
  272. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.stl +3 -0
  273. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.part +13 -0
  274. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.stl +3 -0
  275. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.part +13 -0
  276. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.stl +3 -0
  277. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.part +13 -0
  278. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.stl +3 -0
  279. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.part +13 -0
  280. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.stl +3 -0
  281. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.part +13 -0
  282. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.stl +3 -0
  283. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.part +13 -0
  284. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.stl +3 -0
  285. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.part +13 -0
  286. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.stl +3 -0
  287. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.part +13 -0
  288. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.stl +3 -0
  289. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.part +13 -0
  290. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.stl +3 -0
  291. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.part +13 -0
  292. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.stl +3 -0
  293. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.part +13 -0
  294. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.stl +3 -0
  295. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.part +13 -0
  296. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.stl +3 -0
  297. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.part +13 -0
  298. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.stl +3 -0
  299. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.part +13 -0
  300. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.stl +3 -0
  301. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.part +13 -0
  302. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.stl +3 -0
  303. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.part +13 -0
  304. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.stl +3 -0
  305. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.part +13 -0
  306. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.stl +3 -0
  307. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.part +13 -0
  308. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.stl +3 -0
  309. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.part +14 -0
  310. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.stl +3 -0
  311. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.part +14 -0
  312. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.stl +3 -0
  313. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.part +14 -0
  314. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.stl +3 -0
  315. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.part +14 -0
  316. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.stl +3 -0
  317. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.part +14 -0
  318. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.stl +3 -0
  319. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.part +14 -0
  320. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.stl +3 -0
  321. reachy_mini/descriptions/reachy_mini/urdf/config.json +18 -0
  322. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf +3282 -0
  323. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf.bak +3282 -0
  324. reachy_mini/descriptions/reachy_mini/urdf/robot_no_collision.urdf +2316 -0
  325. reachy_mini/io/__init__.py +1 -0
  326. reachy_mini/io/abstract.py +70 -0
  327. reachy_mini/io/protocol.py +44 -0
  328. reachy_mini/io/zenoh_client.py +258 -0
  329. reachy_mini/io/zenoh_server.py +183 -0
  330. reachy_mini/kinematics/__init__.py +68 -0
  331. reachy_mini/kinematics/analytical_kinematics.py +102 -0
  332. reachy_mini/kinematics/nn_kinematics.py +100 -0
  333. reachy_mini/kinematics/placo_kinematics.py +662 -0
  334. reachy_mini/media/__init__.py +1 -0
  335. reachy_mini/media/audio_base.py +75 -0
  336. reachy_mini/media/audio_gstreamer.py +194 -0
  337. reachy_mini/media/audio_sounddevice.py +207 -0
  338. reachy_mini/media/audio_utils.py +27 -0
  339. reachy_mini/media/camera_base.py +58 -0
  340. reachy_mini/media/camera_constants.py +13 -0
  341. reachy_mini/media/camera_gstreamer.py +144 -0
  342. reachy_mini/media/camera_opencv.py +61 -0
  343. reachy_mini/media/camera_utils.py +60 -0
  344. reachy_mini/media/media_manager.py +186 -0
  345. reachy_mini/motion/__init__.py +4 -0
  346. reachy_mini/motion/goto.py +71 -0
  347. reachy_mini/motion/move.py +36 -0
  348. reachy_mini/motion/recorded_move.py +132 -0
  349. reachy_mini/reachy_mini.py +705 -0
  350. reachy_mini/utils/__init__.py +46 -0
  351. reachy_mini/utils/constants.py +9 -0
  352. reachy_mini/utils/interpolation.py +227 -0
  353. reachy_mini/utils/parse_urdf_for_kinematics.py +85 -0
  354. reachy_mini-1.0.0rc1.dist-info/METADATA +261 -0
  355. reachy_mini-1.0.0rc1.dist-info/RECORD +359 -0
  356. reachy_mini-1.0.0rc1.dist-info/WHEEL +5 -0
  357. reachy_mini-1.0.0rc1.dist-info/entry_points.txt +3 -0
  358. reachy_mini-1.0.0rc1.dist-info/licenses/LICENSE +201 -0
  359. reachy_mini-1.0.0rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,442 @@
1
+ """Daemon for Reachy Mini robot.
2
+
3
+ This module provides a daemon that runs a backend for either a simulated Reachy Mini using Mujoco or a real Reachy Mini robot using a serial connection.
4
+ It includes methods to start, stop, and restart the daemon, as well as to check its status.
5
+ It also provides a command-line interface for easy interaction.
6
+ """
7
+
8
+ import json
9
+ import logging
10
+ import time
11
+ from dataclasses import asdict, dataclass
12
+ from enum import Enum
13
+ from threading import Event, Thread
14
+ from typing import Any, Optional
15
+
16
+ from reachy_mini.daemon.backend.abstract import MotorControlMode
17
+ from reachy_mini.daemon.utils import (
18
+ convert_enum_to_dict,
19
+ find_serial_port,
20
+ get_ip_address,
21
+ )
22
+
23
+ from ..io.zenoh_server import ZenohServer
24
+ from .backend.mujoco import MujocoBackend, MujocoBackendStatus
25
+ from .backend.robot import RobotBackend, RobotBackendStatus
26
+
27
+
28
+ class Daemon:
29
+ """Daemon for simulated or real Reachy Mini robot.
30
+
31
+ Runs the server with the appropriate backend (Mujoco for simulation or RobotBackend for real hardware).
32
+ """
33
+
34
+ def __init__(self, log_level: str = "INFO", wireless_version: bool = False) -> None:
35
+ """Initialize the Reachy Mini daemon."""
36
+ self.log_level = log_level
37
+ self.logger = logging.getLogger(__name__)
38
+ self.logger.setLevel(self.log_level)
39
+
40
+ self.wireless_version = wireless_version
41
+
42
+ self.backend: "RobotBackend | MujocoBackend | None" = None
43
+ self._status = DaemonStatus(
44
+ state=DaemonState.NOT_INITIALIZED,
45
+ wireless_version=wireless_version,
46
+ simulation_enabled=None,
47
+ backend_status=None,
48
+ error=None,
49
+ wlan_ip=None,
50
+ )
51
+ self._thread_publish_status = Thread(target=self._publish_status, daemon=True)
52
+ self._thread_event_publish_status = Event()
53
+
54
+ async def start(
55
+ self,
56
+ sim: bool = False,
57
+ serialport: str = "auto",
58
+ scene: str = "empty",
59
+ localhost_only: bool = True,
60
+ wake_up_on_start: bool = True,
61
+ check_collision: bool = False,
62
+ kinematics_engine: str = "AnalyticalKinematics",
63
+ headless: bool = False,
64
+ ) -> "DaemonState":
65
+ """Start the Reachy Mini daemon.
66
+
67
+ Args:
68
+ sim (bool): If True, run in simulation mode using Mujoco. Defaults to False.
69
+ serialport (str): Serial port for real motors. Defaults to "auto", which will try to find the port automatically.
70
+ scene (str): Name of the scene to load in simulation mode ("empty" or "minimal"). Defaults to "empty".
71
+ localhost_only (bool): If True, restrict the server to localhost only clients. Defaults to True.
72
+ wake_up_on_start (bool): If True, wake up Reachy Mini on start. Defaults to True.
73
+ check_collision (bool): If True, enable collision checking. Defaults to False.
74
+ kinematics_engine (str): Kinematics engine to use. Defaults to "AnalyticalKinematics".
75
+ headless (bool): If True, run Mujoco in headless mode (no GUI). Defaults to False.
76
+
77
+ Returns:
78
+ DaemonState: The current state of the daemon after attempting to start it.
79
+
80
+ """
81
+ if self._status.state == DaemonState.RUNNING:
82
+ self.logger.warning("Daemon is already running.")
83
+ return self._status.state
84
+
85
+ self._status.simulation_enabled = sim
86
+
87
+ if not localhost_only:
88
+ self._status.wlan_ip = get_ip_address()
89
+
90
+ self._start_params = {
91
+ "sim": sim,
92
+ "serialport": serialport,
93
+ "headless": headless,
94
+ "scene": scene,
95
+ "localhost_only": localhost_only,
96
+ }
97
+
98
+ self.logger.info("Starting Reachy Mini daemon...")
99
+ self._status.state = DaemonState.STARTING
100
+
101
+ try:
102
+ self.backend = self._setup_backend(
103
+ wireless_version=self.wireless_version,
104
+ sim=sim,
105
+ serialport=serialport,
106
+ scene=scene,
107
+ check_collision=check_collision,
108
+ kinematics_engine=kinematics_engine,
109
+ headless=headless,
110
+ )
111
+ except Exception as e:
112
+ self._status.state = DaemonState.ERROR
113
+ self._status.error = str(e)
114
+ raise e
115
+
116
+ self.server = ZenohServer(self.backend, localhost_only=localhost_only)
117
+ self.server.start()
118
+ self._thread_publish_status.start()
119
+
120
+ def backend_wrapped_run() -> None:
121
+ assert self.backend is not None, (
122
+ "Backend should be initialized before running."
123
+ )
124
+
125
+ try:
126
+ self.backend.wrapped_run()
127
+ except Exception as e:
128
+ self.logger.error(f"Backend encountered an error: {e}")
129
+ self._status.state = DaemonState.ERROR
130
+ self._status.error = str(e)
131
+ self.server.stop()
132
+ self.backend = None
133
+
134
+ self.backend_run_thread = Thread(target=backend_wrapped_run)
135
+ self.backend_run_thread.start()
136
+
137
+ if not self.backend.ready.wait(timeout=2.0):
138
+ self.logger.error(
139
+ "Backend is not ready after 2 seconds. Some error occurred."
140
+ )
141
+ self._status.state = DaemonState.ERROR
142
+ self._status.error = self.backend.error
143
+ return self._status.state
144
+
145
+ if wake_up_on_start:
146
+ try:
147
+ self.logger.info("Waking up Reachy Mini...")
148
+ self.backend.set_motor_control_mode(MotorControlMode.Enabled)
149
+ await self.backend.wake_up()
150
+ except Exception as e:
151
+ self.logger.error(f"Error while waking up Reachy Mini: {e}")
152
+ self._status.state = DaemonState.ERROR
153
+ self._status.error = str(e)
154
+ return self._status.state
155
+ except KeyboardInterrupt:
156
+ self.logger.warning("Wake up interrupted by user.")
157
+ self._status.state = DaemonState.STOPPING
158
+ return self._status.state
159
+
160
+ self.logger.info("Daemon started successfully.")
161
+ self._status.state = DaemonState.RUNNING
162
+ return self._status.state
163
+
164
+ async def stop(self, goto_sleep_on_stop: bool = True) -> "DaemonState":
165
+ """Stop the Reachy Mini daemon.
166
+
167
+ Args:
168
+ goto_sleep_on_stop (bool): If True, put Reachy Mini to sleep on stop. Defaults to True.
169
+
170
+ Returns:
171
+ DaemonState: The current state of the daemon after attempting to stop it.
172
+
173
+ """
174
+ if self._status.state == DaemonState.STOPPED:
175
+ self.logger.warning("Daemon is already stopped.")
176
+ return self._status.state
177
+
178
+ if self.backend is None:
179
+ self.logger.info("Daemon backend is not initialized.")
180
+ self._status.state = DaemonState.STOPPED
181
+ return self._status.state
182
+
183
+ try:
184
+ if self._status.state in (DaemonState.STOPPING, DaemonState.ERROR):
185
+ goto_sleep_on_stop = False
186
+
187
+ self.logger.info("Stopping Reachy Mini daemon...")
188
+ self._status.state = DaemonState.STOPPING
189
+ self.backend.is_shutting_down = True
190
+ self._thread_event_publish_status.set()
191
+ self.server.stop()
192
+
193
+ if goto_sleep_on_stop:
194
+ try:
195
+ self.logger.info("Putting Reachy Mini to sleep...")
196
+ self.backend.set_motor_control_mode(MotorControlMode.Enabled)
197
+ await self.backend.goto_sleep()
198
+ self.backend.set_motor_control_mode(MotorControlMode.Disabled)
199
+ except Exception as e:
200
+ self.logger.error(f"Error while putting Reachy Mini to sleep: {e}")
201
+ self._status.state = DaemonState.ERROR
202
+ self._status.error = str(e)
203
+ except KeyboardInterrupt:
204
+ self.logger.warning("Sleep interrupted by user.")
205
+ self._status.state = DaemonState.STOPPING
206
+
207
+ self.backend.should_stop.set()
208
+ self.backend_run_thread.join(timeout=5.0)
209
+ if self.backend_run_thread.is_alive():
210
+ self.logger.warning("Backend did not stop in time, forcing shutdown.")
211
+ self._status.state = DaemonState.ERROR
212
+
213
+ self.backend.close()
214
+ self.backend.ready.clear()
215
+
216
+ if self._status.state != DaemonState.ERROR:
217
+ self.logger.info("Daemon stopped successfully.")
218
+ self._status.state = DaemonState.STOPPED
219
+ except Exception as e:
220
+ self.logger.error(f"Error while stopping the daemon: {e}")
221
+ self._status.state = DaemonState.ERROR
222
+ self._status.error = str(e)
223
+ except KeyboardInterrupt:
224
+ self.logger.warning("Daemon already stopping...")
225
+
226
+ backend_status = self.backend.get_status()
227
+ if backend_status.error:
228
+ self._status.state = DaemonState.ERROR
229
+
230
+ self.backend = None
231
+
232
+ return self._status.state
233
+
234
+ async def restart(
235
+ self,
236
+ sim: Optional[bool] = None,
237
+ serialport: Optional[str] = None,
238
+ scene: Optional[str] = None,
239
+ headless: Optional[bool] = None,
240
+ localhost_only: Optional[bool] = None,
241
+ wake_up_on_start: Optional[bool] = None,
242
+ goto_sleep_on_stop: Optional[bool] = None,
243
+ ) -> "DaemonState":
244
+ """Restart the Reachy Mini daemon.
245
+
246
+ Args:
247
+ sim (bool): If True, run in simulation mode using Mujoco. Defaults to None (uses the previous value).
248
+ serialport (str): Serial port for real motors. Defaults to None (uses the previous value).
249
+ scene (str): Name of the scene to load in simulation mode ("empty" or "minimal"). Defaults to None (uses the previous value).
250
+ headless (bool): If True, run Mujoco in headless mode (no GUI). Defaults to None (uses the previous value).
251
+ localhost_only (bool): If True, restrict the server to localhost only clients. Defaults to None (uses the previous value).
252
+ wake_up_on_start (bool): If True, wake up Reachy Mini on start. Defaults to None (don't wake up).
253
+ goto_sleep_on_stop (bool): If True, put Reachy Mini to sleep on stop. Defaults to None (don't go to sleep).
254
+
255
+ Returns:
256
+ DaemonState: The current state of the daemon after attempting to restart it.
257
+
258
+ """
259
+ if self._status.state == DaemonState.STOPPED:
260
+ self.logger.warning("Daemon is not running.")
261
+ return self._status.state
262
+
263
+ if self._status.state in (DaemonState.RUNNING, DaemonState.ERROR):
264
+ self.logger.info("Restarting Reachy Mini daemon...")
265
+
266
+ await self.stop(
267
+ goto_sleep_on_stop=goto_sleep_on_stop
268
+ if goto_sleep_on_stop is not None
269
+ else False
270
+ )
271
+ params: dict[str, Any] = {
272
+ "sim": sim if sim is not None else self._start_params["sim"],
273
+ "serialport": serialport
274
+ if serialport is not None
275
+ else self._start_params["serialport"],
276
+ "scene": scene if scene is not None else self._start_params["scene"],
277
+ "headless": headless
278
+ if headless is not None
279
+ else self._start_params["headless"],
280
+ "localhost_only": localhost_only
281
+ if localhost_only is not None
282
+ else self._start_params["localhost_only"],
283
+ "wake_up_on_start": wake_up_on_start
284
+ if wake_up_on_start is not None
285
+ else False,
286
+ }
287
+
288
+ return await self.start(**params)
289
+
290
+ raise NotImplementedError(
291
+ "Restarting is only supported when the daemon is in RUNNING or ERROR state."
292
+ )
293
+
294
+ def status(self) -> "DaemonStatus":
295
+ """Get the current status of the Reachy Mini daemon."""
296
+ if self.backend is not None:
297
+ self._status.backend_status = self.backend.get_status()
298
+
299
+ assert self._status.backend_status is not None, (
300
+ "Backend status should not be None after backend initialization."
301
+ )
302
+
303
+ if self._status.backend_status.error:
304
+ self._status.state = DaemonState.ERROR
305
+ self._status.error = self._status.backend_status.error
306
+ else:
307
+ self._status.backend_status = None
308
+
309
+ return self._status
310
+
311
+ def _publish_status(self) -> None:
312
+ self._thread_event_publish_status.clear()
313
+ while self._thread_event_publish_status.is_set() is False:
314
+ json_str = json.dumps(
315
+ asdict(self.status(), dict_factory=convert_enum_to_dict)
316
+ )
317
+ self.server.pub_status.put(json_str)
318
+ time.sleep(1)
319
+
320
+ async def run4ever(
321
+ self,
322
+ sim: bool = False,
323
+ serialport: str = "auto",
324
+ scene: str = "empty",
325
+ localhost_only: bool = True,
326
+ wake_up_on_start: bool = True,
327
+ goto_sleep_on_stop: bool = True,
328
+ check_collision: bool = False,
329
+ kinematics_engine: str = "AnalyticalKinematics",
330
+ headless: bool = False,
331
+ ) -> None:
332
+ """Run the Reachy Mini daemon indefinitely.
333
+
334
+ First, it starts the daemon, then it keeps checking the status and allows for graceful shutdown on user interrupt (Ctrl+C).
335
+
336
+ Args:
337
+ sim (bool): If True, run in simulation mode using Mujoco. Defaults to False.
338
+ serialport (str): Serial port for real motors. Defaults to "auto", which will try to find the port automatically.
339
+ scene (str): Name of the scene to load in simulation mode ("empty" or "minimal"). Defaults to "empty".
340
+ localhost_only (bool): If True, restrict the server to localhost only clients. Defaults to True.
341
+ wake_up_on_start (bool): If True, wake up Reachy Mini on start. Defaults to True.
342
+ goto_sleep_on_stop (bool): If True, put Reachy Mini to sleep on stop. Defaults to True
343
+ check_collision (bool): If True, enable collision checking. Defaults to False.
344
+ kinematics_engine (str): Kinematics engine to use. Defaults to "AnalyticalKinematics".
345
+ headless (bool): If True, run Mujoco in headless mode (no GUI). Defaults to False.
346
+
347
+ """
348
+ await self.start(
349
+ sim=sim,
350
+ serialport=serialport,
351
+ scene=scene,
352
+ localhost_only=localhost_only,
353
+ wake_up_on_start=wake_up_on_start,
354
+ check_collision=check_collision,
355
+ kinematics_engine=kinematics_engine,
356
+ headless=headless,
357
+ )
358
+
359
+ if self._status.state == DaemonState.RUNNING:
360
+ try:
361
+ self.logger.info("Daemon is running. Press Ctrl+C to stop.")
362
+ while self.backend_run_thread.is_alive():
363
+ self.logger.info(f"Daemon status: {self.status()}")
364
+ for _ in range(10):
365
+ self.backend_run_thread.join(timeout=1.0)
366
+ else:
367
+ self.logger.error("Backend thread has stopped unexpectedly.")
368
+ self._status.state = DaemonState.ERROR
369
+ except KeyboardInterrupt:
370
+ self.logger.warning("Daemon interrupted by user.")
371
+ except Exception as e:
372
+ self.logger.error(f"An error occurred: {e}")
373
+ self._status.state = DaemonState.ERROR
374
+ self._status.error = str(e)
375
+
376
+ await self.stop(goto_sleep_on_stop)
377
+
378
+ def _setup_backend(
379
+ self,
380
+ wireless_version: bool,
381
+ sim: bool,
382
+ serialport: str,
383
+ scene: str,
384
+ check_collision: bool,
385
+ kinematics_engine: str,
386
+ headless: bool,
387
+ ) -> "RobotBackend | MujocoBackend":
388
+ if sim:
389
+ return MujocoBackend(
390
+ scene=scene,
391
+ check_collision=check_collision,
392
+ kinematics_engine=kinematics_engine,
393
+ headless=headless,
394
+ )
395
+ else:
396
+ if serialport == "auto":
397
+ ports = find_serial_port(wireless_version=wireless_version)
398
+
399
+ if len(ports) == 0:
400
+ raise RuntimeError(
401
+ "No Reachy Mini serial port found. "
402
+ "Check USB connection and permissions. "
403
+ "Or directly specify the serial port using --serialport."
404
+ )
405
+ elif len(ports) > 1:
406
+ raise RuntimeError(
407
+ f"Multiple Reachy Mini serial ports found {ports}."
408
+ "Please specify the serial port using --serialport."
409
+ )
410
+
411
+ serialport = ports[0]
412
+ self.logger.info(f"Found Reachy Mini serial port: {serialport}")
413
+
414
+ return RobotBackend(
415
+ serialport=serialport,
416
+ log_level=self.log_level,
417
+ check_collision=check_collision,
418
+ kinematics_engine=kinematics_engine,
419
+ )
420
+
421
+
422
+ class DaemonState(Enum):
423
+ """Enum representing the state of the Reachy Mini daemon."""
424
+
425
+ NOT_INITIALIZED = "not_initialized"
426
+ STARTING = "starting"
427
+ RUNNING = "running"
428
+ STOPPING = "stopping"
429
+ STOPPED = "stopped"
430
+ ERROR = "error"
431
+
432
+
433
+ @dataclass
434
+ class DaemonStatus:
435
+ """Dataclass representing the status of the Reachy Mini daemon."""
436
+
437
+ state: DaemonState
438
+ wireless_version: bool
439
+ simulation_enabled: Optional[bool]
440
+ backend_status: Optional[RobotBackendStatus | MujocoBackendStatus]
441
+ error: Optional[str] = None
442
+ wlan_ip: Optional[str] = None
@@ -0,0 +1,114 @@
1
+ """Utilities for managing the Reachy Mini daemon."""
2
+
3
+ import fcntl
4
+ import os
5
+ import socket
6
+ import struct
7
+ import subprocess
8
+ import time
9
+ from enum import Enum
10
+ from typing import Any, List
11
+
12
+ import psutil
13
+ import serial.tools.list_ports
14
+
15
+
16
+ def daemon_check(spawn_daemon: bool, use_sim: bool) -> None:
17
+ """Check if the Reachy Mini daemon is running and spawn it if necessary."""
18
+
19
+ def is_python_script_running(
20
+ script_name: str,
21
+ ) -> tuple[bool, int | None, bool | None]:
22
+ """Check if a specific Python script is running."""
23
+ found_script = False
24
+ simluation_enabled = False
25
+ for proc in psutil.process_iter(["pid", "name", "cmdline"]):
26
+ try:
27
+ for cmd in proc.info["cmdline"]:
28
+ if script_name in cmd:
29
+ found_script = True
30
+ if "--sim" in cmd:
31
+ simluation_enabled = True
32
+ if found_script:
33
+ return True, proc.pid, simluation_enabled
34
+ except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
35
+ continue
36
+ return False, None, None
37
+
38
+ if spawn_daemon:
39
+ daemon_is_running, pid, sim = is_python_script_running("reachy-mini-daemon")
40
+ if daemon_is_running and sim == use_sim:
41
+ print(
42
+ f"Reachy Mini daemon is already running (PID: {pid}). "
43
+ "No need to spawn a new one."
44
+ )
45
+ return
46
+ elif daemon_is_running and sim != use_sim:
47
+ print(
48
+ f"Reachy Mini daemon is already running (PID: {pid}) with a different configuration. "
49
+ )
50
+ print("Killing the existing daemon...")
51
+ assert pid is not None, "PID should not be None if daemon is running"
52
+ os.kill(pid, 9)
53
+ time.sleep(1)
54
+
55
+ print("Starting a new daemon...")
56
+ subprocess.Popen(
57
+ ["reachy-mini-daemon", "--sim"] if use_sim else ["reachy-mini-daemon"],
58
+ start_new_session=True,
59
+ )
60
+
61
+
62
+ def find_serial_port(
63
+ wireless_version: bool = False,
64
+ vid: str = "1a86",
65
+ pid: str = "55d3",
66
+ pi_uart: str = "/dev/ttyAMA3",
67
+ ) -> list[str]:
68
+ """Find the serial port for Reachy Mini based on VID and PID or the Raspberry Pi UART for the wireless version.
69
+
70
+ Args:
71
+ wireless_version (bool): Whether to look for the wireless version using the Raspberry Pi UART.
72
+ vid (str): Vendor ID of the device. (eg. "1a86").
73
+ pid (str): Product ID of the device. (eg. "55d3").
74
+ pi_uart (str): Path to the Raspberry Pi UART device. (eg. "/dev/ttyAMA3").
75
+
76
+ """
77
+ # If it's a wireless version, we should use the Raspberry Pi UART
78
+ if wireless_version:
79
+ return [pi_uart] if os.path.exists(pi_uart) else []
80
+
81
+ # If it's a lite version, we should find it using the VID and PID
82
+ ports = serial.tools.list_ports.comports()
83
+
84
+ vid = vid.upper()
85
+ pid = pid.upper()
86
+
87
+ return [p.device for p in ports if f"USB VID:PID={vid}:{pid}" in p.hwid]
88
+
89
+
90
+ def get_ip_address(ifname: str = "wlan0") -> str | None:
91
+ """Get the IP address of a specific network interface (Linux Only)."""
92
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
93
+ try:
94
+ return socket.inet_ntoa(
95
+ fcntl.ioctl(
96
+ s.fileno(),
97
+ 0x8915, # SIOCGIFADDR
98
+ struct.pack("256s", ifname[:15].encode("utf-8")),
99
+ )[20:24]
100
+ )
101
+ except OSError:
102
+ print(f"Could not get IP address for interface {ifname}.")
103
+ return None
104
+
105
+
106
+ def convert_enum_to_dict(data: List[Any]) -> dict[str, Any]:
107
+ """Convert a dataclass containing Enums to a dictionary with enum values."""
108
+
109
+ def convert_value(obj: Any) -> Any:
110
+ if isinstance(obj, Enum):
111
+ return obj.value
112
+ return obj
113
+
114
+ return dict((k, convert_value(v)) for k, v in data)
@@ -0,0 +1,6 @@
1
+ <contact>
2
+ <!-- <exclude name="exclude0" body1="torso" body2="sts32155"/> -->
3
+ </contact>
4
+ <default>
5
+ <equality solref="0.002 1" solimp="0.99 0.999 0.0005 0.5 2"/>
6
+ </default>
@@ -0,0 +1,13 @@
1
+ {
2
+ "configuration": "default",
3
+ "documentId": "7836ed39be931c6ece17e007",
4
+ "documentMicroversion": "ac3fd0c16468a1e3078617de",
5
+ "elementId": "48f0e86376312f8ca242a082",
6
+ "fullConfiguration": "default",
7
+ "id": "MUIOPFRAXdyRYA5/y",
8
+ "isStandardContent": false,
9
+ "name": "5W_SPEAKER <1>",
10
+ "partId": "JFD",
11
+ "suppressed": false,
12
+ "type": "Part"
13
+ }
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:89c220ac5fa6dd559fcd2f3faccb7197904ab6b882ccf5d2ad04b17a09d58b98
3
+ size 229884
@@ -0,0 +1,13 @@
1
+ {
2
+ "configuration": "default",
3
+ "documentId": "7836ed39be931c6ece17e007",
4
+ "documentMicroversion": "ac3fd0c16468a1e3078617de",
5
+ "elementId": "d5df0bcac25cddb763b3a090",
6
+ "fullConfiguration": "default",
7
+ "id": "MT+KnYpqaZ58+3raS",
8
+ "isStandardContent": false,
9
+ "name": "antenna <2>",
10
+ "partId": "JFD",
11
+ "suppressed": false,
12
+ "type": "Part"
13
+ }
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:01f894d2eb9cdc94e7c45944cabb6fa84074e33fb45c3ab9974744bc0e43a9cb
3
+ size 1048584
@@ -0,0 +1,13 @@
1
+ {
2
+ "configuration": "default",
3
+ "documentId": "7836ed39be931c6ece17e007",
4
+ "documentMicroversion": "ac3fd0c16468a1e3078617de",
5
+ "elementId": "41e19b342cf83e0d866fde9b",
6
+ "fullConfiguration": "default",
7
+ "id": "M6OWFp5hfkfES9FmB",
8
+ "isStandardContent": false,
9
+ "name": "Antenna_body_3DPrint <2>",
10
+ "partId": "JF/",
11
+ "suppressed": false,
12
+ "type": "Part"
13
+ }
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3f760ace60b1a368ba7c51bcd01a152a85e66a587fb24d55886cb9d9ffb9008f
3
+ size 241784
@@ -0,0 +1,13 @@
1
+ {
2
+ "configuration": "default",
3
+ "documentId": "7836ed39be931c6ece17e007",
4
+ "documentMicroversion": "ac3fd0c16468a1e3078617de",
5
+ "elementId": "41e19b342cf83e0d866fde9b",
6
+ "fullConfiguration": "default",
7
+ "id": "MHVB1f7lyvjCWrFJe",
8
+ "isStandardContent": false,
9
+ "name": "Antenna_Holder-L_3DPrint <1>",
10
+ "partId": "KFDB",
11
+ "suppressed": false,
12
+ "type": "Part"
13
+ }
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5c2f0efae648fa0174dbc374fb63f4b48f55dea18f16f407540d255d8c91a426
3
+ size 449784
@@ -0,0 +1,13 @@
1
+ {
2
+ "configuration": "default",
3
+ "documentId": "7836ed39be931c6ece17e007",
4
+ "documentMicroversion": "ac3fd0c16468a1e3078617de",
5
+ "elementId": "41e19b342cf83e0d866fde9b",
6
+ "fullConfiguration": "default",
7
+ "id": "MX6Uc6wQ4cFgySRks",
8
+ "isStandardContent": false,
9
+ "name": "Antenna_Holder-R_3DPrint <1>",
10
+ "partId": "JFv",
11
+ "suppressed": false,
12
+ "type": "Part"
13
+ }
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c7cd59ec8fd200294880c062b9190f223eb7fc7c207caecbb5de28fd4accbbe1
3
+ size 465984
@@ -0,0 +1,13 @@
1
+ {
2
+ "configuration": "default",
3
+ "documentId": "7836ed39be931c6ece17e007",
4
+ "documentMicroversion": "ac3fd0c16468a1e3078617de",
5
+ "elementId": "41e19b342cf83e0d866fde9b",
6
+ "fullConfiguration": "default",
7
+ "id": "MObKCzX1Fco0wvr0/",
8
+ "isStandardContent": false,
9
+ "name": "Antenna_interface_3DPrint <2>",
10
+ "partId": "JF7",
11
+ "suppressed": false,
12
+ "type": "Part"
13
+ }
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:662384ed2de2c37fff6d5bab1ba0ccb76ee03f5d1680043d255e33e879b481bb
3
+ size 179984