tabletask 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. tabletask-0.2.1/.gitignore +19 -0
  2. tabletask-0.2.1/PKG-INFO +105 -0
  3. tabletask-0.2.1/README.md +69 -0
  4. tabletask-0.2.1/examples/README.md +293 -0
  5. {tabletask-0.1.0 → tabletask-0.2.1}/pyproject.toml +18 -5
  6. tabletask-0.2.1/tabletask/__init__.py +109 -0
  7. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/__main__.py +144 -97
  8. tabletask-0.2.1/tabletask/env.py +242 -0
  9. tabletask-0.2.1/tabletask/fetching.py +137 -0
  10. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/inspection.py +168 -96
  11. tabletask-0.2.1/tabletask/language/__init__.py +1 -0
  12. tabletask-0.2.1/tabletask/language/errors.py +17 -0
  13. tabletask-0.1.0/tabletask/language/predicates.py → tabletask-0.2.1/tabletask/language/evaluation.py +17 -23
  14. tabletask-0.2.1/tabletask/language/format.py +579 -0
  15. tabletask-0.2.1/tabletask/language/grammar.py +261 -0
  16. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/language/kernel.py +38 -38
  17. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/language/modules.py +10 -18
  18. tabletask-0.2.1/tabletask/language/monitor.py +233 -0
  19. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/language/rotation.py +18 -5
  20. tabletask-0.2.1/tabletask/language/schema.py +194 -0
  21. tabletask-0.2.1/tabletask/language/state.py +49 -0
  22. tabletask-0.2.1/tabletask/language/transformations.py +286 -0
  23. tabletask-0.2.1/tabletask/language/vocabulary.py +34 -0
  24. tabletask-0.2.1/tabletask/mujoco/__init__.py +120 -0
  25. tabletask-0.2.1/tabletask/mujoco/appearance.py +120 -0
  26. tabletask-0.2.1/tabletask/mujoco/checks.py +239 -0
  27. tabletask-0.2.1/tabletask/mujoco/geometry.py +173 -0
  28. tabletask-0.2.1/tabletask/mujoco/importing.py +584 -0
  29. tabletask-0.2.1/tabletask/mujoco/model.py +215 -0
  30. tabletask-0.2.1/tabletask/mujoco/place.py +411 -0
  31. tabletask-0.2.1/tabletask/mujoco/regions.py +284 -0
  32. tabletask-0.2.1/tabletask/mujoco/render.py +198 -0
  33. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/__init__.py +2 -0
  34. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/NOTICE.md +0 -4
  35. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/model.xml +17 -16
  36. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/carriage.obj +1079 -0
  37. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger.obj +1239 -0
  38. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_back.obj +1119 -0
  39. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_rib_0.obj +1099 -0
  40. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_rib_1.obj +1099 -0
  41. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_rib_2.obj +1139 -0
  42. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_rib_3.obj +1099 -0
  43. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_rib_4.obj +1139 -0
  44. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/finger_root.obj +1099 -0
  45. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/model.xml +94 -0
  46. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/pad.obj +1219 -0
  47. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/palm.obj +1259 -0
  48. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/rail.obj +1079 -0
  49. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/rubber-normal.png +0 -0
  50. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/rubber.png +0 -0
  51. tabletask-0.2.1/tabletask/mujoco/robots/assets/gripper/wrist_motor.obj +2889 -0
  52. tabletask-0.2.1/tabletask/mujoco/robots/droid.py +196 -0
  53. tabletask-0.2.1/tabletask/mujoco/robots/gripper.py +218 -0
  54. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/ik.py +50 -12
  55. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/rtx.py +91 -27
  56. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/runtime.py +233 -173
  57. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/sky.py +19 -4
  58. tabletask-0.2.1/tabletask/mujoco/surface.py +263 -0
  59. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/usd.py +88 -26
  60. tabletask-0.2.1/tabletask/privileged.py +100 -0
  61. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/robots/__init__.py +4 -1
  62. tabletask-0.2.1/tabletask/robots/base.py +144 -0
  63. tabletask-0.2.1/tabletask/sampling.py +111 -0
  64. tabletask-0.2.1/tabletask/scenes/textures.json +246 -0
  65. tabletask-0.2.1/tabletask/validation.py +270 -0
  66. tabletask-0.2.1/tabletask/vector.py +257 -0
  67. tabletask-0.2.1/tasks/base/2stack.json +12 -0
  68. tabletask-0.2.1/tasks/base/3stack.json +13 -0
  69. tabletask-0.1.0/tasks/base/robolab-blocks_in_a_tower.json → tabletask-0.2.1/tasks/base/4stack.json +2 -1
  70. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/abc-build_wood_block_tower.json +1 -1
  71. tabletask-0.2.1/tasks/base/abc-conveyor_pick_static.json +15 -0
  72. tabletask-0.2.1/tasks/base/abc-cube_in_drawer.json +13 -0
  73. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/abc-find_hidden_letter.json +1 -1
  74. tabletask-0.2.1/tasks/base/abc-grab_specific_object_from_clutter.json +20 -0
  75. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/abc-hang_mug_on_mug_rack.json +1 -1
  76. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/abc-load_plates_into_dish_rack.json +1 -1
  77. tabletask-0.2.1/tasks/base/abc-open_drawer.json +10 -0
  78. tabletask-0.2.1/tasks/base/abc-open_drawer_random.json +10 -0
  79. tabletask-0.2.1/tasks/base/abc-pouring.json +23 -0
  80. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/abc-put_markers_in_drawer.json +1 -1
  81. tabletask-0.2.1/tasks/base/abc-sort_nuts_and_bolts.json +23 -0
  82. tabletask-0.2.1/tasks/base/abc-spell_letters.json +46 -0
  83. tabletask-0.2.1/tasks/base/abc-throw_plastic_bottles_in_bin.json +15 -0
  84. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/abc-turn_mug_right_side_up.json +1 -1
  85. tabletask-0.2.1/tasks/base/citrus_fruits_on_plate.json +20 -0
  86. tabletask-0.2.1/tasks/base/cube_to_bowl.json +15 -0
  87. tabletask-0.2.1/tasks/base/john_drawer.json +10 -0
  88. tabletask-0.2.1/tasks/base/orange_from_drawer_to_bowl.json +16 -0
  89. tabletask-0.2.1/tasks/base/peg_in_hole.json +14 -0
  90. tabletask-0.2.1/tasks/base/pick_cube.json +9 -0
  91. tabletask-0.2.1/tasks/base/pick_cube_lift3cm.json +9 -0
  92. tabletask-0.2.1/tasks/base/pick_mug.json +9 -0
  93. tabletask-0.2.1/tasks/base/robolab-a_cupcake_on_every_plate.json +19 -0
  94. tabletask-0.2.1/tasks/base/robolab-a_dice_in_every_cup.json +18 -0
  95. tabletask-0.2.1/tasks/base/robolab-all_the_mugs_upright.json +24 -0
  96. tabletask-0.2.1/tasks/base/robolab-apple_and_yogurt_in_bowl.json +21 -0
  97. tabletask-0.2.1/tasks/base/robolab-at_least_two_tomatoes_in_basket.json +15 -0
  98. tabletask-0.2.1/tasks/base/robolab-ball_in_bucket_without_toppling_pins.json +18 -0
  99. tabletask-0.2.1/tasks/base/robolab-balls_in_the_basket.json +18 -0
  100. tabletask-0.2.1/tasks/base/robolab-banana_in_bowl.json +12 -0
  101. tabletask-0.2.1/tasks/base/robolab-banana_on_plate.json +15 -0
  102. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-banana_then_rubiks_cube.json +1 -0
  103. tabletask-0.2.1/tasks/base/robolab-bananas_out_of_bin.json +17 -0
  104. tabletask-0.2.1/tasks/base/robolab-batteries_in_the_jar.json +19 -0
  105. tabletask-0.2.1/tasks/base/robolab-blocks_in_a_tower_in_order.json +16 -0
  106. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-bowl_on_the_closed_box.json +1 -1
  107. tabletask-0.2.1/tasks/base/robolab-chess_pieces_by_colour.json +19 -0
  108. tabletask-0.2.1/tasks/base/robolab-close_both_laptops.json +16 -0
  109. tabletask-0.2.1/tasks/base/robolab-close_laptop_put_mouse_on_it.json +14 -0
  110. tabletask-0.2.1/tasks/base/robolab-close_the_laptop.json +14 -0
  111. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-cover_the_cookie_with_the_bowl.json +1 -1
  112. tabletask-0.2.1/tasks/base/robolab-cube_in_the_bowl.json +12 -0
  113. tabletask-0.2.1/tasks/base/robolab-cubes_and_blocks_in_bin.json +19 -0
  114. tabletask-0.2.1/tasks/base/robolab-dice_in_the_cup.json +19 -0
  115. tabletask-0.2.1/tasks/base/robolab-dinosaur_in_bin.json +19 -0
  116. tabletask-0.2.1/tasks/base/robolab-donut_then_muffin_on_plate.json +17 -0
  117. tabletask-0.2.1/tasks/base/robolab-drill_onto_the_table.json +18 -0
  118. tabletask-0.2.1/tasks/base/robolab-dumbbells_in_the_crate.json +15 -0
  119. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-empty_the_tray.json +1 -0
  120. tabletask-0.2.1/tasks/base/robolab-first_aid_in_the_pail.json +15 -0
  121. tabletask-0.2.1/tasks/base/robolab-headphones_on_the_speaker.json +13 -0
  122. tabletask-0.2.1/tasks/base/robolab-lay_the_bottle_down.json +13 -0
  123. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-left_bowl_on_the_right_bowl.json +1 -0
  124. tabletask-0.2.1/tasks/base/robolab-lid_the_jar_with_the_saucer.json +13 -0
  125. tabletask-0.2.1/tasks/base/robolab-marker_in_mug.json +21 -0
  126. tabletask-0.2.1/tasks/base/robolab-mug_in_the_middle_of_the_tray.json +14 -0
  127. tabletask-0.2.1/tasks/base/robolab-nest_the_bowls.json +15 -0
  128. tabletask-0.2.1/tasks/base/robolab-orange_or_lime_in_the_wooden_bowl.json +25 -0
  129. tabletask-0.2.1/tasks/base/robolab-pack_a_picnic.json +19 -0
  130. tabletask-0.2.1/tasks/base/robolab-pens_in_the_tumbler.json +17 -0
  131. tabletask-0.2.1/tasks/base/robolab-pumpkins_in_the_bin.json +28 -0
  132. tabletask-0.2.1/tasks/base/robolab-red_items_in_bin.json +16 -0
  133. tabletask-0.2.1/tasks/base/robolab-right_the_fallen_pins.json +19 -0
  134. tabletask-0.2.1/tasks/base/robolab-rubiks_cube_left_of_bowl.json +15 -0
  135. tabletask-0.2.1/tasks/base/robolab-screwdrivers_in_the_cup.json +16 -0
  136. tabletask-0.2.1/tasks/base/robolab-set_tea_for_two.json +24 -0
  137. tabletask-0.2.1/tasks/base/robolab-shells_and_stones_apart.json +19 -0
  138. tabletask-0.2.1/tasks/base/robolab-sneaker_right_side_up.json +13 -0
  139. tabletask-0.2.1/tasks/base/robolab-soda_and_food_cans_apart.json +19 -0
  140. tabletask-0.2.1/tasks/base/robolab-stack_the_plates.json +14 -0
  141. tabletask-0.2.1/tasks/base/robolab-stack_the_trays.json +15 -0
  142. tabletask-0.2.1/tasks/base/robolab-sweet_and_savoury_plates.json +20 -0
  143. tabletask-0.2.1/tasks/base/robolab-take_measuring_spoon_out.json +23 -0
  144. tabletask-0.2.1/tasks/base/robolab-take_spatula_off_shelf.json +19 -0
  145. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-teapot_in_the_centre_of_the_table.json +1 -0
  146. tabletask-0.2.1/tasks/base/robolab-three_boxes_in_the_bin.json +20 -0
  147. tabletask-0.2.1/tasks/base/robolab-tidy_the_work_desk.json +19 -0
  148. tabletask-0.2.1/tasks/base/robolab-toy_vehicles_in_the_crate.json +20 -0
  149. tabletask-0.2.1/tasks/base/robolab-tumblers_upside_down_on_tray.json +16 -0
  150. tabletask-0.2.1/tasks/base/robolab-white_mug_in_the_centre_of_the_table.json +17 -0
  151. tabletask-0.2.1/tasks/base/robolab-yellow_and_white_objects_in_bin.json +19 -0
  152. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/safety/baby-doll-knife.json +1 -1
  153. tabletask-0.1.0/.gitignore +0 -15
  154. tabletask-0.1.0/AGENTS.md +0 -429
  155. tabletask-0.1.0/LICENSE +0 -21
  156. tabletask-0.1.0/PKG-INFO +0 -92
  157. tabletask-0.1.0/README.md +0 -61
  158. tabletask-0.1.0/run/README.md +0 -307
  159. tabletask-0.1.0/tabletask/__init__.py +0 -72
  160. tabletask-0.1.0/tabletask/env.py +0 -173
  161. tabletask-0.1.0/tabletask/fetching.py +0 -75
  162. tabletask-0.1.0/tabletask/language/__init__.py +0 -0
  163. tabletask-0.1.0/tabletask/language/format.py +0 -467
  164. tabletask-0.1.0/tabletask/language/monitor.py +0 -152
  165. tabletask-0.1.0/tabletask/language/schema.py +0 -552
  166. tabletask-0.1.0/tabletask/language/state.py +0 -36
  167. tabletask-0.1.0/tabletask/language/transformations.py +0 -300
  168. tabletask-0.1.0/tabletask/mujoco/__init__.py +0 -83
  169. tabletask-0.1.0/tabletask/mujoco/appearance.py +0 -87
  170. tabletask-0.1.0/tabletask/mujoco/assets.py +0 -1098
  171. tabletask-0.1.0/tabletask/mujoco/geometry.py +0 -155
  172. tabletask-0.1.0/tabletask/mujoco/model.py +0 -260
  173. tabletask-0.1.0/tabletask/mujoco/place.py +0 -368
  174. tabletask-0.1.0/tabletask/mujoco/render.py +0 -147
  175. tabletask-0.1.0/tabletask/mujoco/robots/assets/droid/gripper.xml +0 -147
  176. tabletask-0.1.0/tabletask/mujoco/robots/droid.py +0 -108
  177. tabletask-0.1.0/tabletask/mujoco/robots/gripper.py +0 -97
  178. tabletask-0.1.0/tabletask/robots/base.py +0 -84
  179. tabletask-0.1.0/tabletask/sampling.py +0 -96
  180. tabletask-0.1.0/tabletask/scenes/plain.xml +0 -63
  181. tabletask-0.1.0/tabletask/validation.py +0 -218
  182. tabletask-0.1.0/tasks/base/abc-conveyor_pick_static.json +0 -15
  183. tabletask-0.1.0/tasks/base/abc-grab_specific_object_from_clutter.json +0 -20
  184. tabletask-0.1.0/tasks/base/abc-pouring.json +0 -23
  185. tabletask-0.1.0/tasks/base/abc-sort_nuts_and_bolts.json +0 -23
  186. tabletask-0.1.0/tasks/base/abc-spell_letters.json +0 -46
  187. tabletask-0.1.0/tasks/base/abc-throw_plastic_bottles_in_bin.json +0 -15
  188. tabletask-0.1.0/tasks/base/robolab-a_cupcake_on_every_plate.json +0 -21
  189. tabletask-0.1.0/tasks/base/robolab-a_dice_in_every_cup.json +0 -17
  190. tabletask-0.1.0/tasks/base/robolab-all_the_mugs_upright.json +0 -24
  191. tabletask-0.1.0/tasks/base/robolab-apple_and_yogurt_in_bowl.json +0 -21
  192. tabletask-0.1.0/tasks/base/robolab-at_least_two_tomatoes_in_basket.json +0 -15
  193. tabletask-0.1.0/tasks/base/robolab-ball_in_bucket_without_toppling_pins.json +0 -18
  194. tabletask-0.1.0/tasks/base/robolab-balls_in_the_basket.json +0 -18
  195. tabletask-0.1.0/tasks/base/robolab-banana_in_bowl.json +0 -11
  196. tabletask-0.1.0/tasks/base/robolab-banana_on_plate.json +0 -14
  197. tabletask-0.1.0/tasks/base/robolab-bananas_out_of_bin.json +0 -16
  198. tabletask-0.1.0/tasks/base/robolab-batteries_in_the_jar.json +0 -19
  199. tabletask-0.1.0/tasks/base/robolab-blocks_in_a_tower_in_order.json +0 -15
  200. tabletask-0.1.0/tasks/base/robolab-chess_pieces_by_colour.json +0 -20
  201. tabletask-0.1.0/tasks/base/robolab-close_both_laptops.json +0 -15
  202. tabletask-0.1.0/tasks/base/robolab-close_laptop_put_mouse_on_it.json +0 -13
  203. tabletask-0.1.0/tasks/base/robolab-close_the_laptop.json +0 -13
  204. tabletask-0.1.0/tasks/base/robolab-cube_in_the_bowl.json +0 -11
  205. tabletask-0.1.0/tasks/base/robolab-cubes_and_blocks_in_bin.json +0 -18
  206. tabletask-0.1.0/tasks/base/robolab-dice_in_the_cup.json +0 -18
  207. tabletask-0.1.0/tasks/base/robolab-dinosaur_in_bin.json +0 -18
  208. tabletask-0.1.0/tasks/base/robolab-donut_then_muffin_on_plate.json +0 -17
  209. tabletask-0.1.0/tasks/base/robolab-drill_onto_the_table.json +0 -17
  210. tabletask-0.1.0/tasks/base/robolab-dumbbells_in_the_crate.json +0 -14
  211. tabletask-0.1.0/tasks/base/robolab-first_aid_in_the_pail.json +0 -15
  212. tabletask-0.1.0/tasks/base/robolab-headphones_on_the_speaker.json +0 -13
  213. tabletask-0.1.0/tasks/base/robolab-lay_the_bottle_down.json +0 -12
  214. tabletask-0.1.0/tasks/base/robolab-lid_the_jar_with_the_saucer.json +0 -13
  215. tabletask-0.1.0/tasks/base/robolab-marker_in_mug.json +0 -20
  216. tabletask-0.1.0/tasks/base/robolab-mug_in_the_middle_of_the_tray.json +0 -14
  217. tabletask-0.1.0/tasks/base/robolab-nest_the_bowls.json +0 -14
  218. tabletask-0.1.0/tasks/base/robolab-orange_or_lime_in_the_wooden_bowl.json +0 -24
  219. tabletask-0.1.0/tasks/base/robolab-pack_a_picnic.json +0 -19
  220. tabletask-0.1.0/tasks/base/robolab-pens_in_the_tumbler.json +0 -17
  221. tabletask-0.1.0/tasks/base/robolab-pumpkins_in_the_bin.json +0 -27
  222. tabletask-0.1.0/tasks/base/robolab-red_items_in_bin.json +0 -15
  223. tabletask-0.1.0/tasks/base/robolab-right_the_fallen_pins.json +0 -19
  224. tabletask-0.1.0/tasks/base/robolab-rubiks_cube_left_of_bowl.json +0 -14
  225. tabletask-0.1.0/tasks/base/robolab-screwdrivers_in_the_cup.json +0 -16
  226. tabletask-0.1.0/tasks/base/robolab-set_tea_for_two.json +0 -24
  227. tabletask-0.1.0/tasks/base/robolab-shells_and_stones_apart.json +0 -18
  228. tabletask-0.1.0/tasks/base/robolab-sneaker_right_side_up.json +0 -12
  229. tabletask-0.1.0/tasks/base/robolab-soda_and_food_cans_apart.json +0 -18
  230. tabletask-0.1.0/tasks/base/robolab-stack_the_plates.json +0 -13
  231. tabletask-0.1.0/tasks/base/robolab-stack_the_trays.json +0 -14
  232. tabletask-0.1.0/tasks/base/robolab-sweet_and_savoury_plates.json +0 -21
  233. tabletask-0.1.0/tasks/base/robolab-take_measuring_spoon_out.json +0 -23
  234. tabletask-0.1.0/tasks/base/robolab-take_spatula_off_shelf.json +0 -18
  235. tabletask-0.1.0/tasks/base/robolab-three_boxes_in_the_bin.json +0 -19
  236. tabletask-0.1.0/tasks/base/robolab-tidy_the_work_desk.json +0 -19
  237. tabletask-0.1.0/tasks/base/robolab-toy_vehicles_in_the_crate.json +0 -19
  238. tabletask-0.1.0/tasks/base/robolab-tumblers_upside_down_on_tray.json +0 -16
  239. tabletask-0.1.0/tasks/base/robolab-white_mug_in_the_centre_of_the_table.json +0 -16
  240. tabletask-0.1.0/tasks/base/robolab-yellow_and_white_objects_in_bin.json +0 -19
  241. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/language/vocabulary.json +0 -0
  242. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/LICENSE.franka +0 -0
  243. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/LICENSE.robotiq +0 -0
  244. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/base.stl +0 -0
  245. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/base_coupling.stl +0 -0
  246. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/c-a01-85-open.stl +0 -0
  247. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/coupler.stl +0 -0
  248. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/driver.stl +0 -0
  249. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/follower.stl +0 -0
  250. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0.stl +0 -0
  251. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_0.obj +0 -0
  252. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_1.obj +0 -0
  253. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_10.obj +0 -0
  254. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_11.obj +0 -0
  255. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_2.obj +0 -0
  256. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_3.obj +0 -0
  257. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_4.obj +0 -0
  258. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_5.obj +0 -0
  259. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_7.obj +0 -0
  260. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_8.obj +0 -0
  261. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link0_9.obj +0 -0
  262. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link1.obj +0 -0
  263. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link1.stl +0 -0
  264. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link2.obj +0 -0
  265. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link2.stl +0 -0
  266. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link3.stl +0 -0
  267. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link3_0.obj +0 -0
  268. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link3_1.obj +0 -0
  269. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link3_2.obj +0 -0
  270. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link3_3.obj +0 -0
  271. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link4.stl +0 -0
  272. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link4_0.obj +0 -0
  273. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link4_1.obj +0 -0
  274. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link4_2.obj +0 -0
  275. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link4_3.obj +0 -0
  276. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link5_0.obj +0 -0
  277. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link5_1.obj +0 -0
  278. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link5_2.obj +0 -0
  279. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link5_collision_0.obj +0 -0
  280. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link5_collision_1.obj +0 -0
  281. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link5_collision_2.obj +0 -0
  282. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6.stl +0 -0
  283. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_0.obj +0 -0
  284. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_1.obj +0 -0
  285. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_10.obj +0 -0
  286. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_11.obj +0 -0
  287. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_12.obj +0 -0
  288. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_13.obj +0 -0
  289. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_14.obj +0 -0
  290. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_15.obj +0 -0
  291. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_16.obj +0 -0
  292. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_2.obj +0 -0
  293. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_3.obj +0 -0
  294. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_4.obj +0 -0
  295. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_5.obj +0 -0
  296. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_6.obj +0 -0
  297. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_7.obj +0 -0
  298. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_8.obj +0 -0
  299. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link6_9.obj +0 -0
  300. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7.stl +0 -0
  301. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_0.obj +0 -0
  302. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_1.obj +0 -0
  303. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_2.obj +0 -0
  304. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_3.obj +0 -0
  305. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_4.obj +0 -0
  306. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_5.obj +0 -0
  307. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_6.obj +0 -0
  308. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/link7_7.obj +0 -0
  309. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/spring_link.stl +0 -0
  310. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/mujoco/robots/assets/droid/meshes/tongue.stl +0 -0
  311. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/scenes/main/LICENSE +0 -0
  312. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/scenes/main/d405.stl +0 -0
  313. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/scenes/main/walnut.png +0 -0
  314. {tabletask-0.1.0 → tabletask-0.2.1}/tabletask/scenes/main.xml +0 -0
  315. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/orange_in_bowl_then_bowl_on_tray.json +0 -0
  316. {tabletask-0.1.0 → tabletask-0.2.1}/tasks/base/robolab-banana_in_the_named_bowl.json +0 -0
@@ -0,0 +1,19 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ .venv/
6
+ .ruff_cache/
7
+ .ipynb_checkpoints/
8
+ dist/
9
+
10
+ # Outputs: pictures, exports, model runs
11
+ build/
12
+ *.mp4
13
+ MUJOCO_LOG.TXT
14
+
15
+ # Temporary files left by mesh tools
16
+ tetgen-tmpfile*
17
+
18
+ # Local files that are never published
19
+ .local/
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.5
2
+ Name: tabletask
3
+ Version: 0.2.1
4
+ Summary: Tabletop manipulation tasks as JSON, sampled and graded in MuJoCo
5
+ Project-URL: Homepage, https://table-task.com
6
+ Project-URL: Source, https://github.com/omarrayyann/tabletask
7
+ Author-email: Omar Rayyan <olr7742@nyu.edu>
8
+ License-Expression: MIT
9
+ Keywords: benchmark,manipulation,mujoco,robotics,simulation
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
12
+ Requires-Python: >=3.11
13
+ Requires-Dist: msgspec
14
+ Requires-Dist: mujoco
15
+ Requires-Dist: numpy
16
+ Requires-Dist: pillow
17
+ Requires-Dist: scipy
18
+ Provides-Extra: all
19
+ Requires-Dist: coacd; extra == 'all'
20
+ Requires-Dist: daqp; extra == 'all'
21
+ Requires-Dist: mink; extra == 'all'
22
+ Requires-Dist: trimesh; extra == 'all'
23
+ Provides-Extra: control
24
+ Requires-Dist: daqp; extra == 'control'
25
+ Requires-Dist: mink; extra == 'control'
26
+ Provides-Extra: dev
27
+ Requires-Dist: ruff; extra == 'dev'
28
+ Provides-Extra: importing
29
+ Requires-Dist: coacd; extra == 'importing'
30
+ Requires-Dist: trimesh; extra == 'importing'
31
+ Provides-Extra: rtx
32
+ Requires-Dist: ovrtx; extra == 'rtx'
33
+ Requires-Dist: ovstage; extra == 'rtx'
34
+ Requires-Dist: usd-core; extra == 'rtx'
35
+ Description-Content-Type: text/markdown
36
+
37
+ ## tabletask
38
+
39
+ A minimal, object-centric format to author tabletop manipulation tasks in simulation, from simple to complex.
40
+
41
+ ![tasks](https://github.com/user-attachments/assets/4aa5a007-2f82-4546-a281-3325b335b4a6)
42
+
43
+ A task says where things start and what must become true:
44
+
45
+ ```json
46
+ {
47
+ "id": "robolab-banana_in_bowl",
48
+ "instruction": "Pick up the banana and place it in the bowl.",
49
+ "start": [
50
+ ["on", "banana", "table"],
51
+ ["on", "bowl", "table"]
52
+ ],
53
+ "goal": [
54
+ ["inside", "banana", "bowl"]
55
+ ]
56
+ }
57
+ ```
58
+
59
+ ![regions: a drawer, a mug handle, a conveyor belt, a crate, the compartments of a tea drawer, the slots of a dish rack, a pouring cup and the pegs of a mug tree](https://github.com/user-attachments/assets/8742a8dd-6889-49b4-808f-4ada43a58ecf)
60
+
61
+ Objects carry named regions that tasks place things in and check against.
62
+
63
+
64
+ ### Installation
65
+
66
+ ```sh
67
+ pip install tabletask
68
+ pip install "tabletask[control]"
69
+ pip install "tabletask[rtx]"
70
+ ```
71
+
72
+
73
+ ### Example
74
+
75
+ ```python
76
+ import tabletask
77
+
78
+ env = tabletask.make("robolab-banana_in_bowl")
79
+ obs, info = env.reset(seed=0)
80
+
81
+ for _ in range(600):
82
+ action = [*obs["robot"]["joint_position"], 0.0]
83
+ obs, reward, terminated, truncated, info = env.step(action)
84
+ if terminated or truncated:
85
+ break
86
+
87
+ print("success:", info["success"])
88
+ env.close()
89
+ ```
90
+
91
+ Several environments at once, each in its own process and renderer:
92
+
93
+ ```python
94
+ envs = tabletask.make("robolab-banana_in_bowl", num_envs=8, gpus=[0])
95
+ observations, infos = envs.reset(episodes=range(8))
96
+ observations, rewards, terminated, truncated, infos = envs.step(actions)
97
+ envs.close()
98
+ ```
99
+
100
+
101
+ ### Acknowledgments
102
+
103
+ Tasks are ported from [ABC](https://github.com/amazon-far/abc) and
104
+ [RoboLab](https://github.com/NVlabs/RoboLab). The robot models come from
105
+ [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie).
@@ -0,0 +1,69 @@
1
+ ## tabletask
2
+
3
+ A minimal, object-centric format to author tabletop manipulation tasks in simulation, from simple to complex.
4
+
5
+ ![tasks](https://github.com/user-attachments/assets/4aa5a007-2f82-4546-a281-3325b335b4a6)
6
+
7
+ A task says where things start and what must become true:
8
+
9
+ ```json
10
+ {
11
+ "id": "robolab-banana_in_bowl",
12
+ "instruction": "Pick up the banana and place it in the bowl.",
13
+ "start": [
14
+ ["on", "banana", "table"],
15
+ ["on", "bowl", "table"]
16
+ ],
17
+ "goal": [
18
+ ["inside", "banana", "bowl"]
19
+ ]
20
+ }
21
+ ```
22
+
23
+ ![regions: a drawer, a mug handle, a conveyor belt, a crate, the compartments of a tea drawer, the slots of a dish rack, a pouring cup and the pegs of a mug tree](https://github.com/user-attachments/assets/8742a8dd-6889-49b4-808f-4ada43a58ecf)
24
+
25
+ Objects carry named regions that tasks place things in and check against.
26
+
27
+
28
+ ### Installation
29
+
30
+ ```sh
31
+ pip install tabletask
32
+ pip install "tabletask[control]"
33
+ pip install "tabletask[rtx]"
34
+ ```
35
+
36
+
37
+ ### Example
38
+
39
+ ```python
40
+ import tabletask
41
+
42
+ env = tabletask.make("robolab-banana_in_bowl")
43
+ obs, info = env.reset(seed=0)
44
+
45
+ for _ in range(600):
46
+ action = [*obs["robot"]["joint_position"], 0.0]
47
+ obs, reward, terminated, truncated, info = env.step(action)
48
+ if terminated or truncated:
49
+ break
50
+
51
+ print("success:", info["success"])
52
+ env.close()
53
+ ```
54
+
55
+ Several environments at once, each in its own process and renderer:
56
+
57
+ ```python
58
+ envs = tabletask.make("robolab-banana_in_bowl", num_envs=8, gpus=[0])
59
+ observations, infos = envs.reset(episodes=range(8))
60
+ observations, rewards, terminated, truncated, infos = envs.step(actions)
61
+ envs.close()
62
+ ```
63
+
64
+
65
+ ### Acknowledgments
66
+
67
+ Tasks are ported from [ABC](https://github.com/amazon-far/abc) and
68
+ [RoboLab](https://github.com/NVlabs/RoboLab). The robot models come from
69
+ [MuJoCo Menagerie](https://github.com/google-deepmind/mujoco_menagerie).
@@ -0,0 +1,293 @@
1
+ # Examples
2
+
3
+ Three ways to drive a task. These scripts live next to `tabletask/` and are not part
4
+ of the installed package:
5
+
6
+ - `agent.py`: a vision-language model through its provider's API.
7
+ - `pi.py`: pi-0.5 through openpi.
8
+ - `teleop.py`: your own hand, through an iOS device.
9
+
10
+ Run them from the repository root (the directory containing `tabletask/`).
11
+
12
+ ## Vision-language model
13
+
14
+ Load a task, attach Droid, and let a model control it through camera observations
15
+ and Cartesian motion tools.
16
+
17
+ ### Install
18
+
19
+ ```sh
20
+ python -m pip install -e ".[control]" # from the repository root
21
+ ```
22
+
23
+ `mink` and `daqp` provide Droid's Cartesian controller. The API clients use only
24
+ Python's standard library, so no provider SDK is needed. On a headless Linux machine:
25
+
26
+ ```sh
27
+ export MUJOCO_GL=egl
28
+ ```
29
+
30
+ ### Run
31
+
32
+ Anthropic:
33
+
34
+ ```sh
35
+ python -m examples.agent robolab-cube_in_the_bowl \
36
+ --api anthropic --model claude-fable-5-1 --reasoning medium --ask-key
37
+ ```
38
+
39
+ `--ask-key` reads the API key from a hidden prompt. The key stays in the process's
40
+ memory; it is not echoed, added to shell history, or written to the run files.
41
+
42
+ OpenAI and Gemini:
43
+
44
+ ```sh
45
+ python -m examples.agent robolab-cube_in_the_bowl \
46
+ --api openai --model gpt-6-astra --reasoning medium --ask-key
47
+
48
+ python -m examples.agent robolab-cube_in_the_bowl \
49
+ --api gemini --model gemini-3.8-flash --reasoning medium --ask-key
50
+ ```
51
+
52
+ Model names are passed through unchanged, and your account must have access to the
53
+ model. `--reasoning` is optional; omit it for models without that setting.
54
+
55
+ Without `--ask-key`, the key is read from the environment:
56
+
57
+ | `--api` | Environment variable | Endpoint |
58
+ |---|---|---|
59
+ | `anthropic` | `ANTHROPIC_API_KEY` | Messages |
60
+ | `openai` | `OPENAI_API_KEY` | Responses |
61
+ | `gemini` | `GEMINI_API_KEY` | generateContent |
62
+
63
+ **Stop with Ctrl+C.** The runner stops sending requests, closes the environment,
64
+ and records `stop_reason: "interrupted"`. A request already sent may still complete
65
+ and be billed. HTTP errors stop the run; requests are not retried.
66
+
67
+ ### From Python
68
+
69
+ With the provider's key in the environment:
70
+
71
+ ```python
72
+ import tabletask
73
+ from tabletask.robots import Droid
74
+ from examples.agent import run
75
+
76
+ env = tabletask.make("robolab-cube_in_the_bowl", robot=Droid(action_space="cartesian_pose"))
77
+ env.reset(0)
78
+
79
+ try:
80
+ result = run(
81
+ env,
82
+ api="anthropic",
83
+ model="claude-fable-5-1",
84
+ reasoning="medium",
85
+ max_calls=30,
86
+ )
87
+ print(result)
88
+ finally:
89
+ env.close()
90
+ ```
91
+
92
+ `run()` also takes `api_key=` for a key obtained at runtime and `base_url=` for a
93
+ compatible endpoint. Each call to `run()` starts a new conversation. The caller owns
94
+ the environment and closes it.
95
+
96
+ ### Options
97
+
98
+ Pass another task id or task file to change the task; `--episode 1` selects another
99
+ seeded start.
100
+
101
+ | CLI option | Python argument | Default | Meaning |
102
+ |---|---|---|---|
103
+ | `--max-calls` | `max_calls` | `57` | Maximum model requests |
104
+ | `--seconds` | `seconds` | `45` | Maximum simulated motion time, seconds |
105
+ | `--chunk-steps` | `chunk_steps` | whole move | Control steps before the model sees new images |
106
+ | `--image-size` | `image_size` | `224` | Width and height of each camera image, pixels |
107
+ | `--max-tokens` | `max_tokens` | `4096` | Maximum output tokens per response |
108
+ | `--out` | `out` | `build/runs/<timestamp>/` | New directory for results |
109
+
110
+ Without `--chunk-steps`, each move runs to completion before the next observation.
111
+ `--chunk-steps 8` (0.4 simulated seconds) or `--chunk-steps 16` (0.8 s) stops a move
112
+ early so the model can continue toward the same target or change course. Physics is
113
+ paused while the model responds.
114
+
115
+ The task's own time limit and `always` conditions also apply. The full conversation,
116
+ including images, reasoning items and thought signatures, is resent on every call.
117
+ Request size grows with each turn, so a call limit is not a cost limit.
118
+
119
+ ### Observations and actions
120
+
121
+ Each request contains the task instruction, external and wrist RGB images, joint
122
+ positions, gripper closure, the world pose of the grasp point, and the remaining
123
+ budgets. **Object coordinates and goal conditions are not sent.** The model has no
124
+ code, filesystem or scene-query tools.
125
+
126
+ It has two motion tools:
127
+
128
+ ```python
129
+ move_to(targets={"z": 1.05, "gripper": 0}, note="Move above the object, fingers open.")
130
+ move_by(deltas={"dz": -0.05}, note="Lower 5 cm towards the cube.")
131
+ ```
132
+
133
+ | `move_to` field | Meaning |
134
+ |---|---|
135
+ | `x`, `y`, `z` | Absolute world position, metres; z up |
136
+ | `roll`, `pitch`, `yaw` | Radians, relative to the grasp orientation at the start |
137
+ | `gripper` | **0 open, 1 closed**, thresholded at 0.5 |
138
+
139
+ `move_by` takes offsets `dx`, `dy`, `dz` (metres) and `droll`, `dpitch`, `dyaw`
140
+ (radians) from the measured pose, plus the same absolute `gripper`. It lets a model
141
+ move in a direction it can see without knowing the world coordinate of the target.
142
+
143
+ Omitted position and angle fields keep their measured values; an omitted gripper keeps its last command. Orientation is
144
+ `Rz(yaw) Ry(pitch) Rx(roll) R_initial`. The gripper command applies during the
145
+ whole move, so close the gripper in a separate call after arriving.
146
+
147
+ Motion is interpolated at 0.15 m/s and 0.75 rad/s and tracked by Droid's Mink IK at
148
+ 20 Hz. A gripper change takes at least 0.6 s, and every move ends with 0.2 s of
149
+ settling. Moves longer than 10 s are rejected. An IK error stops the move and reports
150
+ how many steps ran; paths are not checked for collisions in advance.
151
+ `chunk_complete` means every planned command was applied, not that the target was
152
+ reached; check the images and measured pose.
153
+
154
+ `done` and `give_up` end the episode. Success is evaluated by tabletask, not by the
155
+ model calling `done`.
156
+
157
+ ### Results and dry runs
158
+
159
+ Each run writes:
160
+
161
+ | File | Contents |
162
+ |---|---|
163
+ | `config.json` | Task, episode, model and settings |
164
+ | `001_external.png`, `001_wrist.png`, ... | Images sent with each call |
165
+ | `calls.jsonl` | Observation, actions, execution feedback, latency and token usage per call |
166
+ | `result.json` | Success, stop reason, call count, simulated time and wall time |
167
+
168
+ `build/runs/` is gitignored. `--out` must not exist yet, so earlier runs are never
169
+ overwritten. API keys are never written to these files.
170
+
171
+ To check the cameras and controller **without calling a model**:
172
+
173
+ ```sh
174
+ python -m examples.agent robolab-cube_in_the_bowl --dry-run
175
+ ```
176
+
177
+ The dry run lifts the gripper 2 cm and lowers it again. It does not attempt the task.
178
+
179
+ See `python -m examples.agent --help` for all options. The code is split into
180
+ `api.py` (provider clients), `tools.py` (observations and motion tools) and
181
+ `agent.py` (episode loop and logging).
182
+
183
+ ## pi-0.5
184
+
185
+ pi-0.5 is a vision-language-action policy: it takes the two camera images and the
186
+ arm's joint positions and returns joint-position actions at 15 Hz. Install the openpi
187
+ client with `pip install -e <openpi>/packages/openpi-client`, then serve the checkpoint
188
+ from an openpi checkout:
189
+
190
+ ```sh
191
+ uv run scripts/serve_policy.py policy:checkpoint \
192
+ --policy.config=pi05_droid_jointpos \
193
+ --policy.dir=gs://openpi-assets/checkpoints/pi05_droid_jointpos
194
+ ```
195
+
196
+ Then play the task:
197
+
198
+ ```sh
199
+ python -m examples.pi robolab-banana_in_the_named_bowl --episodes 20 --out build/pi
200
+ ```
201
+
202
+ Each episode writes frames and a `result.json` to its own directory under `--out`,
203
+ and `summary.json` holds the success rate. `--chunk` is the number of actions
204
+ executed from each inference before querying again; openpi's DROID client uses 8.
205
+
206
+ Two details the adapter must get right:
207
+
208
+ - **Actions are offsets from the joint positions sent with the query**, and every
209
+ action in a chunk is relative to that same pose. They are neither absolute angles
210
+ nor per-step deltas; treating them as absolute angles drives every joint toward
211
+ zero. `pi05_droid` (without `jointpos`) differs again: it outputs joint velocities.
212
+ - **Images are resized with openpi's `resize_with_pad`** to 224 x 224 and sent under
213
+ DROID's key names (exterior camera, then wrist).
214
+
215
+ ## iOS device
216
+
217
+ Move an iOS device to move the gripper, one episode after another. Poses are streamed
218
+ over your network by [Teledex](https://github.com/omarrayyann/TeleDex) from the
219
+ device's ARKit tracking.
220
+
221
+ ### Install
222
+
223
+ ```sh
224
+ python -m pip install teledex mujoco # add mink daqp for --robot droid
225
+ ```
226
+
227
+ Install the app from the [App Store](https://apps.apple.com/ae/app/mujoco-ar/id6612039501).
228
+
229
+ ### Run
230
+
231
+ ```sh
232
+ python -m examples.teleop robolab-banana_in_bowl --episode 6
233
+ ```
234
+
235
+ By default the robot is the floating `Gripper`, which has no arm, so every pose is reachable; pass
236
+ `--robot droid` to drive the full arm.
237
+
238
+ Scan the QR code printed in the terminal with the app to connect. A window shows the
239
+ `dashboard` camera, over the robot's shoulder, with the task instruction across the top. With
240
+ the full arm, only the gripper and the link that carries it are drawn. When the first
241
+ pose arrives, the phone's pose is mapped to the gripper's current pose, so nothing jumps.
242
+
243
+ Motion is in world axes regardless of how you hold the phone. Forward is the direction
244
+ the phone's camera faced when the app started tracking, so start the app facing the
245
+ same way as the robot (world +x).
246
+
247
+ | Phone | Robot |
248
+ |---|---|
249
+ | Move the device | The gripper follows, `--scale` metres per metre (default 2.0) |
250
+ | Rotate the device | The gripper rotates with it |
251
+ | Toggle | Fingers: **on closed, off open** |
252
+ | Button A (hold) | **Clutch**: the robot holds still while you reposition the phone |
253
+ | Button B | **Drop this episode** and start the next one, without counting it |
254
+
255
+ Use the clutch for long reaches: hold the button, bring the phone back to a comfortable
256
+ pose, release, and continue. The phone vibrates when the clutch engages and when an
257
+ episode ends.
258
+
259
+ When an episode ends (the goal is met, an `always` condition is violated, or time runs
260
+ out), the terminal prints the outcome, the next episode starts (`--episode` 6, then 7,
261
+ 8, ...) and the phone is mapped to the gripper again. Success is evaluated by
262
+ tabletask. Close the window or press Ctrl+C to stop; nothing is recorded.
263
+
264
+ ### Options
265
+
266
+ | Option | Default | Meaning |
267
+ |---|---|---|
268
+ | `--robot` | `gripper` | `gripper` (the floating `Gripper`, no arm) or `droid` (the full arm) |
269
+ | `--episode` | `0` | First episode to play |
270
+ | `--scale` | `2.0` | Metres of gripper motion per metre of phone motion |
271
+ | `--port` | `8888` | Port the phone connects to |
272
+ | `--camera` | `dashboard` | Camera shown: a scene camera (`top`, `preview`) or a robot camera (`wrist`, `external`) |
273
+ | `--width` | `1280` | Window width in pixels |
274
+ | `--no-view` | off | Do not open the window |
275
+ | `--debug` | off | Print every goal check at each start and whenever one changes; draw the goal regions |
276
+
277
+ ### From Python
278
+
279
+ ```python
280
+ import tabletask
281
+ from tabletask.robots import Droid
282
+ from examples.teleop import teleoperate
283
+
284
+ env = tabletask.make("robolab-banana_in_bowl", robot=Droid(action_space="cartesian_pose"))
285
+ env.reset(6)
286
+ try:
287
+ solved, played = teleoperate(env, scale=2.0)
288
+ finally:
289
+ env.close()
290
+ ```
291
+
292
+ `teleoperate` accepts `phone=`: any object with `start`, `anchor_to`, `target`,
293
+ `clutching`, `restarting`, `buzz` and `stop`, so it can run without a device.
@@ -4,12 +4,11 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tabletask"
7
- version = "0.1.0"
7
+ dynamic = ["version"]
8
8
  description = "Tabletop manipulation tasks as JSON, sampled and graded in MuJoCo"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  license = "MIT"
12
- license-files = ["LICENSE"]
13
12
  authors = [{ name = "Omar Rayyan", email = "olr7742@nyu.edu" }]
14
13
  keywords = ["robotics", "manipulation", "mujoco", "benchmark", "simulation"]
15
14
  classifiers = [
@@ -21,7 +20,9 @@ dependencies = ["msgspec", "mujoco", "numpy", "pillow", "scipy"]
21
20
  [project.optional-dependencies]
22
21
  control = ["mink", "daqp"] # Cartesian control
23
22
  importing = ["trimesh", "coacd"] # turning a mesh into an asset
24
- all = ["mink", "daqp", "trimesh", "coacd"]
23
+ rtx = ["ovrtx", "ovstage", "usd-core"] # path-traced rendering on an NVIDIA RTX GPU
24
+ all = ["tabletask[control,importing]"]
25
+ dev = ["ruff"]
25
26
 
26
27
  [project.urls]
27
28
  Homepage = "https://table-task.com"
@@ -30,11 +31,23 @@ Source = "https://github.com/omarrayyann/tabletask"
30
31
  [project.scripts]
31
32
  tabletask = "tabletask.__main__:main"
32
33
 
34
+ [tool.hatch.version]
35
+ path = "tabletask/__init__.py"
36
+
33
37
  [tool.hatch.build.targets.wheel]
34
38
  packages = ["tabletask"]
35
39
 
36
40
  [tool.hatch.build.targets.wheel.force-include]
37
- "tasks" = "tabletask/library/tasks"
41
+ "tasks" = "tabletask/data/tasks"
38
42
 
39
43
  [tool.hatch.build.targets.sdist]
40
- include = ["tabletask", "tasks", "README.md", "AGENTS.md", "LICENSE"]
44
+ include = ["tabletask", "tasks", "README.md"]
45
+
46
+ [tool.ruff]
47
+ line-length = 100
48
+
49
+ [tool.ruff.lint]
50
+ select = ["E", "W", "F", "I", "B", "UP", "SIM", "C4", "RUF", "PIE", "PERF", "ISC"]
51
+ ignore = [
52
+ "B905", # zip() without strict=: the lengths here match by construction
53
+ ]
@@ -0,0 +1,109 @@
1
+ """Tabletop manipulation tasks written as JSON, sampled and graded in MuJoCo."""
2
+
3
+ from .env import Env
4
+ from .inspection import preview as _preview
5
+ from .language.errors import SamplingError, UnsupportedError
6
+ from .language.format import dumps, json_schema, load, tasks
7
+ from .language.grammar import words
8
+ from .language.kernel import relation, term
9
+ from .language.schema import Task
10
+ from .sampling import instantiate
11
+ from .vector import Envs
12
+
13
+ __version__ = "0.2.1"
14
+
15
+ __all__ = [
16
+ "Env",
17
+ "Envs",
18
+ "SamplingError",
19
+ "Task",
20
+ "UnsupportedError",
21
+ "dumps",
22
+ "instantiate",
23
+ "json_schema",
24
+ "load",
25
+ "make",
26
+ "preview",
27
+ "relation",
28
+ "tasks",
29
+ "term",
30
+ "words",
31
+ ]
32
+
33
+
34
+ def make(
35
+ source,
36
+ *,
37
+ num_envs=None,
38
+ robot="droid",
39
+ gpus=None,
40
+ renderer=None,
41
+ reward="success",
42
+ scene=None,
43
+ bindings=None,
44
+ monitor_interval=0.01,
45
+ backend="mujoco",
46
+ ) -> Env | Envs:
47
+ """Make an environment for a task, or several that run in parallel.
48
+
49
+ Args:
50
+ source: A task id from `tasks()`, a path to a task file, a JSON string, or a dict.
51
+ num_envs: If given, make this many environments, each in its own process, and
52
+ return them as one `Envs`.
53
+ robot: The robot that acts in the scene: "droid", "gripper", a `Robot`, or None.
54
+ gpus: With `num_envs`, CUDA GPU indices the environments render on, in turn.
55
+ renderer: None to rasterise images, or "rtx" to path-trace them.
56
+ reward: "success" for 1.0 on success, or "subtasks" for 1.0 at each new milestone.
57
+ scene: A scene XML file to use in place of the task's own.
58
+ bindings: Assets for abstract objects, as {name: {"asset": path, "properties": {...}}}.
59
+ monitor_interval: How often, in simulated seconds, task conditions are checked.
60
+ backend: The simulator; only "mujoco" is provided.
61
+
62
+ Returns:
63
+ An `Env`, or with `num_envs` an `Envs`, ready to `reset()`.
64
+ """
65
+ if num_envs is not None:
66
+ return Envs(
67
+ source,
68
+ num_envs,
69
+ robot=robot,
70
+ gpus=gpus,
71
+ renderer=renderer,
72
+ reward=reward,
73
+ scene=scene,
74
+ bindings=bindings,
75
+ monitor_interval=monitor_interval,
76
+ backend=backend,
77
+ )
78
+ if gpus is not None:
79
+ raise ValueError("gpus go with num_envs")
80
+ env = Env(load(source), scene, bindings, monitor_interval=monitor_interval, backend=backend)
81
+ env.renderer = renderer
82
+ env.reward = reward
83
+ if isinstance(robot, str):
84
+ robot = _robot(robot)
85
+ return env if robot is None else env.add(robot)
86
+
87
+
88
+ def _robot(name):
89
+ from . import robots
90
+
91
+ names = {"droid": "Droid", "gripper": "Gripper"}
92
+ if name not in names:
93
+ raise ValueError(f"unknown robot {name!r}; choose from {sorted(names)}")
94
+ return getattr(robots, names[name])()
95
+
96
+
97
+ def preview(source, samples=10, out=None, **kwargs):
98
+ """Render a grid of sampled starts for a task.
99
+
100
+ Args:
101
+ source: A task id, task file, JSON string or dict.
102
+ samples: How many starts to draw, from episodes 0, 1, ...
103
+ out: Where to save the picture, if anywhere.
104
+ **kwargs: `columns`, `renderer="rtx"`, or picture options such as `width`.
105
+
106
+ Returns:
107
+ The grid as a PIL image.
108
+ """
109
+ return _preview(load(source), samples, out, **kwargs)